# Use with AI tools Source: https://apidoc.mailercloud.com/ai-tools Connect Claude, Cursor, ChatGPT, and other AI assistants to the Mailercloud API documentation. These docs are built to be read by AI coding assistants as well as humans. If you build your integration with an AI tool, point it at the resources below and it will always work from accurate, current documentation. ## Two MCP servers Mailercloud offers two Model Context Protocol servers — most AI workflows want both: | | URL | What it does | | ----------------------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------- | | **Docs MCP** | `https://apidoc.mailercloud.com/mcp` | Lets agents **search and read this documentation** | | **[Mailercloud MCP](/guides/mcp-server)** | `https://mcp.mailercloud.com/mcp` | Lets agents **act on your account** — create campaigns, manage contacts, send email (47 tools) | ## Docs MCP server Add it to any MCP-compatible client (Claude, Claude Code, Cursor, Windsurf, VS Code) to let your assistant read these docs while it writes your integration: ``` https://apidoc.mailercloud.com/mcp ``` For example, in Claude Code: ```bash theme={null} claude mcp add mailercloud-docs --transport http https://apidoc.mailercloud.com/mcp ``` ## llms.txt AI agents can discover every page of this documentation through the standard index files: * [`/llms.txt`](/llms.txt) — index of all pages with descriptions * [`/llms-full.txt`](/llms-full.txt) — the entire documentation in a single Markdown file ## Markdown for every page Append `.md` to any page URL to get its raw Markdown — ideal for pasting into a prompt or fetching from an agent: ``` https://apidoc.mailercloud.com/api-reference/campaigns/create-campaign.md ``` You can also use the copy menu on any page to copy it as Markdown or open it directly in ChatGPT or Claude. # Client Details Source: https://apidoc.mailercloud.com/api-reference/account/client-details /openapi-v1.json get /client/plan API to get current user details # Create Automation Source: https://apidoc.mailercloud.com/api-reference/automations/create-automation /openapi-v1.json post /automations API to create an advanced automation in a single request. `name` and `nodes` are required. `auto_publish` is optional (defaults to `false` = draft). `timezone`, `start_time`, `end_time`, `allow_re_enrollment`, `re_enroll_interval`, `re_enroll_unit` are optional. The automation is declared as a directed graph of nodes: exactly one trigger node, plus any number of action / wait / condition nodes wired via `parent_id`. Caller-supplied node ids (`id`, `parent_id`, `target_id`) are short strings used only to wire the graph in the request; they are not stored. **Plan gate:** the caller's plan must include advanced automation, otherwise a `403` is returned. # Get Automation Details Source: https://apidoc.mailercloud.com/api-reference/automations/get-automation-details /openapi-v1.json post /automations/{id} Retrieve details and node-level campaign report data for an advanced automation by its ID. The request body filters which node types are included. # Download Verification Results Source: https://apidoc.mailercloud.com/api-reference/bulk-files/download-verification-results /openapi-verifier.json get /verifyFile/download/{file_id} Download the verified results file for a completed verification. # Get File Verification Status Source: https://apidoc.mailercloud.com/api-reference/bulk-files/get-file-verification-status /openapi-verifier.json get /verifyFileStatus/{file_id} Poll the processing status and result summary of an uploaded file. # List Verification Files Source: https://apidoc.mailercloud.com/api-reference/bulk-files/list-verification-files /openapi-verifier.json post /verifyFiles List your uploaded verification files with pagination and search. # Upload File for Verification Source: https://apidoc.mailercloud.com/api-reference/bulk-files/upload-file-for-verification /openapi-verifier.json post /verifyFile Upload a file of email addresses for bulk verification. Max **10 MB** and **100,000 emails** per file. Processing is asynchronous — poll `GET /verifyFileStatus/{file_id}`. (These are the API upload limits; larger files — up to 100 MB / 1M addresses in CSV/TXT — can be verified through the in-app List Verification upload.) # Campaign Domain Report Source: https://apidoc.mailercloud.com/api-reference/campaigns/campaign-domain-report /openapi-v1.json post /campaign/domain/report/{id} This report contains statistics for the top-performing email domains in a campaign. The domains report allows you to break down your customers into groups according to their mailbox service provider. # Campaign List Source: https://apidoc.mailercloud.com/api-reference/campaigns/campaign-list /openapi-v1.json post /campaign/list Get the details of all the campaigns you have created. # Create Campaign Source: https://apidoc.mailercloud.com/api-reference/campaigns/create-campaign /openapi-v1.json post /campaign > A newer version of this endpoint with more options is available: [Create Campaign (v2)](/api-reference/campaigns/create-campaign-v2). API for creating an email campaign. For creating a campaign, HTML or plain text and list id or segment are mandatory. # Create Campaign (v2) Source: https://apidoc.mailercloud.com/api-reference/campaigns/create-campaign-v2 /openapi-v1.json post /campaign/save **The newer version of Create Campaign with additional options — prefer this endpoint for new integrations.** **Required:** `name`, `subject`, and `sender` (with `sender_name` + `sender_email`). **Content:** provide `html` or `plain_text`. **Audience:** provide at least one of `list_ids`, `segments`, or `tag_ids`. # Get Single Campaign Details Source: https://apidoc.mailercloud.com/api-reference/campaigns/get-single-campaign-details /openapi-v1.json get /campaign/{id} Get the details of a single campaign. # List Campaign Clicks Source: https://apidoc.mailercloud.com/api-reference/campaigns/list-campaign-clicks /openapi-v1.json post /campaign/{id}/clicks Get a paginated list of contacts who clicked a link in a specific campaign. Each row carries the contact's encrypted id, email, name, the tags currently assigned to the contact, the lists the contact currently belongs to (with their ids and names), and the time of the click in your account timezone. Each contact appears at most once in the response. If a contact clicked more than once, the time shown is the most recent click. # List Campaign Opens Source: https://apidoc.mailercloud.com/api-reference/campaigns/list-campaign-opens /openapi-v1.json post /campaign/{id}/opens Get a paginated list of contacts who opened a specific campaign. Each row carries the contact's encrypted id, email, name, the tags currently assigned to the contact, the lists the contact currently belongs to (with their ids and names), and the time of the open in your account timezone. Each contact appears at most once in the response. If a contact opened the campaign multiple times, the time shown is the most recent open. # List Campaign Unsubscribes Source: https://apidoc.mailercloud.com/api-reference/campaigns/list-campaign-unsubscribes /openapi-v1.json post /campaign/{id}/unsubs Get a paginated list of contacts who unsubscribed via a specific campaign. Each row carries the contact's encrypted id, email, name, the tags currently assigned to the contact, the lists the contact currently belongs to (with their ids and names), the time of the unsubscribe in your account timezone, and the reason the contact gave (if any). # Schedule Campaign Source: https://apidoc.mailercloud.com/api-reference/campaigns/schedule-campaign /openapi-v1.json post /campaign/schedule/{id} API for scheduling campaign. If the schedule_at is not given, the campaign will schedule for the current time. # Send a Test Email Source: https://apidoc.mailercloud.com/api-reference/campaigns/send-a-test-email /openapi-v1.json post /campaign/testmail/{id} Send a test email. # Testmail Group List Source: https://apidoc.mailercloud.com/api-reference/campaigns/testmail-group-list /openapi-v1.json post /campaign/testmail-groups/list Get the details of all the testmail groups you have created. # Update Campaign Source: https://apidoc.mailercloud.com/api-reference/campaigns/update-campaign /openapi-v1.json put /campaign/{id} API for updating the campaign. Can't change or edit the list, segments, pause_rule, rules for the campaigns in sending status. Pause the campaign to edit the scheduled date. # Create Batch Contact Source: https://apidoc.mailercloud.com/api-reference/contacts/create-batch-contact /openapi-v1.json post /contacts/batch Create a Batch contact. You can create a maximum of 50 contact through this API. # Create Contact Source: https://apidoc.mailercloud.com/api-reference/contacts/create-contact /openapi-v1.json post /contacts API for creating contact. For creating a contact, email and list id is required. If you try to create a contact that already exists, it gives an "already exists" message . You can add custom property data by mapping the property id : value. You can add contacts until your contact quota limit is reached. If you create a contact in a suppressed list and if this contact is also present in the active list, the contact will be removed from the active list to the suppressed list. # Create or Update Contact Source: https://apidoc.mailercloud.com/api-reference/contacts/create-or-update-contact /openapi-v1.json post /contacts/upsert API to manage your contacts, allowing you to either create new contacts or update existing ones based on your needs. When you send a request, the API first checks if the contact already exists in your database. If the contact is found, the API will automatically update the existing contact with the new information provided. This ensures that your contact list remains up-to-date without creating duplicates. **Custom Property Data:** The API allows you to add custom properties to each contact. You can do this in two ways: - By Property ID: Map the property ID to its corresponding value. - By Personalization Tag: Alternatively, you can use personalization tag for that property to specify values. **Contact Quota Limit:** Please note that you can continue adding or updating contacts until you reach your designated contact quota limit. If you reach your quota limit, further attempts to add new contacts will be rejected until you either remove some existing contacts or increase your quota. # Delete Contact Source: https://apidoc.mailercloud.com/api-reference/contacts/delete-contact /openapi-v1.json delete /contacts/{id} Delete a contact based on their ID # Get Contact Details Source: https://apidoc.mailercloud.com/api-reference/contacts/get-contact-details /openapi-v1.json get /contacts/{id} Get contact details based on their Contact ID or Email # Get Contacts in a List Source: https://apidoc.mailercloud.com/api-reference/contacts/get-contacts-in-a-list /openapi-v1.json post /contact/search/{id} You can collect all your contacts on a single list. # Remove Contact Tag Source: https://apidoc.mailercloud.com/api-reference/contacts/remove-contact-tag /openapi-v1.json post /contact/tag/remove API to remove contact-tags from individual contacts When you send a request, the API first checks if the contact already exists in your database. If the contact is found, the API will check if the tags you provided are valid. You can give both tag names or tag ids. The API allows you to remove contact-tags. You can do this in two ways: - By Contact ID: You can add the **contact ID** from your panel to remove tags. - By Email: Alternatively, you can use the **email ID** of the contact whose tag you want to update. # Update Contact Source: https://apidoc.mailercloud.com/api-reference/contacts/update-contact /openapi-v1.json put /contacts/{id} Update contact details based on contact ID or Email using this API. However, you can't update the list ID and email. # Create Property Source: https://apidoc.mailercloud.com/api-reference/custom-properties/create-property /openapi-v1.json post /contact/property API for creating custom property of contacts. Custom properties store specific information for contact records in Mailercloud. You are allowed to create a maximum of 100 properties. # Delete Property Source: https://apidoc.mailercloud.com/api-reference/custom-properties/delete-property /openapi-v1.json delete /contact/property/{id} API for deleting custom property of contacts. If the property is used in a webform you won't be able to delete it. # List Property Source: https://apidoc.mailercloud.com/api-reference/custom-properties/list-property /openapi-v1.json post /contact/property/search Using this API, you can list all the properties of your contacts in your Mailercloud account. You can also make segments based on these properties # Update Property Source: https://apidoc.mailercloud.com/api-reference/custom-properties/update-property /openapi-v1.json patch /contact/property/{id} API for updating custom property of contacts. Editing custom property type using this API is not possible. You can only edit the name and description. # List Inbox-Tracking Campaigns Source: https://apidoc.mailercloud.com/api-reference/email/list-inbox-tracking-campaigns /openapi-emailapi.json post /v2/email/inbox-tracking API to get inbox tracking details for Email API campaigns. Returns a paginated list of campaigns enriched with inbox / spam / missed placement percentages and a per-mailbox-provider breakdown. Supports filtering by campaign id, subject, sender and date range, plus sorting on key metrics. **Sample Code** # Send Email Source: https://apidoc.mailercloud.com/api-reference/email/send-email /openapi-emailapi.json post /email Send a single email — transactional (order confirmations, OTPs, notifications) or promotional — through the Mailercloud Email API. Supports plain text, HTML, AMP content, attachments, and multiple recipients (To, CC, BCC). **Key points:** - `from` (and `replyTo`) must belong to a verified sender on your account. - Set `version` to `"1.0"` for HTML-only sends, or `"2.0"` when including `amp_html`. - Provide both `html` and `text` for the best deliverability. - Attachments are fetched at send time from a publicly accessible `url`. Need per-recipient personalization (`Hi {{first_name}}…`) in one request? Use [Send Personalized Email (mail merge)](/api-reference/email/send-personalized-email) — same request structure plus `merge_vars`. # Send Personalized Email Source: https://apidoc.mailercloud.com/api-reference/email/send-personalized-email /openapi-emailapi.json post /email-api Send transactional or marketing emails with **per-recipient personalization** (mail merge). Same request structure as `POST /email`, plus an optional `merge_vars` object on each `recipients.to[]` entry. **Personalization:** - `{{variable}}` placeholders in `subject`, `text`, `html`, `amp_html` and `fromName` are replaced with that recipient's `merge_vars` values. - In `html`, `{{var}}` is HTML-escaped; use `{{{var}}}` (triple brace) to inject raw HTML (pre-trusted content only). - Dot-notation walks nested objects: `{{order.id}}`, `{{order.shipping.city}}`. - A missing key renders as an empty string (never blocks the send). - Rendering activates only when at least one recipient carries a non-empty `merge_vars`; otherwise `{{...}}` is delivered literally (identical to `/email`). **CC / BCC:** cc and bcc recipients receive an audit copy rendered against the **first** `to` recipient's `merge_vars` scope. **Notes:** - `merge_vars` must be a JSON object — a non-object value returns `400`. - The combined size of all recipients' `merge_vars` must be ≤ 100 KB, else `413`. - `replyTo` must be a verified sender address; it does **not** support `{{var}}` templates. - Mail merge is supported only on this HTTP endpoint (not on SMTP relay). # Inbox-tracking Source: https://apidoc.mailercloud.com/api-reference/inbox-tracker/inbox-tracking /openapi-v1.json post /inbox-tracking API to get inbox tracking details. Date period is required (date_from & date_to), campaign_id is optional, domain is optional # Create a New List Source: https://apidoc.mailercloud.com/api-reference/lists/create-a-new-list /openapi-v1.json post /list Your Mailercloud list, also known as your recipient, is where you store and manage all of your contacts. # Delete a List Source: https://apidoc.mailercloud.com/api-reference/lists/delete-a-list /openapi-v1.json delete /list/{id} This API deletes a specific list by id. However, you can't delete your list if its used in an active campaign , active automation or in an active webform . # Get Single List Details Source: https://apidoc.mailercloud.com/api-reference/lists/get-single-list-details /openapi-v1.json get /list/{id} Get single list details based on id. # List Lists Source: https://apidoc.mailercloud.com/api-reference/lists/list-lists /openapi-v1.json post /lists/search Use this API to return an array of all of your contact lists. You can filter, search and sort list. # Update a List Source: https://apidoc.mailercloud.com/api-reference/lists/update-a-list /openapi-v1.json patch /list/{id} Update the details of a specific list by id. However, you can only update the names using this API # Create Segment Source: https://apidoc.mailercloud.com/api-reference/segments/create-segment /openapi-v1.json post /segments API to create a segment in a single request. `name`, `match` and `rules` are required. `lists` is optional - if omitted, the segment evaluates against all contacts. A segment is a dynamic contact filter built from a list of rules. Each rule belongs to one of 4 filter_types: `contact_details` (built-in contact fields), `contact_property` (custom properties), `tag` (contact tags), or `activity` (campaign / automation / engagement events). The `match` field controls whether ALL rules must match (`all`) or ANY rule is enough (`any`). # List Segment Source: https://apidoc.mailercloud.com/api-reference/segments/list-segment /openapi-v1.json post /segment/search List all your created segments. # Update a Segment Source: https://apidoc.mailercloud.com/api-reference/segments/update-a-segment /openapi-v1.json put /segments/{id} Update an existing segment by id. The full segment definition is replaced - this is NOT a partial update. Send the complete `name`, `match`, `rules` (and optional `lists`) on every call. On success, the segment's `active_count` is recomputed asynchronously. `GET /v1/segments/{id}` will return `count_status: pending` until the recount finishes (seconds to minutes), then `ready`. Field vocabulary, operator families, and value shapes match the create endpoint - see POST /v1/segments for the full reference. # List Reply Emails Source: https://apidoc.mailercloud.com/api-reference/senders/list-reply-emails /openapi-v1.json post /reply-emails/search Use this API to return an array of all your active reply-to email addresses. You can filter and search reply emails with pagination. # List Senders Source: https://apidoc.mailercloud.com/api-reference/senders/list-senders /openapi-v1.json post /senders/search Use this API to return an array of all your active and verified sender email addresses with sender name and reply-to email. You can filter, search and sort senders. # Create Tag Source: https://apidoc.mailercloud.com/api-reference/tags/create-tag /openapi-v1.json post /tags API for creating tags for contacts and campaign. # Delete Tag Source: https://apidoc.mailercloud.com/api-reference/tags/delete-tag /openapi-v1.json delete /tags/{id} This API deletes a specific tag by id. # List Tags Source: https://apidoc.mailercloud.com/api-reference/tags/list-tags /openapi-v1.json post /tags/search Using this API, you can list all the tags of your contacts and campaign in your Mailercloud account # Update Tag Source: https://apidoc.mailercloud.com/api-reference/tags/update-tag /openapi-v1.json put /tags/{id} API for updating tag name of contacts and campaign. # Create Template Source: https://apidoc.mailercloud.com/api-reference/templates/create-template /openapi-v1.json post /templates/create API to create a new template in Mailercloud. **Required Fields:** - name: Name of the template (required, max 100 characters, must be unique) - html: Specifies the HTML content (required) **Optional Fields:** - categoryId: Specifies the category ID of the template, you can get it from the **Get Template Categories** API. It would be 0 by default. - plainText: Specifies the plain text content # Get Template by Name or ID Source: https://apidoc.mailercloud.com/api-reference/templates/get-template-by-name-or-id /openapi-v1.json get /templates/details This endpoint retrieves the full details of an email template in mailercloud. You can fetch a template either by passing the template name or its ID in the query parameters. ```Name curl --request GET \ --url https://cloudapi.mailercloud.com/v1/templates/details?name=example \ --header 'Authorization: Your API Key here' ``` ```ID curl --request GET \ --url https://cloudapi.mailercloud.com/v1/templates/details?id=abc \ --header 'Authorization: Your API Key here' ``` # Get Template Categories Source: https://apidoc.mailercloud.com/api-reference/templates/get-template-categories /openapi-v1.json get /templates/categories/list This API endpoint is used to list the template categories in Mailercloud. # Get Template Details Source: https://apidoc.mailercloud.com/api-reference/templates/get-template-details /openapi-v1.json get /templates/details/{id} This API endpoint is used to retrieve the details of a specific email template by its ID in Mailercloud. # List Templates Source: https://apidoc.mailercloud.com/api-reference/templates/list-templates /openapi-v1.json post /templates/list Get a list of your saved email templates. By default the response returns only template metadata (id, name, type, status, dates) — fast and small, ideal for building a template picker or dashboard. If you also want the full template body (HTML, AMP, and plain text) inlined in the same response, set `include_content: true`. This is useful when you need to render or display the templates yourself without making a separate `GET /templates/details/{id}` call for each one. You can filter, sort, search, and paginate through your templates: - Filter by template type (`html`, `amp`, or both) - Filter by status (`saved`, `draft`, or both) - Filter by category - Search by template name (case-insensitive substring match) - Sort by name, created date, or modified date — ascending or descending - Paginate with `page` and `limit` **Response limits when `include_content: true`:** Because template bodies can be large, two safeguards apply when you ask for content: 1. `limit` is capped at 20 templates per response (even if you request more). 2. The total response size is capped at 10 MB. If the response would exceed the size cap, you'll receive as many templates as fit, and the response will include `truncated: true`. When this happens, fetch the missing templates one at a time using `GET /templates/details/{id}` — the `template_count` field tells you the total number of templates that match your filter so you know how many are missing. # Update Template Source: https://apidoc.mailercloud.com/api-reference/templates/update-template /openapi-v1.json post /templates/update This API allows you to update an existing email template in Mailercloud. You can update a template either by providing its id or by using the templateName — at least one of them is required. **Required Fields:** - id: The unique ID of the template you want to update. (Required if templateName is not provided.) - templateName: The name of the template you want to update. (Required if id is not provided.) - name: The new name for the template (maximum 100 characters). The name must be unique. - html: The updated HTML content of the template. **Optional Fields:** - categoryId: Specifies the category ID of the template, you can get it from the **Get Template Categories** API. It would be 0 by default. - plainText: Specifies the plain text content # Verify Emails Source: https://apidoc.mailercloud.com/api-reference/verification/verify-emails /openapi-verifier.json post /verifyEmail Verify a single email or a batch of up to **50** emails in real time. Duplicates are removed automatically. Each billable result consumes one credit; returns `402` when the account has insufficient credits. Credits are consumed for every verification attempt, including `unknown` results. Same credit balance as file uploads; active Marketing subscribers receive 250 free credits monthly. # Webform List Source: https://apidoc.mailercloud.com/api-reference/webforms/webform-list /openapi-v1.json post /webform/search Use this API to return an array of all of your webforms. You can filter, search and sort webforms. # Create a New Webhook Source: https://apidoc.mailercloud.com/api-reference/webhooks/create-a-new-webhook /openapi-v1.json post /webhooks Mailercloud webhook is a mechanism that allows external systems to receive real-time updates and notifications about events occurring within your account. # Delete a Webhook Source: https://apidoc.mailercloud.com/api-reference/webhooks/delete-a-webhook /openapi-v1.json delete /webhooks/{id} This API deletes a specific webhook by id. # Get Webhook Details Source: https://apidoc.mailercloud.com/api-reference/webhooks/get-webhook-details /openapi-v1.json get /webhooks/detail/{id} Get webhook details based on their ID # Search and List Webhooks Source: https://apidoc.mailercloud.com/api-reference/webhooks/search-and-list-webhooks /openapi-v1.json post /webhooks/search API to list all webhooks with the ability to search, filter, and sort the results. # Test Webhook Source: https://apidoc.mailercloud.com/api-reference/webhooks/test-webhook /openapi-v1.json post /webhooks/test API to send dummy trigger requests to the webhook URL for testing purposes. # Toggle Webhook Status Source: https://apidoc.mailercloud.com/api-reference/webhooks/toggle-webhook-status /openapi-v1.json post /webhooks/toggle/{id} API for deactivating or activating the status of a webhook. # Update a Webhook Source: https://apidoc.mailercloud.com/api-reference/webhooks/update-a-webhook /openapi-v1.json put /webhooks/{id} API for modifying webhook information. This allows you to update the webhook's name, URL, and events. # Authentication Source: https://apidoc.mailercloud.com/authentication Authenticate to the Mailercloud API with an API key in the authorization header. To authenticate, add an `authorization` header to your API request that contains an API key. API Keys allow you to use another method of authentication separate from your account username and password. API Keys add an additional layer of security for your account. To use keys, you must set a plain text header named `authorization` where the contents of the header is your API Secret Key. ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/campaign \ --header 'Authorization: Your API key here' \ --header 'Content-Type: application/json' ``` You are responsible for the security of your API key; we recommend that you store it in a secure location on your server. Because of the potential security risks associated with exposing your API key, Mailercloud does not support client-side implementation of the API using CORS requests. ## Creating API keys Create your key directly here: **[app.mailercloud.com/account/api-integrations](https://app.mailercloud.com/account/api-integrations)** (in-app: Account → API Integrations). You can create up to 10 different API keys and delete a key whenever you want. For the **Email Verifier API**, keys are separate — create them at **[app.mailercloud.com/email-verifier/api-keys](https://app.mailercloud.com/email-verifier/api-keys)** (in-app: Email Verification → API Key). # Conventions & versioning Source: https://apidoc.mailercloud.com/conventions Naming conventions per product, pagination, API versions, idempotency, and SDK status. ## Field naming per product The two API products use different casing conventions — this is intentional and stable: | Product | Casing | Example | | ------------- | ------------ | ---------------------------------------- | | Marketing API | `snake_case` | `sender_email`, `list_ids`, `is_publish` | | Email API | `camelCase` | `fromName`, `replyTo`, `campaignType` | Don't mix them: a `from_name` sent to the Email API (or a `senderEmail` to the Marketing API) is silently ignored or rejected. ## Pagination List endpoints across the Marketing API use **page-based pagination** with two required body fields: ```json theme={null} { "page": 1, "limit": 10 } ``` `page` starts at 1. Responses include a total count so you can compute the number of pages. There is no cursor-based pagination. ## API versions * **v1** (`https://cloudapi.mailercloud.com/v1`) — the current Marketing API. All endpoints except one. * **v2** (`https://cloudapi.mailercloud.com/v2`) — currently a single endpoint, [Create Campaign (v2)](/api-reference/campaigns/create-campaign-v2), which offers more options than the v1 create (pause rules, frequency cap, tag/segment targeting). Both versions are fully supported; v2 is recommended for new integrations that need those capabilities. * **Email API** versioning is expressed in the request body: `version: "1.0"` (HTML only) or `"2.0"` (with AMP). ## Idempotency The APIs do not currently support idempotency keys. A request that times out client-side may still have been processed — for sends, this means a retry can deliver a duplicate email. Design batch retries accordingly: prefer confirming state (e.g. campaign exists, contact exists via [upsert](/api-reference/contacts/create-or-update-contact)) over blind re-submission of send requests. ## SDKs Plain HTTP/cURL is the officially supported integration path — every endpoint page shows generated examples in cURL, Python, JavaScript, PHP, and Go. There are no official SDK packages at this time; AI-assisted integration is first-class instead (see [Use with AI tools](/ai-tools)). # Errors Source: https://apidoc.mailercloud.com/errors Error formats for every Mailercloud API product, the Email API internal status-code table, and which errors are retryable. Each product returns a distinct error envelope. This page maps all of them. ## Marketing API (`cloudapi.mailercloud.com`) Standard HTTP status codes with a field-level error array: ```json theme={null} { "errors": [ { "field": "sender_email", "message": "sender_email must be a valid email address" } ] } ``` | HTTP | Meaning | Retry? | | ----- | ---------------------------------------------- | -------------------- | | `400` | Validation failed — see `errors[].field` | No — fix the request | | `401` | Missing/invalid API key | No | | `404` | Resource not found | No | | `429` | Rate limited — see [Rate limits](/rate-limits) | Yes, with backoff | | `5xx` | Server error | Yes, with backoff | ## Email API (`email-api.mailercloud.com`) The Email API returns an envelope with its own internal status code system: ```json theme={null} { "status": "SUCCESS", "statusCode": 1000, "message": "NA" } ``` **Always check `statusCode`, not just the HTTP status.** Some delivery-outcome codes are returned with HTTP `200` even though they represent a failure (e.g. `9007` Hard bounce). An agent or client that keys only off HTTP status will misread these as success. ### Internal status codes | Code | Meaning | Typical HTTP | Retry? | | ------ | ------------------------------------------------------------------ | ------------ | ------------------------ | | `1000` | Success | 200 | — | | `9001` | Throttling error | 429 | ✅ backoff | | `9002` | Message sending quota exceeded | 200 | ❌ raise quota | | `9003` | Authentication failure | 403 | ❌ | | `9004` | Recipient address not specified | 400 | ❌ | | `9005` | From field missing | 400 | ❌ | | `9006` | Soft bounce (temporarily deferred) | 200 | ✅ later | | `9007` | Hard bounce | 200 | ❌ remove address | | `9008` | Email reported as spam | 200 | ❌ | | `9009` | Email unsubscribed | 200 | ❌ | | `9010` | Email in suppression list | 200 | ❌ | | `9011` | Sender address not verified | 400 | ❌ verify sender | | `9012` | ESP rejected message | 200 | ❌ | | `9013` | Request to ESP expired | 200 | ✅ | | `9014` | ESP unavailable | 500 | ✅ backoff | | `9015` | IP not whitelisted with ESP | 401 | ❌ | | `9016` | Subject field empty | 400 | ❌ | | `9017` | Invalid sender address | 400 | ❌ | | `9018` | Invalid email address | 400 | ❌ | | `9019` | Recipient's mailbox is full | 200 | ✅ later | | `9021` | Mailbox not found on email server | 200 | ❌ | | `9022` | Unsupported version | 400 | ❌ — use `1.0`/`2.0` | | `9024` | Authorization failure | 403 | ❌ | | `9452` | Message overloading | 200 | ✅ backoff | | `9512` | Host email server not found | 200 | ❌ | | `9999` | Unknown error occurred | 200 | ✅ once, then investigate | | `8000` | Campaign ID required for inbox tracking | 400 | ❌ | | `8001` | Campaign ID format invalid (alphanumeric/hyphen/tilde, ≤100 chars) | 400 | ❌ | ## Email Verifier API (`verify.mailercloud.com`) Simple error object with standard HTTP semantics: ```json theme={null} { "error": "Invalid or inactive API key" } ``` | HTTP | Meaning | Retry? | | ----- | ---------------------------------------------------- | ----------------- | | `400` | Invalid request (bad JSON, >50 emails, missing file) | No | | `401` | Missing/invalid API key | No | | `402` | Insufficient credits | No — buy credits | | `413` | File too large (>10 MB or >100k emails) | No | | `503` | Service busy | Yes, with backoff | # Sync contacts in real time Source: https://apidoc.mailercloud.com/guides/contact-sync Push signups from your website, app, or CRM into Mailercloud lists as they happen. Three endpoints cover almost every sync scenario: | Scenario | Endpoint | | ---------------------------------------------- | --------------------------------------------------------------------------- | | New signup on your site | [`POST /contacts`](/api-reference/contacts/create-contact) | | Might already exist (form resubmits, CRM sync) | [`POST /contacts/upsert`](/api-reference/contacts/create-or-update-contact) | | Bulk import (migrations, nightly sync) | [`POST /contacts/batch`](/api-reference/contacts/create-batch-contact) | ## Real-time: one contact per event Call this from your signup handler, checkout flow, or form webhook (e.g. a Wix or WordPress form): ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/contacts \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "email": "jane@example.com", "first_name": "Jane", "list_id": "YOUR_LIST_ID", "tags": ["signup-website"] }' ``` Use `tags` to record where the contact came from — you can segment and trigger automations on tags later. ## Idempotent sync: upsert If the same email may be submitted more than once, use **upsert** instead — it creates the contact if new, updates it if it exists, and won't fail on duplicates. ## Bulk: batch create For imports, send up to a full batch in one call with `contacts` (array) and `list_id`. For very large one-time migrations, consider the CSV import wizard in the app instead — it includes field mapping and validation. ## Custom fields Contacts accept a `custom_fields` object keyed by your account's custom-field IDs. List your fields via the app under **Audience → Custom fields**, or see [Custom Properties](/api-reference/custom-properties) to manage them via API. # Mailercloud MCP server Source: https://apidoc.mailercloud.com/guides/mcp-server Let AI agents act on your Mailercloud account — create campaigns, manage contacts, send email, and analyze performance via the Model Context Protocol. Mailercloud ships a full-platform [Model Context Protocol](https://modelcontextprotocol.io) server. Connect it to Claude, Cursor, or any MCP-compatible agent and your assistant can **take real actions on your account** — not just read documentation. ``` https://mcp.mailercloud.com/mcp ``` This is different from the docs search MCP (`apidoc.mailercloud.com/mcp`), which lets agents *read this documentation*. The Mailercloud MCP server lets agents *operate your account*: create campaigns, manage contacts, send transactional email, and more. Most integrations want both. ## What agents can do 47 tools covering the platform, including: * **Campaigns** — list, create, update, schedule, send test emails, AI performance analysis and comparison * **Contacts & lists** — create/update/upsert contacts, batch imports, manage lists and tags * **Templates** — full CRUD * **Transactional email** — send via the Email API * **Webhooks & automations** — manage webhooks, inspect automations * **Analytics** — engagement funnels, deliverability health, campaign audits and benchmarks ## Connect **Claude (web/desktop):** Settings → Connectors → Add custom connector → paste the URL above; authenticate when prompted. **Claude Code:** ```bash theme={null} claude mcp add mailercloud --transport http https://mcp.mailercloud.com/mcp ``` **Cursor / other MCP clients:** add an HTTP (streamable) MCP server with the same URL. ## Authentication The server supports OAuth sign-in (you'll be prompted in the client) with API-key fallback. All actions are scoped to your own Mailercloud account. An agent connected to this server can make real changes — create and schedule campaigns, modify contacts. Grant access to trusted tools only, and prefer a test account for experimentation. # Quickstart: send your first campaign Source: https://apidoc.mailercloud.com/guides/quickstart Create a list, add a contact, and send your first email campaign in five minutes. ## 1. Get your API key In your Mailercloud account, open **Settings → API** and create a key. You can create up to 10 keys. Every request below sends this key in the `Authorization` header (plain text, no `Bearer` prefix). ## 2. Create a list ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/list \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{"list_type": 1, "name": "Newsletter Subscribers"}' ``` The response includes the list's `id` — you'll need it in the next steps. ## 3. Add a contact ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/contacts \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "email": "jane@example.com", "first_name": "Jane", "list_id": "YOUR_LIST_ID" }' ``` ## 4. Create a campaign `name`, `subject`, `sender`, and `list_ids` are required, plus your HTML content: ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/campaign \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "name": "My first campaign", "subject": "Hello from Mailercloud", "sender": { "sender_email": "you@yourdomain.com", "sender_name": "Your Name" }, "list_ids": ["YOUR_LIST_ID"], "html": "

