Technical reference
MailWizz API Reference
Complete reference for the MailWizz 2.x REST API as deployed on Cloud Server for Email managed infrastructure. Covers SDK setup (PHP, Python, Ruby), authentication, HTTP semantics, and every endpoint we support: lists, fields, segments, subscribers, campaigns, tracking, bounces, countries, customers and templates. Examples are tested against production MailWizz instances we operate.
The 1.x API documentation is preserved at api-docs.mailwizz.com/v1. We recommend migrating to 2.x; if you operate a managed instance with us, contact the infrastructure team and we will plan the upgrade with you.
On this page
01
Installing the SDKs
The MailWizz 2.x API is HTTP+JSON, so any language with an HTTP client can call it directly. In practice we recommend the maintained SDKs for the three most common languages used by clients on our infrastructure.
PHP
The PHP client is the reference implementation. Install via Composer:
composer require ems-api/php-client
The package exposes endpoint classes under the EmsApi\Endpoint namespace. The example files under vendor/ems-api/php-client/examples/ are the fastest way to see every endpoint in action.
Python
Install the community Python SDK:
pip install mailwizz-python-sdk
Source and examples are at github.com/twisted1919/mailwizz-python-sdk. The setup pattern mirrors PHP: configure once, then instantiate endpoint objects.
Ruby
Clone the repository and install the only required gem:
git clone https://github.com/twisted1919/mailwizz-ruby-sdk.git
cd mailwizz-ruby-sdk
gem install excon
Follow examples/setup_api.rb for initial configuration.
Other languages
Node.js, Go and other languages can use any HTTP client. A community Node package exists at npmjs.com/package/node-mailwizz. For languages without an SDK, calling the REST endpoints directly with a standard HTTP library is straightforward — the conventions in section 3 are all you need.
02
Configuration and setup
Every SDK needs two pieces of information: the API URL of your MailWizz installation, and your API key. Both come from the MailWizz admin panel.
Finding your API URL and key
Inside MailWizz, navigate to Customer Area → Profile → API Keys. Generate a new public API key and copy both the key string and the API URL shown next to it. On our managed installations the URL has the form https://your-mailwizz.example.com/api.
If your MailWizz instance is not configured with clean URLs (rewrites disabled), the API URL must include /index.php — for example https://example.com/api/index.php. Clients we manage have clean URLs enabled by default.
PHP configuration
require_once __DIR__ . '/vendor/autoload.php';
$config = new \EmsApi\Config([
'apiUrl' => 'https://your-mailwizz.example.com/api',
'apiKey' => 'YOUR_PUBLIC_API_KEY',
'components' => [
'cache' => [
'class' => \EmsApi\Cache\File::class,
'filesPath' => __DIR__ . '/data/cache',
],
],
]);
\EmsApi\Base::setConfig($config);
date_default_timezone_set('UTC');
The cache component is optional but strongly recommended. The MailWizz API returns ETag headers on GET requests; the file cache stores responses keyed by ETag and returns the cached body when MailWizz responds with 304 Not Modified. The cache directory must be writable by the PHP process.
Python configuration
from mailwizz.config import Config
Config.set_config({
'api_url': 'https://your-mailwizz.example.com/api',
'api_key': 'YOUR_PUBLIC_API_KEY',
'charset': 'utf-8',
})
TLS
HTTPS is required for production. Self-signed certificates work for development but the SDKs verify by default — disable verification only against an explicit dev URL, never against your production instance. All MailWizz installations we manage ship with valid Let’s Encrypt certificates auto-renewed.
03
HTTP methods and conventions
The API follows REST conventions. Every endpoint matches an HTTP verb to a CRUD operation:
| Verb | Operation | Idempotent |
|---|---|---|
| GET | Retrieve a resource or collection | Yes |
| POST | Create a new resource | No |
| PUT | Update an existing resource (full or partial) | Yes |
| DELETE | Delete a resource | Yes |
Some shared hosting environments and reverse proxies block PUT and DELETE. If your update or delete calls return 403 Forbidden, the issue is almost always at the web server level, not in MailWizz itself. Apache typically needs <LimitExcept GET POST> directives reviewed; nginx needs proxy_method passed through. On our managed infrastructure both are allowed by default.
Response envelope
Every response is JSON with a consistent envelope. A successful call returns status: "success" plus a data object. A failed call returns status: "error" plus an error message (and sometimes a structured errors object describing per-field problems).
// Success
{
"status": "success",
"data": { /* resource or collection */ }
}
// Error
{
"status": "error",
"error": "Invalid API key"
}
Pagination
Every list endpoint accepts pageNumber (default 1) and perPage (default 10, max 100). The response carries count, total_pages, current_page, next_page and prev_page — use these to drive your pagination loop rather than guessing.
Caching with ETag
GET responses include an ETag header. Sending it back as If-None-Match on subsequent requests gets you a 304 Not Modified with no body when the resource has not changed. The PHP SDK does this automatically when a cache component is configured (section 2).
04
Lists
Lists are the top-level container for subscribers in MailWizz. Every subscriber, segment, field and campaign hangs off a list.
GETGet all lists
// PHP
$endpoint = new \EmsApi\Endpoint\Lists();
$response = $endpoint->getLists($pageNumber = 1, $perPage = 10);
// HTTP
GET API-URL/lists?page=1&per_page=10
Returns a paginated collection. Each record exposes general (name, display name, description, list_uid), defaults (from_name, from_email, reply_to, subject), notifications (subscribe/unsubscribe webhooks) and company (legal address required by anti-spam laws).
GETGet one list
// PHP
$response = $endpoint->getList('LIST-UNIQUE-ID');
// HTTP
GET API-URL/lists/LIST-UNIQUE-ID
POSTCreate a list
$response = $endpoint->create([
'general' => [
'name' => 'My API List',
'description' => 'Created from the API',
],
'defaults' => [
'from_name' => 'John Doe',
'from_email' => 'john@example.com',
'reply_to' => 'john@example.com',
'subject' => 'Hello!',
],
'company' => [
'name' => 'John Doe LLC',
'country' => 'United States',
'zone' => 'New York',
'address_1' => '500 5th Ave',
'city' => 'New York City',
'zip_code' => '10019',
],
]);
// Response
{
"status": "success",
"list_uid": "hv4163y076d84"
}
Required blocks: general and defaults. Optional: notifications and company (if omitted, the customer’s default company is used). For the full list of accepted countries and zones, query the Countries endpoint (section 11).
PUTUpdate a list
$response = $endpoint->update('LIST-UNIQUE-ID', [
'general' => ['name' => 'Renamed', 'description' => 'Updated via API'],
/* same block structure as create */
]);
POSTCopy a list
$response = $endpoint->copy('LIST-UNIQUE-ID');
// Returns a new list_uid for the copy.
Copy duplicates the list’s configuration (fields, segments, defaults) but not the subscribers. This is the right operation when you want to fork a list’s structure for a new audience.
DELETEDelete a list
$response = $endpoint->delete('LIST-UNIQUE-ID');
Deleting a list removes all subscribers, segments, fields and historical campaign references. There is no soft-delete or trash. For production lists, take a backup of subscribers via the Subscribers endpoint before deleting.
05
List fields
Fields define the custom attributes attached to each subscriber: email (always required and built-in), names, segmentation tags, anything specific to your data model.
GETGet all list fields
$endpoint = new \EmsApi\Endpoint\ListFields();
$response = $endpoint->getFields('LIST-UNIQUE-ID');
// HTTP
GET API-URL/lists/LIST-UNIQUE-ID/fields
Each field record returns tag (the column name in API calls and merge tags), label (human-readable name in the MailWizz UI), required (yes/no), help_text and type. Built-in fields are EMAIL, FNAME and LNAME; everything else is custom.
Field types
| Identifier | Use for |
|---|---|
text | Single-line text (default for names, codes, tags) |
textarea | Multi-line free text |
dropdown | Pre-defined options (industries, plan tiers) |
checkbox | Boolean consent or feature flags |
radio | Mutually exclusive options |
date | Birthdays, anniversaries, expirations |
country | ISO-aware country picker, segmentable by region |
06
List segments
Segments are saved filters over a list. Once defined, a segment can be the target of a campaign or referenced from autoresponder rules.
GETGet all segments of a list
$endpoint = new \EmsApi\Endpoint\ListSegments();
$response = $endpoint->getSegments('LIST-UNIQUE-ID');
// HTTP
GET API-URL/lists/LIST-UNIQUE-ID/segments
Each record returns segment_uid, name and subscribers_count. The count is materialised — it does not re-execute the segment query on every call, so for very fresh data you should rely on the engagement webhooks rather than polling the segment endpoint.
Segments with many conditions or that reference custom fields with low cardinality can become expensive to evaluate at campaign send time. If a campaign appears stuck at 0 sent, the most common cause we see in production is a segment that times out before MailWizz can enumerate it. Keep segments to 3-5 conditions where possible and prefer indexed fields. We tune MySQL on managed installations to handle deep segments, but no infrastructure makes a poorly-shaped segment fast.
07
Subscribers
The subscribers endpoint is the most-used part of the API. It supports the full CRUD plus several search and bulk operations.
GETGet all subscribers of a list
$endpoint = new \EmsApi\Endpoint\ListSubscribers();
$response = $endpoint->getSubscribers('LIST-UNIQUE-ID', $pageNumber = 1, $perPage = 10);
// HTTP
GET API-URL/lists/LIST-UNIQUE-ID/subscribers?page=1&per_page=10
Returns records with subscriber_uid, all merge tag values (EMAIL, FNAME, LNAME, plus any custom fields you defined), status (confirmed, unconfirmed, unsubscribed, blacklisted), source (api, import, web, etc.) and date_added.
POSTCreate a subscriber
$response = $endpoint->create('LIST-UNIQUE-ID', [
'EMAIL' => 'subscriber@example.com',
'FNAME' => 'John',
'LNAME' => 'Doe',
// any custom field tag goes here too
]);
If the list is configured for double opt-in (the default and recommended setting), creating a subscriber via the API triggers the confirmation email. Use real email addresses during testing. To bypass confirmation entirely, switch the list to single opt-in in the MailWizz admin — not at the API level — before importing.
POSTCreate subscribers in bulk
$response = $endpoint->createBulk('LIST-UNIQUE-ID', [
['EMAIL' => 'a@example.com', 'FNAME' => 'Anna'],
['EMAIL' => 'b@example.com', 'FNAME' => 'Bob'],
['EMAIL' => 'c@example.com', 'FNAME' => 'Carol'],
// up to 1000 per request on managed installations
]);
// HTTP
POST API-URL/lists/LIST-UNIQUE-ID/subscribers/bulk
Bulk create is dramatically faster than calling create in a loop because it issues a single transaction. On infrastructure we operate, we lift the default 1000-per-request limit when justified by a one-off import; ask the infrastructure team before designing a sustained pipeline that exceeds it.
PUTUpdate a subscriber
// By subscriber_uid
$response = $endpoint->update('LIST-UNIQUE-ID', 'SUBSCRIBER-UNIQUE-ID', [
'FNAME' => 'John',
'LNAME' => 'Doe Updated',
]);
// By email (search-then-update under the hood)
$response = $endpoint->updateByEmail('LIST-UNIQUE-ID', 'subscriber@example.com', [
'FNAME' => 'John',
'LNAME' => 'Doe Updated',
]);
POSTCreate or update (upsert)
$response = $endpoint->createUpdate('LIST-UNIQUE-ID', [
'EMAIL' => 'subscriber@example.com',
'FNAME' => 'John',
'LNAME' => 'Doe',
]);
This is the right call when you sync from an external system and do not want to track which subscribers already exist. MailWizz performs a search-by-email, updates if found, creates otherwise.
Search endpoints
// Search by email within one list
$endpoint->emailSearch('LIST-UNIQUE-ID', 'subscriber@example.com');
// Search by email across all lists
$endpoint->emailSearchAllLists('subscriber@example.com');
// Search by custom field values
$endpoint->searchByCustomFields('LIST-UNIQUE-ID', [
'COMPANY' => 'Acme Inc',
]);
// Search by status: confirmed | unconfirmed | unsubscribed | blacklisted
$endpoint->searchByStatus('LIST-UNIQUE-ID', 'confirmed');
The convenience getters getConfirmedSubscribers(), getUnconfirmedSubscribers() and getUnsubscribedSubscribers() wrap the same status search with pagination.
PUTUnsubscribe
// Silent unsubscribe (no email sent)
$endpoint->unsubscribe('LIST-UNIQUE-ID', 'SUBSCRIBER-UNIQUE-ID');
$endpoint->unsubscribeByEmail('LIST-UNIQUE-ID', 'subscriber@example.com');
// Unsubscribe from every list at once
$endpoint->unsubscribeByEmailFromAllLists('subscriber@example.com');
All unsubscribe operations are silent — they do not send a goodbye email. For GDPR-style erasure requests, use unsubscribe-from-all-lists then follow with delete if you have a legal obligation to remove the record entirely.
DELETEDelete a subscriber
$endpoint->delete('LIST-UNIQUE-ID', 'SUBSCRIBER-UNIQUE-ID');
$endpoint->deleteByEmail('LIST-UNIQUE-ID', 'subscriber@example.com');08
Campaigns
Campaigns are messages sent to a list (optionally narrowed by a segment). The API supports regular and autoresponder campaigns, with full lifecycle control: create, schedule, pause, resume, mark sent, delete.
GETGet all campaigns
$endpoint = new \EmsApi\Endpoint\Campaigns();
$response = $endpoint->getCampaigns($pageNumber = 1, $perPage = 10);
// HTTP
GET API-URL/campaigns
GETGet one campaign
$response = $endpoint->getCampaign('CAMPAIGN-UNIQUE-ID');
Returns the full campaign record with metadata, scheduling, template reference, list and segment binding, and current status.
POSTCreate a campaign
$response = $endpoint->create([
'name' => 'My API Campaign',
'type' => 'regular', // regular | autoresponder
'from_name' => 'John Doe',
'from_email' => 'john@example.com',
'subject' => 'Testing the API',
'reply_to' => 'john@example.com',
'send_at' => date('Y-m-d H:i:s', strtotime('+10 hours')),
'list_uid' => 'LIST-UNIQUE-ID',
'segment_uid' => 'SEGMENT-UNIQUE-ID', // optional
'options' => [
'url_tracking' => 'yes',
'json_feed' => 'no',
'xml_feed' => 'no',
'plain_text_email' => 'yes',
'email_stats' => 'reports@example.com',
],
'template' => [
// exactly one of: archive | template_uid | content
'content' => file_get_contents(__DIR__ . '/template.html'),
'inline_css' => 'yes',
'plain_text' => null, // null = auto-generate
'auto_plain_text' => 'yes',
],
]);
// Response
{
"status": "success",
"campaign_uid": "hv4163y076d84"
}
Autoresponder campaigns
Set type to autoresponder and add three extra fields in the options block:
'autoresponder_event' => 'AFTER-SUBSCRIBE',
'autoresponder_time_unit' => 'hour', // minute | hour | day | week | month | year
'autoresponder_time_value' => 1,
// only when event is AFTER-CAMPAIGN-OPEN:
'autoresponder_open_campaign_id' => 123,
Available events: AFTER-SUBSCRIBE (fires when the subscriber joins the list) and AFTER-CAMPAIGN-OPEN (fires when they open a specific other campaign).
Recurring campaigns
For repeated sends on a schedule, add a cron expression:
'cronjob' => '0 9 * * MON', // every Monday at 09:00
'cronjob_enabled' => 1,
Recurring is only valid for type=regular. The campaign re-evaluates the list (and segment, if any) each time it fires, so new subscribers are included on subsequent runs.
PUTUpdate / POSTCopy / PUTPause-Unpause / PUTMark sent
$endpoint->update('CAMPAIGN-UNIQUE-ID', [/* same shape as create */]);
$endpoint->copy('CAMPAIGN-UNIQUE-ID');
$endpoint->pauseUnpause('CAMPAIGN-UNIQUE-ID');
$endpoint->markSent('CAMPAIGN-UNIQUE-ID');
$endpoint->delete('CAMPAIGN-UNIQUE-ID');
markSent exists for operational recovery: if a campaign was sent through some external mechanism and you need to update MailWizz state without resending, this is the correct call.
GETCampaign stats
$response = $endpoint->getStats('CAMPAIGN-UNIQUE-ID');
Returns the full stats envelope: subscribers_count, processed_count, delivery_success/error counts and rates, opens (total and unique), clicks (total and unique), unsubscribes, complaints, bounces broken down by hard, soft and internal. Open rate after May 2021 should be treated cautiously because of Apple Mail Privacy Protection — for the operational context, see our note on Apple MPP engagement metric reliability.
09
Campaign tracking
The tracking endpoint is used by MailWizz internally to record opens, clicks and unsubscribes triggered from email content. Direct calls are useful when relaying tracking through your own infrastructure or when reconstructing events after a webhook delivery failure.
GETTrack URL click
$endpoint = new \EmsApi\Endpoint\CampaignsTracking();
$response = $endpoint->trackUrl('CAMPAIGN-UID', 'SUBSCRIBER-UID', 'URL-HASH');
// HTTP
GET API-URL/campaigns/CAMPAIGN-UID/track-url/SUBSCRIBER-UID/URL-HASH
The URL-HASH is the SHA-256 of the original click target as MailWizz stored it when the campaign was prepared. You retrieve hashes from the campaign template or from the URL-stats endpoint of the MailWizz admin.
GETTrack open
$endpoint->trackOpening('CAMPAIGN-UID', 'SUBSCRIBER-UID');
// HTTP
GET API-URL/campaigns/CAMPAIGN-UID/track-opening/SUBSCRIBER-UID
POSTTrack unsubscribe
$endpoint->trackUnsubscribe('CAMPAIGN-UID', 'SUBSCRIBER-UID', [
'ip_address' => '203.0.113.42',
'user_agent' => 'Mozilla/5.0 ...',
'reason' => 'No longer interested',
]);
Recording the unsubscribe reason is optional but extremely useful for list hygiene analysis — correlating reasons against segments or campaigns surfaces content problems early.
10
Campaign bounces
The campaign bounces endpoint exposes the bounce records associated with a campaign. Use it to feed external monitoring, to drive a custom suppression workflow, or to backfill bounce data when the SMTP-level bounce processor was misconfigured during a send.
GETGet all bounces
$endpoint = new \EmsApi\Endpoint\CampaignBounces();
$response = $endpoint->getBounces('CAMPAIGN-UNIQUE-ID', $pageNumber = 1, $perPage = 10);
Each record returns the SMTP message (raw bounce string), processed flag, bounce_type (hard, soft or internal), and the subscriber identifier.
POSTCreate a bounce
$endpoint->create('CAMPAIGN-UNIQUE-ID', [
'message' => '5.1.1 Recipient address rejected: User unknown',
'bounce_type' => 'hard', // hard | soft | internal
'subscriber_uid' => 'SUBSCRIBER-UNIQUE-ID',
]);
On managed infrastructure we operate, bounces are recorded automatically at the MTA layer by PowerMTA’s feedback-loop and accounting pipeline. You should only call this endpoint when integrating an external bounce processor or recovering from a configuration gap. Operational context on this is captured in our note on real-time bounce processing at the MTA layer.
11
Countries and zones
The Countries endpoint is read-only and powers the country/zone validation in list company blocks and customer creation. Use it to populate dropdowns or validate user input before sending it to the create endpoints.
GETGet all countries
$endpoint = new \EmsApi\Endpoint\Countries();
$response = $endpoint->getCountries($pageNumber = 1, $perPage = 100);
Returns country_id, name and ISO-3166 alpha-2 code. There are 240 countries in the dataset, so a single 100-per-page call gets you the first half.
GETGet zones (states / provinces) of a country
$response = $endpoint->getZones('COUNTRY-ID', $pageNumber = 1, $perPage = 100);
// HTTP
GET API-URL/countries/COUNTRY-ID/zones
Returns zone_id, name and code for every sub-region MailWizz knows about for that country (US states, Canadian provinces, Brazilian states, etc.).
12
Customers
The customers endpoint is used by resellers and platform operators creating new MailWizz customers programmatically. On managed installations this endpoint is restricted to admin keys; reach the infrastructure team to enable it for a delegated key if you need it for onboarding automation.
POSTCreate a customer
$endpoint = new \EmsApi\Endpoint\Customers();
$response = $endpoint->create([
'customer' => [
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'john@example.com',
'password' => 'STRONG_PASSWORD',
'timezone' => 'UTC',
'birthDate' => '1985-04-12',
],
'company' => [
'name' => 'John Doe LLC',
'country' => 'United States',
'zone' => 'New York',
'city' => 'Brooklyn',
'zip_code' => '11222',
'address_1' => '500 Some Street',
'address_2' => '',
],
]);
// Response
{
"status": "success",
"customer_uid": "wc149l7wdm9be"
}
The company block becomes mandatory if MailWizz is configured to require it. Country and zone names must match exactly what the Countries endpoint (section 11) returns — that is why we treat Countries as a hard dependency for any automation that creates customers or lists.
13
Templates
Templates are reusable HTML messages. Storing them through the API rather than inlining content into each campaign lets you version templates separately and reuse them across many campaigns.
GETGet / search templates
$endpoint = new \EmsApi\Endpoint\Templates();
// All templates
$endpoint->getTemplates($pageNumber = 1, $perPage = 10);
// One template
$endpoint->getTemplate('TEMPLATE-UNIQUE-ID');
// Search by name (MailWizz 1.4.4+)
$endpoint->searchTemplates(1, 10, ['name' => 'welcome']);
POSTCreate a template
$response = $endpoint->create([
'name' => 'Welcome Email v3',
'content' => file_get_contents(__DIR__ . '/welcome.html'),
// OR: 'archive' => file_get_contents(__DIR__ . '/welcome.zip'),
'inline_css' => 'yes',
]);
// Response
{
"status": "success",
"template_uid": "jo441taeq281e"
}
If your template uses external CSS files, ship them inside a zip archive and pass the binary contents under the archive key. MailWizz unpacks the archive, inlines the CSS at render time if inline_css is yes, and stores the result. Inlining is essential for legacy mail clients (Outlook, some webmail) that strip head-level styles.
PUTUpdate / DELETEDelete
$endpoint->update('TEMPLATE-UNIQUE-ID', [/* same shape as create */]);
$endpoint->delete('TEMPLATE-UNIQUE-ID');14
Errors and troubleshooting
The error envelope is consistent across endpoints, but production debugging often comes down to four recurring problem shapes. We catalogue them here with the diagnostic approach we use on the infrastructure side.
Authentication errors
| Status | Likely cause | Fix |
|---|---|---|
401 | Missing or malformed API key header | Check the X-MW-PUBLIC-KEY header in the SDK’s outgoing request log |
403 method | Server blocks PUT/DELETE | Check Apache/nginx config; managed installations allow all methods by default |
403 IP | API key has an IP allowlist configured | Add the calling IP in MailWizz admin or use a key without IP restriction for non-production debugging |
Validation errors on create / update
The error response includes an errors object keyed by field name with arrays of human-readable messages. Surface these to your end users rather than the generic error field, which only carries the first line of the failure.
// Example response
{
"status": "error",
"error": "Validation failed",
"errors": {
"EMAIL": ["Email is not a valid email address."],
"FNAME": ["First name cannot be blank."]
}
}
“Upload file size is fixed to 2 MB” on imports
This is not a MailWizz limit — it is PHP’s upload_max_filesize and post_max_size. The fix is two values in php.ini (or a per-vhost override). On our managed infrastructure both are set to 64 MB by default and we adjust higher on request. If you are self-hosting, edit php.ini, restart PHP-FPM and the limit increases immediately.
“Campaign stuck at 0 sent”
The most common production cause is a segment that times out before MailWizz can enumerate it (see the segment-depth note in section 6). The second most common is a delivery server with no remaining hourly quota. Check the campaign delivery log in the MailWizz admin: if the log is empty, the issue is segment evaluation; if entries exist but stop, the issue is downstream — usually the MTA queue or rate limiting.
HTTP 304 with empty body
Expected. The SDK’s cache component will return the previously cached response transparently when MailWizz answers 304. If you are not using the cache and receive 304, your client is sending an If-None-Match header; remove it for non-conditional requests.
Anything that affects throughput — sustained 5xx errors, very slow responses on bulk endpoints, or behaviour that is inconsistent across calls — is almost always infrastructure-side rather than API-side. Email infrastructure@cloudserverforemail.com with the campaign UID, the list UID and the time window; we have full access logs and can correlate against the MTA-side picture.
Related material
This reference is the technical complement to several operational notes and managed-service pages elsewhere on the site:
- Managed MailWizz Hosting — what we operate, the SLA, and how the API differs on managed installations
- MailWizz Technical FAQ — questions we answer most frequently, including upgrade paths and integration patterns
- Feedback Loops: How They Work — the operational context behind bounce and complaint records you read through this API
- Configuration Reference — PowerMTA-side configuration that affects how API-sent campaigns actually deliver
Need this API in production?
We operate MailWizz instances with this API enabled by default.
Managed PowerMTA + MailWizz, daily monitoring, EU data center, and direct engineer access. The API runs on the same infrastructure that handles your deliverability.
See Managed MailWizz Talk to engineering