firstName and lastName, which are required on every request — and unknown fields are rejected with 400. The contact must belong to your merchant account — attempting to update a contact owned by another merchant returns 403 Forbidden.
Endpoint
Authentication
string
required
Bearer token using your API key. Format:
Bearer cs_live_your_keystring
required
A unique string you generate for each distinct update. Reuse the same key
when you retry and you get the original result back instead of applying the
update twice. Required — a request without it is rejected with
400 idempotency_key_required. Same semantics as
Create Contact.Path parameters
string
required
The unique identifier of the contact (UUID format).
Request body
string
required
Contact’s first name. Required on every request; non-blank.
string
required
Contact’s last name. Required on every request; non-blank.
string
Organization or company the contact belongs to.
object[]
The desired active email entries. Existing entries missing from this
array are soft-deleted (retained internally for history), and previously
deleted entries stay deleted. Omit the array entirely to leave emails
untouched.
object[]
The desired active phone entries. Same array semantics as
emails. Values
are normalized to E.164 (e.g. +34613628904); bare national numbers are
treated as US. Unparseable numbers return 400.object[]
The desired active address entries. Same array semantics as
emails.string
SUBSCRIBED or UNSUBSCRIBED. Changes propagate to the marketing platform
when your organization has marketing enabled (see meta.marketingSync in
the response).string
SUBSCRIBED or UNSUBSCRIBED. A contact who opted out of SMS by texting
STOP cannot be re-subscribed through the API (409 sms_carrier_locked) —
that requires the verified-START flow in the CharityStack dashboard.Response
On success returns the updated Contact object:object
required
The full updated contact record, in the same shape as
Get Contact.
object
Present only when a consent change was requested. Per-channel outcome of
the marketing sync:
synced, skipped_marketing_not_enabled,
skipped_no_marketing_link, or failed. A skipped/failed sync never
discards the consent change itself.Errors
A request rejected before the update is applied — a validation failure,
or
sms_carrier_locked — does not consume the idempotency key. Fix the body
and retry with the same key.Example — update name and add an email
Example — unsubscribe from email updates
In rare cases a slow update can return a gateway
504 while the update
still completes server-side. The request body is a declarative desired
state, so retrying the same PUT is safe and converges. Successful updates
emit the contact.updated webhook event.