Skip to content

Developers

The API, generated from the code that runs it

A cursor-paged REST API over contacts, lists, tags, segments, campaigns and automations.

Base URLhttps://mintmailer.app/api/v1Every path is relative to it, so /contacts is https://mintmailer.app/api/v1/contacts.

Getting started

Authentication. Send your key as Authorization: Bearer rvz_live_…. A key belongs to one organisation and carries a fixed set of scopes, chosen when it was created; every operation states the scope it requires. A key without the scope gets 403, and a request for another organisation's row gets 404 rather than 403 — confirming that an id exists elsewhere is itself a disclosure.

Pagination. List endpoints return {data, has_more, next_cursor}. Pass next_cursor back as cursor to walk forward; the default page is 50 rows and the maximum is 100. The cursor is a keyset, not an offset, so a row inserted while you page cannot cause a skip or a repeat — which is what makes an incremental sync safe. It is opaque: pass it back unmodified and do not parse it.

Idempotency. Send an Idempotency-Key header on any write and a retry of that exact request returns the first response byte for byte, including its status and any id, rather than creating a second row. Idempotent-Replay on the response says which of the two happened. Omitting the header is allowed and gives you ordinary at-least-once semantics.

Rate limits. Per key, not per organisation, so one integration cannot spend another's budget. RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset are on every response, so you never have to exceed the limit to discover it.

Versioning. v1 changes additively only: an endpoint, an optional field or a new enum value may appear at any time, and nothing is ever removed, renamed or retyped inside a major version. Parse leniently and a release cannot break you. No version is withdrawn on less than twelve months' notice, announced with a Sunset header on every affected response long before it stops answering.

Automations

get/automationsautomation:view

List automations

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
status"draft" | "active" | "paused" | "archived" | "draft" | "active" | "paused" | "archived"[]
Returns200 page of Automation in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "automation",
      "name": "Weekly digest",
      "status": "draft",
      "version": 1,
      "allow_reentry": true,
      "definition": {
        "version": 1,
        "entryNodeId": "entryNodeId",
        "nodes": {}
      },
      "activated_at": "2026-07-14T09:31:02.000Z",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
get/automations/{id}automation:view

Retrieve an automation

Path parameters

idrequiredstringThe automation's id.
Returns200 Automation in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "automation",
    "name": "Weekly digest",
    "status": "draft",
    "version": 1,
    "allow_reentry": true,
    "definition": {
      "version": 1,
      "entryNodeId": "entryNodeId",
      "nodes": {}
    },
    "activated_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
post/automations/{id}/activateautomation:edit

Turn an automation on, or resume a paused one

Path parameters

idrequiredstringThe automation's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns200 Automation in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "automation",
    "name": "Weekly digest",
    "status": "draft",
    "version": 1,
    "allow_reentry": true,
    "definition": {
      "version": 1,
      "entryNodeId": "entryNodeId",
      "nodes": {}
    },
    "activated_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
post/automations/{id}/enrollautomation:edit

Enrol contacts into an active automation

Path parameters

idrequiredstringThe automation's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

contact_idsrequiredstring[]
Returns200 Enrollment in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "object": "enrollment",
    "requested": 128,
    "enrolled": 128
  }
}
post/automations/{id}/pauseautomation:edit

Pause an automation, holding everyone inside it

Path parameters

idrequiredstringThe automation's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns200 Automation in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "automation",
    "name": "Weekly digest",
    "status": "draft",
    "version": 1,
    "allow_reentry": true,
    "definition": {
      "version": 1,
      "entryNodeId": "entryNodeId",
      "nodes": {}
    },
    "activated_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}

Campaigns

get/campaignscampaign:view

