Contacts: Create, Import & Status

Manage email contacts with status, tags, and custom fields

Contacts are the recipients of your emails. Create them individually, bulk-import from CSV, manage their status, and track bounces/complaints.

Create a Contact

Create a single contact.

cURL

curl -X POST https://api.tratto.email/v1/contacts \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email":"[email protected]",
    "firstName":"Alice",
    "lastName":"Smith",
    "status":"subscribed",
    "tags":["vip","newsletter"],
    "customFields":{"plan":"pro","signupDate":"2025-01-01"}
  }'

Response: creation returns the id only.

{
  "data": {
    "id": "cont_abc123"
  }
}

The field is customFields, not metadata. Unknown fields are dropped silently — send metadata and you get a 201, no error, and none of your data stored. Read the contact back once to confirm what actually landed.

List Contacts

Retrieve all contacts with optional filtering.

cURL

curl "https://api.tratto.email/v1/contacts?status=subscribed&limit=50" \
  -H "Authorization: Bearer tratto_live_..."

Query Parameters:

  • q: Email prefix search, case-insensitive. Combinable with status only — with audienceId or tag it returns 422
  • status: Filter by status (subscribed, unsubscribed, bounced, complained)
  • audienceId: Only contacts in that audience
  • tag: Only contacts carrying that tag
  • limit: Max results per page (default 50, max 100)
  • after: Cursor for pagination

Response:

{
  "data": [
    {
      "id": "cont_abc123",
      "email": "[email protected]",
      "firstName": "Alice",
      "lastName": "Smith",
      "status": "subscribed",
      "trackingOptOut": false,
      "tags": ["vip"],
      "customFields": { "plan": "pro" },
      "createdAt": "2025-06-30T12:00:00Z"
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "Y3Vyc29yOnZhbHVl",
    "total": 1284
  }
}

pagination.total is the count of contacts matching the filters, not just the page. trackingOptOut reports whether the recipient asked not to be tracked — see Privacy.

Update a Contact

Update a contact's details (status, tags, custom fields).

cURL

curl -X PATCH https://api.tratto.email/v1/contacts/cont_abc123 \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "status":"unsubscribed",
    "tags":["unsubscribed"],
    "customFields":{"unsubscribedAt":"2025-06-30T12:00:00Z"}
  }'

customFields replaces the whole object — it is not merged field by field.

Contact Status Values

StatusMeaning
subscribedActive contact, can receive emails
unsubscribedContact opted out (manually or via unsubscribe link)
bouncedEmail hard-bounced (invalid address)
complainedContact marked as spam

Auto-updates:

  • When an email bounces → status becomes bounced
  • When a contact clicks unsubscribe → status becomes unsubscribed
  • When an email is complained → status becomes complained

bounced and complained are one-way. A contact the system suppressed cannot be moved to any other status through the API — including unsubscribed. PATCH returns 403 FORBIDDEN, with a message explaining why: re-sending to a hard-bounced or complaining address damages the delivery reputation shared by every account on the sending pool.

Re-sending the contact's current status is accepted as a no-op, so a form that PATCHes every field on save keeps working.

Tags

Use tags to organize contacts into logical groups:

  • vip: High-value customers
  • newsletter: Newsletter subscribers
  • beta: Beta program members
  • churned: At-risk customers

Tagging use cases:

  • Segment campaigns by tag
  • Filter contacts for specific flows
  • Track cohorts

Custom Fields

customFields is a free-form JSON object for your own properties:

{
  "customFields": {
    "plan": "pro",
    "signupDate": "2025-01-01",
    "lastPurchase": "2025-06-15",
    "accountValue": 599.99
  }
}

Use custom fields to:

  • Store your own properties on a contact
  • Filter audiences by custom-field conditions
  • Personalize email content with variables

There is no metadata field. A metadata object in a create or update request is discarded without an error, so the request looks successful and the data is simply gone. The Node SDK calls it customFields, the Python SDK custom_fields.

Unsubscribe a Contact

There is no delete endpoint. A contact is deactivated by moving it to the unsubscribed status, which keeps the record so it stays suppressed. A deleted contact could be re-imported and mailed again by mistake.

cURL

curl -X PATCH https://api.tratto.email/v1/contacts/cont_abc123 \
  -H "Authorization: Bearer tratto_live_..." \
  -H "Content-Type: application/json" \
  -d '{"status":"unsubscribed"}'

Response:

{
  "data": {
    "id": "cont_abc123"
  }
}

Next Steps

  • Use contacts in campaigns? See Campaigns
  • Segment contacts into audiences? Go to Audiences
  • Use contact custom fields in templates? See Templates

Edit this page on GitHub

Last updated on