Create or update a contact

Creates a new contact or updates an existing one. Contacts are matched by email address only — the email is the contact's unique identifier. external_id is stored but never used for matching, so sending an existing external_id with a new email address creates a second contact.

To change a contact's email address: upsert a contact with the new email and the full profile, re-create its list subscriptions (preserving unsubscribed/bounced/complained statuses — do not reset opt-outs), then delete the contact with the old email using contacts.delete. Message history and segment memberships are keyed to the email address and are not transferred.

Returns information about whether the contact was created or updated.

post/api/contacts.upsert

Request body

workspace_idstring required

The ID of the workspace

Example request

{
  "workspace_id": "ws_1234567890",
  "contact": {
    "email": "user@example.com",
    "external_id": "user_12345",
    "timezone": "America/New_York",
    "language": "en-US",
    "first_name": "John",
    "last_name": "Doe",
    "full_name": "John Doe",
    "phone": "+15551234567",
    "address_line_1": "123 Main St",
    "address_line_2": "Apt 4B",
    "country": "US",
    "postcode": "10001",
    "state": "NY",
    "job_title": "Software Engineer",
    "custom_string_1": "Premium tier",
    "custom_number_1": 42,
    "custom_datetime_1": "2023-06-01T09:00:00Z",
    "custom_json_1": {
      "preferences": {
        "theme": "dark",
        "notifications": true
      }
    }
  }
}

Response

Contact upserted successfully

emailstring email

Email address of the contact

action'create' | 'update' | 'error'

The action that was performed: 'create' for new contacts, 'update' for existing contacts, 'error' if validation failed

errorstring nullable

Error message if the operation failed

Example response

{
  "email": "user@example.com",
  "action": "create"
}

Changes

Changed in 6 of the 25 revisions of this API.1510

    • removed the request property contact/contact_lists

      request-property-removed

    • removed the request property contact/contact_segments

      request-property-removed

    • removed the request property contact/created_at

      request-property-removed

    • removed the request property contact/updated_at

      request-property-removed

    • added the new error enum value to the action response property for the response status 200

      response-property-enum-value-added

    • added the new optional request property contact/contact_segments

      new-optional-request-property

    • added the new optional request property contact/full_name

      new-optional-request-property

    • added the optional property error to the response with the 200 status

      response-optional-property-added

  • f018ea66821744See the full diff
    • removed the optional property contact from the response with the 200 status

      response-optional-property-removed

    • removed the optional property error from the response with the 200 status

      response-optional-property-removed

    • added the new create enum value to the action response property for the response status 200

      response-property-enum-value-added

    • added the new update enum value to the action response property for the response status 200

      response-property-enum-value-added

    • added the optional property email to the response with the 200 status

      response-optional-property-added

    • removed the created enum value from the action response property for the response status 200

      response-property-enum-value-removed

    • removed the unchanged enum value from the action response property for the response status 200

      response-property-enum-value-removed

    • removed the updated enum value from the action response property for the response status 200

      response-property-enum-value-removed

    • removed the request property contact/last_order_at

      request-property-removed

    • removed the request property contact/lifetime_value

      request-property-removed

    • removed the request property contact/orders_count

      request-property-removed

    • removed the optional property contact/last_order_at from the response with the 200 status

      response-optional-property-removed

    • removed the optional property contact/lifetime_value from the response with the 200 status

      response-optional-property-removed

    • removed the optional property contact/orders_count from the response with the 200 status

      response-optional-property-removed

    • added the new optional request property contact/contact_lists

      new-optional-request-property

    • added the optional property contact/contact_lists to the response with the 200 status

      response-optional-property-added

    • endpoint added

      endpoint-added