List campaigns

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
status"draft" | "scheduled" | "dispatching" | "sending" | "testing" | "paused" | "sent" | "cancelled" | "failed" | "draft" | "scheduled" | "dispatching" | "sending" | "testing" | "paused" | "sent" | "cancelled" | "failed"[]
Returns200 page of Campaign in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "campaign",
      "name": "Weekly digest",
      "status": "draft",
      "subject": "Your July statement",
      "preheader": "Everything that moved this month, in one place.",
      "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
      "from_name": "Acme",
      "from_email": "[email protected]",
      "reply_to": "[email protected]",
      "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
      "audience": {
        "include": {
          "list_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ],
          "tag_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ],
          "segment_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ]
        },
        "exclude": {
          "list_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ],
          "tag_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ],
          "segment_ids": [
            "cly3k9f2b0000q8n1h4d7g5xz"
          ]
        }
      },
      "track_opens": true,
      "track_clicks": true,
      "scheduled_at": "2026-07-14T09:31:02.000Z",
      "send_started_at": "2026-07-14T09:31:02.000Z",
      "send_completed_at": "2026-07-14T09:31:02.000Z",
      "recipient_count": 128,
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/campaignscampaign:edit

Create a campaign

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namerequiredstring
Returns201 Campaign in dataErrors: 400, 401, 403, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "campaign",
    "name": "Weekly digest",
    "status": "draft",
    "subject": "Your July statement",
    "preheader": "Everything that moved this month, in one place.",
    "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "from_name": "Acme",
    "from_email": "[email protected]",
    "reply_to": "[email protected]",
    "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "audience": {
      "include": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      },
      "exclude": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      }
    },
    "track_opens": true,
    "track_clicks": true,
    "scheduled_at": "2026-07-14T09:31:02.000Z",
    "send_started_at": "2026-07-14T09:31:02.000Z",
    "send_completed_at": "2026-07-14T09:31:02.000Z",
    "recipient_count": 128,
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/campaigns/{id}campaign:view

Retrieve a campaign

Path parameters

idrequiredstringThe campaign's id.
Returns200 Campaign in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "campaign",
    "name": "Weekly digest",
    "status": "draft",
    "subject": "Your July statement",
    "preheader": "Everything that moved this month, in one place.",
    "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "from_name": "Acme",
    "from_email": "[email protected]",
    "reply_to": "[email protected]",
    "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "audience": {
      "include": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      },
      "exclude": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      }
    },
    "track_opens": true,
    "track_clicks": true,
    "scheduled_at": "2026-07-14T09:31:02.000Z",
    "send_started_at": "2026-07-14T09:31:02.000Z",
    "send_completed_at": "2026-07-14T09:31:02.000Z",
    "recipient_count": 128,
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
patch/campaigns/{id}campaign:edit

Update a draft campaign

Path parameters

idrequiredstringThe campaign's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namestring
subjectstring | null
preheaderstring | null
sender_identity_idstring
reply_to"" | string | null
email_document_idstring
audienceobject
includeobject
excludeobject
track_opensboolean
track_clicksboolean
Returns200 Campaign in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "campaign",
    "name": "Weekly digest",
    "status": "draft",
    "subject": "Your July statement",
    "preheader": "Everything that moved this month, in one place.",
    "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "from_name": "Acme",
    "from_email": "[email protected]",
    "reply_to": "[email protected]",
    "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "audience": {
      "include": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      },
      "exclude": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      }
    },
    "track_opens": true,
    "track_clicks": true,
    "scheduled_at": "2026-07-14T09:31:02.000Z",
    "send_started_at": "2026-07-14T09:31:02.000Z",
    "send_completed_at": "2026-07-14T09:31:02.000Z",
    "recipient_count": 128,
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
delete/campaigns/{id}campaign:delete

Delete a draft or cancelled campaign

Path parameters

idrequiredstringThe campaign's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns204 no bodyErrors: 400, 401, 403, 404, 409, 422, 429, 500
post/campaigns/{id}/cancelcampaign:send

Cancel a scheduled or sending campaign

Path parameters

idrequiredstringThe campaign's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns200 Campaign in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "campaign",
    "name": "Weekly digest",
    "status": "draft",
    "subject": "Your July statement",
    "preheader": "Everything that moved this month, in one place.",
    "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "from_name": "Acme",
    "from_email": "[email protected]",
    "reply_to": "[email protected]",
    "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "audience": {
      "include": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      },
      "exclude": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      }
    },
    "track_opens": true,
    "track_clicks": true,
    "scheduled_at": "2026-07-14T09:31:02.000Z",
    "send_started_at": "2026-07-14T09:31:02.000Z",
    "send_completed_at": "2026-07-14T09:31:02.000Z",
    "recipient_count": 128,
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
post/campaigns/{id}/schedulecampaign:send

