Campaigns API

Retrieve campaign information and detailed stats via the API. Use this to power external reporting dashboards, sync campaign data to your data warehouse, or build custom analytics views.

Campaigns are read-only via API

Campaign creation, editing, and sending is done in the EmailSendX dashboard. The API exposes campaign data for reading and reporting purposes. This makes it easy to pull stats into your BI tools without granting dashboard access.

The Campaign Object

A campaign represents a single email send — either a one-time broadcast or a scheduled message. The stats object is included when you retrieve a single campaign using the id query parameter.

json
{
  "id": "clx_camp_april_nl_id",
  "name": "April Newsletter",
  "subject": "What's new this April 🌱",
  "status": "sent",
  "scheduledAt": null,
  "sentAt": "2026-04-15T10:00:00Z",
  "totalRecipients": 5420,
  "stats": {
    "sent": 5420,
    "delivered": 5388,
    "opened": 2168,
    "uniqueOpens": 1945,
    "clicked": 542,
    "uniqueClicks": 487,
    "bounced": 32,
    "complained": 4,
    "unsubscribed": 18
  },
  "createdAt": "2026-04-10T09:00:00Z"
}
FieldTypeDescription
idstringUnique campaign identifier
namestringInternal campaign name (not shown to recipients)
subjectstringEmail subject line
statusenumdraft, scheduled, sending, sent, paused, or cancelled
scheduledAtstring | nullISO 8601 scheduled send time, or null if sent immediately
sentAtstring | nullISO 8601 time sending completed, null if not yet sent
totalRecipientsintegerNumber of contacts the campaign was sent to
stats.sentintegerTotal send attempts
stats.deliveredintegerEmails accepted by recipient mail servers
stats.openedintegerTotal open events (includes re-opens by same contact)
stats.uniqueOpensintegerUnique contacts who opened at least once
stats.clickedintegerTotal click events
stats.uniqueClicksintegerUnique contacts who clicked at least once
stats.bouncedintegerHard + soft bounce count
stats.complainedintegerSpam complaint count
stats.unsubscribedintegerUnsubscribe count from this campaign

Endpoints

Campaign endpoints require the campaigns:read scope.

List Campaigns

GET/api/v1/campaignsscope: campaigns:read

Returns a paginated list of campaigns. Pass the id query parameter to retrieve a single campaign with full stats. Supports filtering by status.

Parameters

NameTypeInRequiredDescription
pageintegerqueryoptionalPage number (default: 1)
limitintegerqueryoptionalResults per page, max 100 (default: 50)
idstringqueryoptionalRetrieve a single campaign by ID — includes full stats object
statusstringqueryoptionalFilter by status: draft, scheduled, sending, sent, paused, cancelled

Response

json
{
  "data": [
    {
      "id": "clx_camp_april_nl_id",
      "name": "April Newsletter",
      "subject": "What's new this April 🌱",
      "status": "sent",
      "scheduledAt": null,
      "sentAt": "2026-04-15T10:00:00Z",
      "totalRecipients": 5420,
      "stats": {
        "sent": 5420,
        "delivered": 5388,
        "opened": 2168,
        "uniqueOpens": 1945,
        "clicked": 542,
        "uniqueClicks": 487,
        "bounced": 32,
        "complained": 4,
        "unsubscribed": 18
      },
      "createdAt": "2026-04-10T09:00:00Z"
    },
    {
      "id": "clx_camp_march_nl_id",
      "name": "March Newsletter",
      "subject": "Spring into better workflows",
      "status": "sent",
      "scheduledAt": "2026-03-18T10:00:00Z",
      "sentAt": "2026-03-18T10:02:00Z",
      "totalRecipients": 5180,
      "stats": {
        "sent": 5180,
        "delivered": 5151,
        "opened": 2020,
        "uniqueOpens": 1804,
        "clicked": 498,
        "uniqueClicks": 441,
        "bounced": 29,
        "complained": 2,
        "unsubscribed": 14
      },
      "createdAt": "2026-03-10T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 24,
    "totalPages": 1
  }
}

Understanding Campaign Stats

Stats are updated in real time as emails are delivered, opened, and clicked. Here are the key derived metrics you can calculate from the stats object:

bash
# Derived metrics from stats fields:

Open Rate          = (uniqueOpens / delivered) * 100
Click-to-Open Rate = (uniqueClicks / uniqueOpens) * 100
Bounce Rate        = (bounced / sent) * 100
Complaint Rate     = (complained / delivered) * 100
Unsubscribe Rate   = (unsubscribed / delivered) * 100

# Example:
# Open Rate = (1945 / 5388) * 100 = 36.1%
# CTOR      = (487 / 1945) * 100  = 25.0%
# Bounce    = (32 / 5420) * 100   = 0.59%

Apple Mail Privacy Protection

Apple Mail Privacy Protection (MPP) causes open events to be recorded even when the recipient hasn't actively opened the email. Open rates on iOS/Mac clients may be inflated. Click data is not affected by MPP and is a more reliable engagement signal.

Building a reporting dashboard?

Pull campaign stats via the API and combine with your product data for attribution analysis.