Hello!

My first campaign.

" }' ``` The sender email must belong to a [verified sender](/api-reference/senders) on your account. ## 5. Send a test email, then schedule Preview it in your own inbox first: ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/campaign/testmail/YOUR_CAMPAIGN_ID \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{"email": "you@yourdomain.com"}' ``` Happy with it? Send or schedule it with [Schedule Campaign](/api-reference/campaigns/schedule-campaign). ## Next steps * [Send transactional email](/guides/transactional-email) for receipts, OTPs, and notifications * [Sync contacts in real time](/guides/contact-sync) from your app or website * [Set up webhooks](/guides/webhooks) to receive campaign events # Send via SMTP relay Source: https://apidoc.mailercloud.com/guides/smtp-relay Send transactional email through Mailercloud's SMTP relay from any framework, CMS, or legacy system — no code changes beyond SMTP settings. If your application already speaks SMTP (WordPress, Laravel, legacy systems, CRMs), you can send through Mailercloud without integrating the HTTP API — just point your SMTP settings at the relay. ## Connection settings | Setting | Value | | -------------- | ---------------------------------- | | Host | `smtp-relay.mailercloud.com` | | Ports | `587`, `2525`, or `465` | | Authentication | `AUTH PLAIN` — username + password | ## Credentials Switch to the **Transactional Email platform** (toggle in the sidebar), then open **Settings → SMTP Configuration** to view your host, username, and password. Use **Generate new password** to create or rotate the password. Generating a new password invalidates the previous one immediately — update all systems using the old credentials. ## Tracking headers Control tracking per message with custom SMTP headers: | Header | Purpose | | ----------------------- | ------------------------------------------------ | | `mld-track-opens` | `true`/`false` — enable or disable open tracking | | `mld-track-inbox` | `true`/`false` — enable inbox-placement tracking | | `mld-track-campaign-id` | Group sends under a campaign ID for reporting | ## Security & delivery extras * **IP Allowed List** — restrict which IP addresses may send through your account (single IPs, ranges, or wildcards). If unset, all IPs are allowed. * **Webhooks** — receive real-time events for transactional sends: Sent, Delivery, Bounce, Spam, Open. See [Set up webhooks](/guides/webhooks). ## Example (Laravel `.env`) ```ini theme={null} MAIL_MAILER=smtp MAIL_HOST=smtp-relay.mailercloud.com MAIL_PORT=587 MAIL_USERNAME=your-smtp-username MAIL_PASSWORD=your-smtp-password MAIL_FROM_ADDRESS=orders@yourdomain.com ``` ## SMTP vs HTTP API — which to use? | | SMTP relay | [HTTP Email API](/api-reference/email/send-email) | | ------------------------------------------ | ------------------------------------------- | -------------------------------------------------------------- | | Setup | Config change only | Small code integration | | Per-recipient personalization (mail merge) | ❌ Not supported | ✅ [`/email-api`](/api-reference/email/send-personalized-email) | | Best for | Existing apps, CMS plugins, quick migration | New integrations, personalization, richer control | The sender domain must be [verified](/authentication) on your account in either case. # Send transactional email Source: https://apidoc.mailercloud.com/guides/transactional-email Send order confirmations, OTPs, and notifications with the Mailercloud Email API from PHP, Node.js, or any HTTP client. Transactional emails (order confirmations, password resets, OTPs) use the dedicated **Email API** at `https://email-api.mailercloud.com` — separate from the campaign API. Set `version` to `"1.0"` when sending `html` only, or `"2.0"` when including `amp_html`. ```bash cURL theme={null} curl --request POST \ --url https://email-api.mailercloud.com/email \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "version": "1.0", "email": { "from": "orders@yourdomain.com", "fromName": "Acme Store", "subject": "Your order is confirmed", "html": "