Schedule a campaign, or send it now

Path parameters

idrequiredstringThe campaign's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

scheduled_atstringWhen to send, as an ISO 8601 instant. Omit to send now.
Returns200 Campaign in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "campaign",
    "name": "Weekly digest",
    "status": "draft",
    "subject": "Your July statement",
    "preheader": "Everything that moved this month, in one place.",
    "sender_identity_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "from_name": "Acme",
    "from_email": "[email protected]",
    "reply_to": "[email protected]",
    "email_document_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "audience": {
      "include": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      },
      "exclude": {
        "list_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "tag_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ],
        "segment_ids": [
          "cly3k9f2b0000q8n1h4d7g5xz"
        ]
      }
    },
    "track_opens": true,
    "track_clicks": true,
    "scheduled_at": "2026-07-14T09:31:02.000Z",
    "send_started_at": "2026-07-14T09:31:02.000Z",
    "send_completed_at": "2026-07-14T09:31:02.000Z",
    "recipient_count": 128,
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/campaigns/{id}/statsanalytics:view

Retrieve a campaign's engagement totals and rates

Path parameters

idrequiredstringThe campaign's id.
Returns200 CampaignStats in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "object": "campaign_stats",
    "campaign_id": "cly3k9f2b0000q8n1h4d7g5xz",
    "sent": 128,
    "delivered": 128,
    "opened": 128,
    "unique_opened": 128,
    "clicked": 128,
    "unique_clicked": 128,
    "bounced": 128,
    "soft_bounced": 128,
    "complained": 128,
    "unsubscribed": 128,
    "failed": 128,
    "open_rate": 0.42,
    "click_rate": 0.42,
    "click_to_open_rate": 0.42,
    "bounce_rate": 0.42,
    "hard_bounce_rate": 0.42,
    "complaint_rate": 0.42,
    "unsubscribe_rate": 0.42,
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}

Contacts

get/contactscontact:view

List contacts

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
status"subscribed" | "unsubscribed" | "bounced" | "complained" | "pending" | "subscribed" | "unsubscribed" | "bounced" | "complained" | "pending"[]
list_idstring | string[]
tag_idstring | string[]
searchstring
Returns200 page of Contact in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "contact",
      "email": "[email protected]",
      "first_name": "Jamie",
      "last_name": "Rivera",
      "status": "subscribed",
      "custom_fields": {
        "plan": "Pro",
        "signup_source": "webinar"
      },
      "opt_in_source": "signup_form",
      "opt_in_at": "2026-07-14T09:31:02.000Z",
      "last_engaged_at": "2026-07-14T09:31:02.000Z",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/contactscontact:edit

Create or update a contact

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

emailrequiredstring
first_namestring | null
last_namestring | null
opt_in_sourcestring | null
status"subscribed" | "unsubscribed" | "bounced" | "complained" | "pending"
Returns200 or 201 Contact in dataErrors: 400, 401, 403, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "contact",
    "email": "[email protected]",
    "first_name": "Jamie",
    "last_name": "Rivera",
    "status": "subscribed",
    "custom_fields": {
      "plan": "Pro",
      "signup_source": "webinar"
    },
    "opt_in_source": "signup_form",
    "opt_in_at": "2026-07-14T09:31:02.000Z",
    "last_engaged_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/contacts/{id}contact:view

Retrieve a contact

Path parameters

idrequiredstringThe contact's id.
Returns200 Contact in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "contact",
    "email": "[email protected]",
    "first_name": "Jamie",
    "last_name": "Rivera",
    "status": "subscribed",
    "custom_fields": {
      "plan": "Pro",
      "signup_source": "webinar"
    },
    "opt_in_source": "signup_form",
    "opt_in_at": "2026-07-14T09:31:02.000Z",
    "last_engaged_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
patch/contacts/{id}contact:edit

Update a contact

Path parameters

idrequiredstringThe contact's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

emailstring
first_namestring | null
last_namestring | null
opt_in_sourcestring | null
status"subscribed" | "unsubscribed" | "bounced" | "complained" | "pending"
Returns200 Contact in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "contact",
    "email": "[email protected]",
    "first_name": "Jamie",
    "last_name": "Rivera",
    "status": "subscribed",
    "custom_fields": {
      "plan": "Pro",
      "signup_source": "webinar"
    },
    "opt_in_source": "signup_form",
    "opt_in_at": "2026-07-14T09:31:02.000Z",
    "last_engaged_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
