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_keyPath 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
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.