Thanks for your order!

", "text": "Thanks for your order!", "recipients": { "to": [{ "name": "Jane", "email": "jane@example.com" }] } } }' ``` ```php PHP theme={null} '1.0', 'email' => [ 'from' => 'orders@yourdomain.com', 'fromName' => 'Acme Store', 'subject' => 'Your order is confirmed', 'html' => '

Thanks for your order!

', 'text' => 'Thanks for your order!', 'recipients' => [ 'to' => [['name' => 'Jane', 'email' => 'jane@example.com']], ], ], ]; $ch = curl_init('https://email-api.mailercloud.com/email'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: YOUR_API_KEY', 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode($payload), ]); $response = curl_exec($ch); curl_close($ch); echo $response; ``` ```javascript Node.js theme={null} const response = await fetch("https://email-api.mailercloud.com/email", { method: "POST", headers: { Authorization: "YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ version: "1.0", email: { from: "orders@yourdomain.com", fromName: "Acme Store", subject: "Your order is confirmed", html: "

Thanks for your order!

", text: "Thanks for your order!", recipients: { to: [{ name: "Jane", email: "jane@example.com" }], }, }, }), }); console.log(await response.json()); ```
## Per-recipient personalization (mail merge) To personalize each recipient's email in a single request — `Hi {{first_name}}, your order {{order.id}} shipped` — use the [mail merge endpoint](/api-reference/email/send-personalized-email): same request structure at `POST /email-api`, plus a `merge_vars` object on each `recipients.to[]` entry. ## Attachments Pass an `attachments` array with a `name` and a publicly fetchable `url` per file — see the [full reference](/api-reference/email/send-email). # Connect forms to your audience Source: https://apidoc.mailercloud.com/guides/webforms Grow lists from your website: Mailercloud webforms, or wire any third-party form (Wix, WordPress, custom) to the contacts API. There are two ways to feed website signups into Mailercloud. ## Option 1 — Mailercloud webforms (no code) Build a form in the app under **Audience → Webforms**, style it, and embed the generated snippet on your site. Submissions land directly in the connected list — no API work needed. You can list your forms programmatically with [Webform list](/api-reference/webforms/webform-list). ## Option 2 — Any third-party form via the API If your form lives in Wix, WordPress, Framer, or your own code, point its submit handler (or the form platform's webhook) at a small endpoint on your server that forwards to Mailercloud: ```javascript Node.js form handler theme={null} app.post("/newsletter-signup", async (req, res) => { await fetch("https://cloudapi.mailercloud.com/v1/contacts/upsert", { method: "POST", headers: { Authorization: process.env.MAILERCLOUD_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ email: req.body.email, first_name: req.body.name, list_id: process.env.LIST_ID, tags: ["signup-website"], }), }); res.redirect("/thanks"); }); ``` Always call the Mailercloud API from your **server**, never from browser JavaScript — your API key must not be exposed to visitors, and the API does not support CORS requests by design. Use **upsert** (not create) so repeat submissions update the existing contact instead of failing, and add a `tags` value per form so you can tell your signup sources apart — see [Sync contacts in real time](/guides/contact-sync). # Set up webhooks Source: https://apidoc.mailercloud.com/guides/webhooks Receive real-time notifications in your systems when campaigns send, open, click, bounce, or unsubscribe. Webhooks push campaign events to your endpoint as they happen — no polling. ## Supported events `campaign_sent` · `campaign_opened` · `campaign_clicked` · `unsubscribe` · `campaign_error` · `spam` · `hard_bounce` ## Create a webhook ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/webhooks \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "name": "CRM sync", "url": "https://yourapp.com/hooks/mailercloud", "events": ["campaign_sent", "campaign_opened", "hard_bounce", "unsubscribe"] }' ``` Your endpoint should return a `2xx` status quickly; do any heavy processing asynchronously. ## Test it Fire a sample payload at your endpoint before going live with [Test webhook](/api-reference/webhooks/test-webhook), and pause/resume delivery any time with [Toggle webhook status](/api-reference/webhooks/toggle-webhook-status). ## Typical uses * Sync unsubscribes and hard bounces back to your CRM so you stop emailing dead addresses everywhere * Trigger in-app flows when a customer opens or clicks a campaign * Alert your team on `campaign_error` events # Introduction Source: https://apidoc.mailercloud.com/index The Mailercloud API provides access to Mailercloud data and functionality — sync data, manage contacts and lists, create campaigns, and send email programmatically. ## Base URLs Mailercloud exposes three API products, each with its own base URL: | Product | Base URL | Reference | | ------------------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------- | | **Marketing API** — campaigns, contacts, lists, segments, webhooks, automations | `https://cloudapi.mailercloud.com/v1` | [Marketing API](/api-reference) | | **Email API** — transactional and personalized sending | `https://email-api.mailercloud.com` | [Email API](/api-reference/email/send-email) | | **Email Verifier API** — verify addresses and clean lists | `https://verify.mailercloud.com` | [Email Verifier](/api-reference/verification/verify-emails) | All three accept `application/json` request bodies and return JSON responses. One Marketing API endpoint has a newer v2 version with additional options — [Create Campaign (v2)](/api-reference/campaigns/create-campaign-v2), served under `/v2`. All other Marketing endpoints use `/v1`. See [Conventions & versioning](/conventions). ## Get started Create a list, add a contact, and send your first campaign in five minutes. Campaigns, contacts, lists, tags, segments, webhooks, automations and more — 56 endpoints. Send transactional email programmatically. Connect Claude, Cursor, or ChatGPT to these docs via MCP and llms.txt. ## Quick example Create a contact list with a single request: ```bash theme={null} curl --request POST \ --url https://cloudapi.mailercloud.com/v1/list \ --header 'Authorization: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{"list_type":1,"name":"Subscription List"}' ``` ## API limits To protect the platform from malicious usage, requests are rate-limited. These limits prevent a single user from making too many calls at once; exceeding them can block your API access. ## We're here to help Questions? Reach us at [mailercloud.com/contact-us](https://www.mailercloud.com/contact-us) and we'll be happy to answer. # Rate limits & retries Source: https://apidoc.mailercloud.com/rate-limits Request limits per product, what a 429 looks like, and how to implement correct backoff. ## Marketing API (`cloudapi.mailercloud.com`) Requests are rate-limited per client IP using a sliding one-second window of **50 requests per second** (higher limits can be arranged for specific IPs — contact support). When the limit is exceeded the API responds: ```http theme={null} HTTP/1.1 429 Too Many Requests ``` ```json theme={null} { "message": "Too Many Requests" } ``` The API does not currently send `X-RateLimit-*` or `Retry-After` headers. Clients — especially AI agents doing batch work — should treat any `429` as a signal to back off exponentially rather than expecting a server-provided retry time. ## Email API (`email-api.mailercloud.com`) Transactional sending is governed by your account's sending quota and throttling rules rather than a fixed per-second number. Two internal status codes signal limits (see [Errors](/errors)): | Code | Meaning | Action | | ------ | ------------------------------ | ------------------------------- | | `9001` | Throttling error | Retry with backoff | | `9002` | Message sending quota exceeded | Do not retry — raise your quota | ## Email Verifier API (`verify.mailercloud.com`) Requests are rate-limited; a `503 service busy, please retry` response also indicates transient capacity pressure — retry with backoff. ## Recommended retry strategy Retry `429`, `5xx`, and throttling responses with exponential backoff and jitter; do not retry validation (`400`) or auth (`401`/`403`) errors. ```javascript theme={null} async function withBackoff(fn, maxRetries = 5) { for (let attempt = 0; ; attempt++) { const res = await fn(); if (res.status !== 429 && res.status < 500) return res; if (attempt >= maxRetries) return res; const delay = Math.min(30000, 1000 * 2 ** attempt) + Math.random() * 500; await new Promise((r) => setTimeout(r, delay)); } } ``` For sustained batch work (e.g. contact syncs), keep total request rate below the limit by pacing requests rather than relying on retries.