delete/contacts/{id}contact:delete

Delete a contact

Path parameters

idrequiredstringThe contact's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns204 no bodyErrors: 400, 401, 403, 404, 409, 422, 429, 500
get/contacts/{id}/listslist:view

List the lists a contact belongs to

Path parameters

idrequiredstringThe contact's id.

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
Returns200 page of List in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "list",
      "name": "Weekly digest",
      "description": "Everyone who opened something in the last 90 days.",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
get/contacts/{id}/tagslist:view

List the tags on a contact

Path parameters

idrequiredstringThe contact's id.

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
Returns200 page of Tag in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "tag",
      "name": "Weekly digest",
      "color": "neutral",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Custom fields

get/custom_fieldscontact:view

List the organisation's custom field definitions

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
Returns200 page of CustomField in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "custom_field",
      "key": "plan",
      "label": "Plan",
      "type": "text",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Lists

get/listslist:view

List contact lists

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
namestring
Returns200 page of List in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "list",
      "name": "Weekly digest",
      "description": "Everyone who opened something in the last 90 days.",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/listslist:edit

Create a contact list

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namerequiredstring
descriptionstring | null
Returns201 List in dataErrors: 400, 401, 403, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "list",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/lists/{id}list:view

Retrieve a contact list

Path parameters

idrequiredstringThe list's id.
Returns200 List in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "list",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
patch/lists/{id}list:edit

Update a contact list

Path parameters

idrequiredstringThe list's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namestring
descriptionstring | null
Returns200 List in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "list",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
delete/lists/{id}list:edit

Delete a contact list, keeping its contacts

Path parameters

idrequiredstringThe list's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns204 no bodyErrors: 400, 401, 403, 404, 409, 422, 429, 500
get/lists/{id}/contactscontact:view

List the contacts on a list

Path parameters

idrequiredstringThe list's id.

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
Returns200 page of Contact in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "contact",
      "email": "[email protected]",
      "first_name": "Jamie",
      "last_name": "Rivera",
      "status": "subscribed",
      "custom_fields": {
        "plan": "Pro",
        "signup_source": "webinar"
      },
      "opt_in_source": "signup_form",
      "opt_in_at": "2026-07-14T09:31:02.000Z",
      "last_engaged_at": "2026-07-14T09:31:02.000Z",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/lists/{id}/contactslist:edit

Add contacts to a list

Path parameters

idrequiredstringThe list's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

contact_idsrequiredstring[]
Returns200 MembershipChange in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "object": "membership_change",
    "changed": 128
  }
}
delete/lists/{id}/contactslist:edit

Remove contacts from a list

Path parameters

idrequiredstringThe list's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

contact_idsrequiredstring[]
Returns200 MembershipChange in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "object": "membership_change",
    "changed": 128
  }
}

Segments

get/segmentssegment:view

List segments

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
namestring
Returns200 page of Segment in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "segment",
      "name": "Weekly digest",
      "description": "Everyone who opened something in the last 90 days.",
      "rules": {
        "version": 1,
        "match": "all",
        "groups": [
          "groups"
        ]
      },
      "last_count": 128,
      "last_counted_at": "2026-07-14T09:31:02.000Z",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/segmentssegment:edit

Create a segment

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namerequiredstring
descriptionstring | null
rulesrequiredany
Returns201 Segment in dataErrors: 400, 401, 403, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "segment",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "rules": {
      "version": 1,
      "match": "all",
      "groups": [
        "groups"
      ]
    },
    "last_count": 128,
    "last_counted_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/segments/{id}segment:view

Retrieve a segment

Path parameters

idrequiredstringThe segment's id.
Returns200 Segment in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "segment",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "rules": {
      "version": 1,
      "match": "all",
      "groups": [
        "groups"
      ]
    },
    "last_count": 128,
    "last_counted_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
patch/segments/{id}segment:edit

Update a segment

Path parameters

