Audience

Contacts & lists

Sync subscribers, custom attributes and list memberships from your backend or CRM using the Brevo v3-compatible /v3/contacts endpoints.

Every endpoint on this page requires an API key with the contacts:write permission (or a key with full access). Adding a contact to a list automatically schedules any active autoresponders and enrolls the contact in any active visual automation workflows configured with a list_joined trigger.

Create or upsert a contact

POST/v3/contactsPermission contacts:write

Creates a new contact, or updates an existing contact when updateEnabled: true is passed. Attribute keys are normalised to uppercase (e.g. FIRSTNAME, PLAN, LTV) and merged with existing attributes on upsert.

ParameterTypeDescription
emailrequiredstringContact email address (normalised to lowercase).
attributesobjectKey-value map of custom contact attributes (strings, numbers or booleans). Available in templates as {{ contact.KEY }} and in dynamic segments and workflow conditions.
listIdsstring[]List UUIDs to subscribe the contact to immediately.
updateEnabledbooleanWhen true, updates the contact if the email already exists (200 OK). When false (default), an existing email returns 400 duplicate_parameter.
emailBlacklistedbooleanOptional flag to mark the contact as unsubscribed from marketing emails.
curl -X POST 'https://app.snappymails.com/v3/contacts' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "jane@example.com",
    "attributes": {
      "FIRSTNAME": "Jane",
      "LASTNAME": "Doe",
      "PLAN": "Enterprise",
      "LTV": 2400
    },
    "listIds": [
      "7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c"
    ],
    "updateEnabled": true
  }'

Responses

201 Created (new contact)
{
  "id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
}
200 OK (existing contact with updateEnabled: true)
{
  "id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
  "updated": true
}

List contacts

GET/v3/contactsPermission contacts:write
ParameterTypeDescription
limitintegerNumber of contacts to return (default 50, max 1000).
offsetintegerZero-based offset for pagination (default 0).
emailstringOptional search filter matching the email address.
curl 'https://app.snappymails.com/v3/contacts?limit=50&offset=0' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json'

Get a contact

GET/v3/contacts/{identifier}Permission contacts:write

identifier can be either the contact's UUID or their URL-encoded email address (for example jane%40example.com).

curl 'https://app.snappymails.com/v3/contacts/jane%40example.com' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json'
200 OK
{
  "id": "c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
  "email": "jane@example.com",
  "emailBlacklisted": false,
  "smsBlacklisted": false,
  "createdAt": "2026-10-20T09:15:00Z",
  "modifiedAt": "2026-10-28T14:22:10Z",
  "listIds": [
    "7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c"
  ],
  "attributes": {
    "FIRSTNAME": "Jane",
    "LASTNAME": "Doe",
    "PLAN": "Enterprise",
    "LTV": 2400
  }
}

Update a contact

PUT/v3/contacts/{identifier}Permission contacts:write

Updates a contact by UUID or URL-encoded email address. Passed attributes are merged into the contact's existing attributes. Returns 204 No Content.

ParameterTypeDescription
attributesobjectAttributes to merge onto the contact.
emailBlacklistedbooleanSet to true to unsubscribe or false to resubscribe.
listIdsstring[]Lists to add the contact to (triggers autoresponders & workflows).
unlinkListIdsstring[]Lists to remove the contact from.
curl -X PUT 'https://app.snappymails.com/v3/contacts/jane%40example.com' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "attributes": {
      "PLAN": "VIP",
      "LTV": 3600
    },
    "listIds": [
      "9a2b3c4d-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
    ],
    "unlinkListIds": [
      "7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c"
    ]
  }'

Delete a contact

DELETE/v3/contacts/{identifier}Permission contacts:write

Permanently deletes the contact and removes their list memberships. Returns 204 No Content. (For GDPR right-to-erasure with cryptographic suppression and event pseudonymisation, use the portal endpoint POST /api/v1/contacts/{id}/erase.)

curl -X DELETE 'https://app.snappymails.com/v3/contacts/jane%40example.com' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json'

Manage subscriber lists

GET/v3/contacts/listsPermission contacts:write
curl 'https://app.snappymails.com/v3/contacts/lists' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json'
200 OK
{
  "count": 1,
  "lists": [
    {
      "id": "7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
      "name": "Newsletter Subscribers",
      "optInType": "SINGLE",
      "totalSubscribers": 1240
    }
  ]
}

Create a list

POST/v3/contacts/listsPermission contacts:write
curl -X POST 'https://app.snappymails.com/v3/contacts/lists' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Product Launch VIPs"
  }'

Add or remove contacts from a list

POST/v3/contacts/lists/{listId}/contacts/addPermission contacts:write
POST/v3/contacts/lists/{listId}/contacts/removePermission contacts:write

Pass either {"emails": ["..."]} or {"ids": ["uuid", ...]}. Adding contacts to a list schedules any active autoresponders and triggers active list_joined workflows.

curl -X POST 'https://app.snappymails.com/v3/contacts/lists/7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c/contacts/add' \
  -H "api-key: $SNAPPYMAILS_API_KEY" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "emails": [
      "jane@example.com",
      "omar@example.com"
    ]
  }'
201 Created
{
  "contacts": {
    "success": ["jane@example.com", "omar@example.com"],
    "failure": []
  }
}

Public subscribe & sign-up forms

For browser-side newsletter forms where you cannot use a secret API key, use either a hosted/embedded Sign-up Form configured in the portal (Forms) or the unauthenticated public subscribe endpoint:

POST/api/public/subscribeNo API key required (public)
Request body
{
  "list_id": "7b1a2c3d-d5e6-4f7a-8b9c-0d1e2f3a4b5c",
  "email": "jane@example.com",
  "attributes": {
    "FIRSTNAME": "Jane"
  }
}
  • On a SINGLE opt-in list, the contact joins immediately ({"status": "ok"}) and triggers autoresponders and list_joined workflows.
  • On a DOUBLE opt-in list, SnappyMails creates a pending membership, sends a branded confirmation email and returns {"status": "pending"}; the contact joins only after clicking the confirmation link.

1-Click Brevo Migration

Moving from Brevo? Open Events & Brevo Import in the portal to import all of your Brevo lists, contacts, custom attributes, templates and blocklisted addresses in one click.