Create or update a contact
const url = 'https://api.sendtruss.com/v1/workspaces/example/contacts/example';const options = { method: 'PUT', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"email":"hello@example.com","attributes":{"additionalProperty":"example"},"tags":["example"],"locale":"example","marketing":{"state":"subscribed","at":"example"},"pixel_consent_at":"2026-04-15T12:00:00Z"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.sendtruss.com/v1/workspaces/example/contacts/example \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "email": "hello@example.com", "attributes": { "additionalProperty": "example" }, "tags": [ "example" ], "locale": "example", "marketing": { "state": "subscribed", "at": "example" }, "pixel_consent_at": "2026-04-15T12:00:00Z" }'Address the contact as ref: plus your own id for the person: it is
created if the reference is new (201) and updated if not (200). By our id
it only updates, and an unknown id is a 404. A field you leave out is left
as it is, so a sync can send only what changed.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The workspace: our id, or ref: plus your reference for it, such as ref:cust_4821. A reference is letters, digits, ., _ and -, up to 128 characters, and needs no URL encoding.
The contact: our id, or ref: plus your reference for the person, such as ref:guest_998. A reference is letters, digits, ., _ and -, up to 128 characters, and needs no URL encoding.
Request Body
Section titled “Request Body”object
The contact’s email address, unique in the workspace. Required when the contact is created.
Values by attribute definition key. Only the keys you send change, null clears one, and a key with no definition is refused. A required attribute must be set when the contact is created and can’t be cleared.
object
The contact’s whole set of tags by name, at most 50. It replaces the tags the contact had; leave it out to keep them.
A language tag such as en or pt-BR, which picks the translation a template sends.
Marketing consent: subscribed or unsubscribed, and at, the time the person gave or withdrew it, no later than now. A contact you never send it for gets no marketing email. A subscribed older than the contact’s latest opt-out is refused.
object
When the person agreed to open tracking, or null to withdraw it.
Responses
Section titled “Responses”Examplegenerated
exampleHeaders
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
The API key is missing, malformed, revoked or expired.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
Example
{ "code": "unauthenticated"}Headers
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
Nothing is at this path for your key. Another platform’s or another workspace’s resource answers the same as one that doesn’t exist.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
Example
{ "code": "not_found"}Headers
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
Refused because of the resource’s current state. The code says why.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
The contact in this workspace that already has the address: ref: plus its reference, or its id when it has none.
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
Example
{ "code": "email_taken"}Headers
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
The request is invalid. The code says why, and errors names each field at fault.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
Each field that failed validation, by its path in the request, with its messages.
object
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
Example
{ "code": "validation_failed"}Headers
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
Too many requests. Wait for the seconds in Retry-After.
object
What went wrong, for a person to read. It may change, so branch on code.
What went wrong, for your code to branch on. A new code is not a breaking change.
The entry on our errors page that explains this code.
This request’s id, the same as its Request-Id header. Quote it when you ask us about the request.
Example
{ "code": "rate_limited"}Headers
Section titled “Headers”This request’s id. Quote it when you ask us about the request.
Seconds to wait before trying again.