idrequiredstringThe segment's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namestring
descriptionstring | null
rulesany
Returns200 Segment in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "segment",
    "name": "Weekly digest",
    "description": "Everyone who opened something in the last 90 days.",
    "rules": {
      "version": 1,
      "match": "all",
      "groups": [
        "groups"
      ]
    },
    "last_count": 128,
    "last_counted_at": "2026-07-14T09:31:02.000Z",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
delete/segments/{id}segment:edit

Delete a segment

Path parameters

idrequiredstringThe segment's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns204 no bodyErrors: 400, 401, 403, 404, 409, 422, 429, 500
get/segments/{id}/contactscontact:view

List the contacts a segment selects

Path parameters

idrequiredstringThe segment's id.

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
Returns200 page of Contact in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "contact",
      "email": "[email protected]",
      "first_name": "Jamie",
      "last_name": "Rivera",
      "status": "subscribed",
      "custom_fields": {
        "plan": "Pro",
        "signup_source": "webinar"
      },
      "opt_in_source": "signup_form",
      "opt_in_at": "2026-07-14T09:31:02.000Z",
      "last_engaged_at": "2026-07-14T09:31:02.000Z",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Tags

get/tagslist:view

List tags

Query parameters

cursorstringnext_cursor from the previous page, passed back unmodified.
limitintegerRows per page, 1–100. Defaults to 50.
namestring
Returns200 page of Tag in dataErrors: 400, 401, 403, 429, 500

Example response

{
  "data": [
    {
      "id": "cly3k9f2b0000q8n1h4d7g5xz",
      "object": "tag",
      "name": "Weekly digest",
      "color": "neutral",
      "created_at": "2026-07-14T09:31:02.000Z",
      "updated_at": "2026-07-14T09:31:02.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/tagslist:edit

Create a tag

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namerequiredstring
color"neutral" | "positive" | "warning" | "danger" | "info"
Returns201 Tag in dataErrors: 400, 401, 403, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "tag",
    "name": "Weekly digest",
    "color": "neutral",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
get/tags/{id}list:view

Retrieve a tag

Path parameters

idrequiredstringThe tag's id.
Returns200 Tag in dataErrors: 400, 401, 403, 404, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "tag",
    "name": "Weekly digest",
    "color": "neutral",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
patch/tags/{id}list:edit

Update a tag

Path parameters

idrequiredstringThe tag's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

namestring
color"neutral" | "positive" | "warning" | "danger" | "info"
Returns200 Tag in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "id": "cly3k9f2b0000q8n1h4d7g5xz",
    "object": "tag",
    "name": "Weekly digest",
    "color": "neutral",
    "created_at": "2026-07-14T09:31:02.000Z",
    "updated_at": "2026-07-14T09:31:02.000Z"
  }
}
delete/tags/{id}list:edit

Delete a tag, keeping its contacts

Path parameters

idrequiredstringThe tag's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.
Returns204 no bodyErrors: 400, 401, 403, 404, 409, 422, 429, 500
post/tags/{id}/contactslist:edit

Apply a tag to contacts

Path parameters

idrequiredstringThe tag's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

contact_idsrequiredstring[]
Returns200 MembershipChange in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "object": "membership_change",
    "changed": 128
  }
}
delete/tags/{id}/contactslist:edit

Remove a tag from contacts

Path parameters

idrequiredstringThe tag's id.

Headers

Idempotency-KeystringA unique string of your choosing. Retrying a request with the same key returns the first response byte for byte — same status, same ids — instead of doing the work twice. Scoped to this key, this method and this path.

Request body

contact_idsrequiredstring[]
Returns200 MembershipChange in dataErrors: 400, 401, 403, 404, 409, 422, 429, 500

Example response

{
  "data": {
    "object": "membership_change",
    "changed": 128
  }
}

Object reference

Every resource carries an object field naming its type, so a client holding one response can tell what it has without inferring from the shape.

Automation

Fields

idrequiredstring
objectrequired"automation"
namerequiredstring
statusrequired"draft" | "active" | "paused" | "archived"
versionrequiredinteger
allow_reentryrequiredboolean
definitionrequiredobjectThe flow, in the grammar automationDefinitionSchema defines. Read-only in v1.
versionrequiredinteger
entryNodeIdrequiredstring | null
nodesrequiredobject
activated_atrequiredstring | null
created_atrequiredstring
updated_atrequiredstring

