v97

latestOpenAPI 3.1.0raw.githubusercontent.com2026-08-04231129815.9 KB
Subscribers

Create or update subscriber

Creates a new subscriber or handles existing ones based on the duplicateStrategy parameter.

Duplicate Strategies:

  • skip (default): Don't update existing subscribers
  • merge: Only fill in missing fields, never overwrite existing values
  • overwrite: Replace all fields (but never reactivate unsubscribed users)
post/subscribers

Request body

emailstring email

Required when creating a new subscriber unless a phone is provided (which creates a phone-only SMS contact). Optional when externalId identifies an existing subscriber.

externalIdstring

Customer-owned app/customer/user ID. Unique per company when provided.

firstNamestring
lastNamestring
phonestring nullable

Phone number in E.164 format or national format. Stored normalized to E.164. Invalid values fail with a 400 validation error. Does not affect SMS consent. With no email or externalId, creates or matches a phone-only (SMS) contact.

phoneCountrystring nullable

ISO 3166-1 alpha-2 country used to read a national-format phone, defaulting to US. A parsing hint only - the stored phoneCountry always comes from the parsed number. Sending it without phone fails with a 400 validation error.

smsConsentboolean

SMS marketing consent. true sets smsStatus to subscribed with consent source api, false sets unsubscribed, omitted leaves SMS status unchanged. Never inferred from phone presence.

status'active' | 'unsubscribed' | 'bounced'

Initial subscriber status.

optInMode'default' | 'confirmed' | 'double_opt_in'

Consent handling for this request:

  • default: obey the company double opt-in setting for new active subscribers; existing unsubscribed contacts are not sent confirmation email
  • confirmed: create or keep active immediately when you have verified consent
  • double_opt_in: send a confirmation email and keep the contact unsubscribed until they confirm
tagsstring[]
listsstring[]

List IDs to add subscriber to. If not provided, subscriber follows the workspace default lists setting. If empty array, subscriber is added to NO lists.

customAttributesobject
enrollInSequencesboolean

Whether to enroll the subscriber in matching sequences. Defaults to true for API calls, or to false when createdAt is supplied.

createdAtstring date-time

Original signup date, for importing history from another platform. Preserves the real date so date-relative segments are correct immediately. An existing contact's date only ever moves earlier, regardless of duplicateStrategy. Supplying this defaults enrollInSequences to false, and updatedAt is never backdated.

duplicateStrategy'skip' | 'merge' | 'overwrite'

How to handle existing subscribers:

  • skip: Don't update existing subscribers (default)
  • merge: Only fill in missing fields, never overwrite existing values
  • overwrite: Replace all fields (but never reactivate unsubscribed users)

Example request

{
  "email": "user@example.com",
  "externalId": "user_123",
  "firstName": "John",
  "lastName": "Doe",
  "phone": "+15551234567",
  "phoneCountry": "IT",
  "tags": [
    "newsletter"
  ],
  "lists": [
    "list-id-1",
    "list-id-2"
  ],
  "customAttributes": {
    "plan": "free"
  },
  "createdAt": "2019-03-14T09:30:00Z"
}

Response

Subscriber created or handled based on duplicate strategy

successboolean

Example response

{
  "success": true,
  "subscriber": {
    "id": "sub_abc123",
    "email": "user@example.com",
    "externalId": "user_123",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "+15551234567",
    "smsStatus": "subscribed",
    "status": "active",
    "emailProvider": "gmail",
    "tags": [
      "premium",
      "newsletter"
    ],
    "customAttributes": {
      "plan": "pro",
      "signupSource": "website"
    },
    "created": true
  },
  "optIn": {
    "required": true,
    "emailQueued": true
  }
}