Upsert a contact by external id
Idempotent upsert of a contact keyed by a stable, customer-supplied
external id — the canonical "sync my system's truth into SendOps" call.
The external id is a permanent dedup key (unlike the 24-hour
Idempotency-Key window): re-running the same request always converges
to the same contact.
Resolution order: (1) if a contact already carries this external_id it
is updated in place — including changing its email; (2) otherwise, if
the supplied email already exists it is adopted (the external id is
stamped onto it), unless that email already belongs to a different
external id, which returns 409 conflict; (3) otherwise a new contact is
created (email is required).
attributes and topic_preferences are the desired set. unsubscribe_all
is omitted-means-untouched (a null/absent value never changes the
current opt-out). lists, when present, replaces static-List membership
exactly (an empty array clears all); when absent, membership is unchanged.
Returns 201 on creation and 200 on update.
Also supports the Idempotency-Key header for transport-level retry
de-duplication, independent of the permanent external-id key.
Path parameters
external_id string required The caller's stable identifier for this contact. Opaque, unique per org.
Request body
Content type: application/json
{
"email": "user@example.com",
"attributes": {},
"unsubscribe_all": true,
"topic_preferences": [
{
"topic_name": "string",
"subscription_status": "OPT_IN"
}
],
"lists": [
"00000000-0000-0000-0000-000000000000"
]
} Responses
code is conflict.
application/problem+json code is internal_error. The
request_id field can be quoted to SendOps support to investigate.
application/problem+json