Campaign

Fields

idrequiredstring
objectrequired"campaign"
namerequiredstring
statusrequired"draft" | "scheduled" | "dispatching" | "sending" | "testing" | "paused" | "sent" | "cancelled" | "failed"
subjectrequiredstring | null
preheaderrequiredstring | null
sender_identity_idrequiredstring | null
from_namerequiredstring | null
from_emailrequiredstring | null
reply_torequiredstring | null
email_document_idrequiredstring | null
audiencerequiredobject
includerequiredobject
excluderequiredobject
track_opensrequiredboolean
track_clicksrequiredboolean
scheduled_atrequiredstring | null
send_started_atrequiredstring | null
send_completed_atrequiredstring | null
recipient_countrequiredinteger
created_atrequiredstring
updated_atrequiredstring

CampaignStats

Fields

objectrequired"campaign_stats"
campaign_idrequiredstring
sentrequiredinteger
deliveredrequiredinteger
openedrequiredinteger
unique_openedrequiredinteger
clickedrequiredinteger
unique_clickedrequiredinteger
bouncedrequiredinteger
soft_bouncedrequiredinteger
complainedrequiredinteger
unsubscribedrequiredinteger
failedrequiredinteger
open_raterequirednumber | null
click_raterequirednumber | null
click_to_open_raterequirednumber | null
bounce_raterequirednumber | null
hard_bounce_raterequirednumber | null
complaint_raterequirednumber | null
unsubscribe_raterequirednumber | null
updated_atrequiredstring | null

Contact

Fields

idrequiredstring
objectrequired"contact"
emailrequiredstring
first_namerequiredstring | null
last_namerequiredstring | null
statusrequired"subscribed" | "unsubscribed" | "bounced" | "complained" | "pending"
custom_fieldsrequiredobject
opt_in_sourcerequiredstring | null
opt_in_atrequiredstring | null
last_engaged_atrequiredstring | null
created_atrequiredstring
updated_atrequiredstring

CustomField

Fields

idrequiredstring
objectrequired"custom_field"
keyrequiredstring
labelrequiredstring
typerequired"text" | "number" | "date" | "boolean"
created_atrequiredstring
updated_atrequiredstring

Enrollment

Fields

objectrequired"enrollment"
requestedrequiredinteger
enrolledrequiredinteger

Error

Every 4xx and 5xx response has this shape, whatever went wrong.

Fields

errorrequiredobject
typerequired"invalid_request_error" | "authentication_error" | "permission_error" | "rate_limit_error" | "idempotency_error" | "api_error"The coarse class. Switch on this, not on code.
coderequired"parameter_invalid" | "parameter_missing" | "malformed_request" | "api_key_missing" | "api_key_invalid" | "api_key_revoked" | "api_key_expired" | "insufficient_scope" | "resource_missing" | "resource_conflict" | "idempotency_key_in_flight" | "unprocessable" | "rate_limit_exceeded" | "internal_error"The specific reason, for a human and for a log.
messagerequiredstring
paramstringThe offending field, as a dotted path. Present when one field is at fault.
request_idrequiredstringAlso returned in X-Request-Id. Quote it in a support message and we can find exactly this request.

List

Fields

idrequiredstring
objectrequired"list"
namerequiredstring
descriptionrequiredstring | null
created_atrequiredstring
updated_atrequiredstring

MembershipChange

Fields

objectrequired"membership_change"
changedrequiredinteger

Segment

Fields

idrequiredstring
objectrequired"segment"
namerequiredstring
descriptionrequiredstring | null
rulesrequiredobjectThe saved rule tree, in the grammar segmentRulesSchema defines. Pass it back unchanged to leave it alone.
versionrequiredinteger
matchrequired"all" | "any"
groupsrequiredany[]
last_countrequiredinteger | null
last_counted_atrequiredstring | null
created_atrequiredstring
updated_atrequiredstring

Tag

Fields

idrequiredstring
objectrequired"tag"
namerequiredstring
colorrequired"neutral" | "positive" | "warning" | "danger" | "info"
created_atrequiredstring
updated_atrequiredstring

Everything here is generated from the schemas the API actually validates against. The machine-readable form is at /api/v1/openapi.json.