Update a contact
curl --request PATCH \ --url https://api.sipstack.com/api/v2/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0 \ --header 'Content-Type: application/json' \ --header 'x-api-key: <x-api-key>' \ --data '{ "firstName": "Jordan", "lastName": "Lee", "email": "jordan.lee@example.com", "business": "Lee Consulting", "tags": [ "vip", "newsletter" ], "customFields": { "plan": "enterprise" } }'import requests
url = "https://api.sipstack.com/api/v2/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
payload = { "firstName": "Jordan", "lastName": "Lee", "email": "jordan.lee@example.com", "business": "Lee Consulting", "tags": ["vip", "newsletter"], "customFields": { "plan": "enterprise" }}headers = { "x-api-key": "<x-api-key>", "Content-Type": "application/json"}
response = requests.patch(url, json=payload, headers=headers)
print(response.json())const url = 'https://api.sipstack.com/api/v2/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0';const options = { method: 'PATCH', headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'}, body: '{"firstName":"Jordan","lastName":"Lee","email":"jordan.lee@example.com","business":"Lee Consulting","tags":["vip","newsletter"],"customFields":{"plan":"enterprise"}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}import axios from 'axios';
const options = { method: 'PATCH', url: 'https://api.sipstack.com/api/v2/contacts/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0', headers: {'x-api-key': '<x-api-key>', 'Content-Type': 'application/json'}, data: { firstName: 'Jordan', lastName: 'Lee', email: 'jordan.lee@example.com', business: 'Lee Consulting', tags: ['vip', 'newsletter'], customFields: {plan: 'enterprise'} }};
try { const { data } = await axios.request(options); console.log(data);} catch (error) { console.error(error);}Updates the mutable fields of a contact (contacts:write). phoneNumber
is not mutable here — it is the dedupe key. 404 when absent / cross-org
/ soft-deleted; 400 when no updatable field is provided.
Consent (consentStatus and the express consentMethod,
consentMethodNote, consentDate, and the implied
impliedConsentBasis, impliedConsentBasisDate, consentEvidence)
is written only when it changes.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Request Body required
Section titled “Request Body required ”Mutable contact fields (all optional; at least one must be present).
phoneNumber is not mutable here — it is the dedupe key; use
create/delete to change it.
object
object
Consent to text. Consent is written only when it changes:
re-sending the contact’s current status (for example, a sync that
sends every field) leaves consent_date untouched, so the 24-month
window for implied consent is not restarted. For a contact that is
already express, sending consentMethod, consentMethodNote or
consentDate records a new basis only if one of them differs; a
field you leave out keeps its recorded value. Each change is added
to the contact’s consent history with the API key that made it.
How express consent was obtained. Used only with consentStatus: express
(ignored otherwise). Optional: if you set express without it, the
consent history records the method as api (declared by caller).
Send it whenever you know it — a stated method is stronger evidence.
Free-text detail on how consent was obtained (longer text is cut at
500 characters). Required when consentMethod is other.
When express consent was obtained: YYYY-MM-DD or a full ISO 8601
timestamp. Cannot be in the future (a YYYY-MM-DD that is today in
any timezone is accepted). Defaults to now. Used only with
consentStatus: express.
The CASL basis for implied consent (Canada’s Anti-Spam
Legislation). Used only with implied consent: sending it with
consentStatus: express or none (or on a contact that is not
implied) is a 400. Campaigns and drips count implied consent for
as long as its basis lasts:
ebr_purchase— existing business relationship from a purchase or other transaction: 2 years fromimpliedConsentBasisDate(the most recent purchase).ebr_contract— existing business relationship from a written contract: 2 years afterimpliedConsentBasisDate, the date the contract ends (may be in the future).ebr_inquiry— an inquiry or application: 6 months fromimpliedConsentBasisDate.nbr— non-business relationship: 2 years fromimpliedConsentBasisDate. Only for organizations SIPSTACK has marked as a charity, political organization, club or association; anyone else gets a400.conspicuous_publication— the person published their number conspicuously, without a statement that they do not want messages: no fixed expiry, and messages must relate to their role or business.consentEvidenceis required.disclosed_address— the person gave you their number without saying they do not want messages: no fixed expiry, same condition.consentEvidenceis required.
An ebr_* or nbr basis without impliedConsentBasisDate is
stored but treated as undeclared. A contact with no declared basis
has undeclared implied consent, which lasts 6 months. Send null
or "" to clear the basis. US numbers still need express consent
for marketing whatever the basis.
The date the basis runs from, YYYY-MM-DD or a full ISO 8601
timestamp: the most recent purchase (ebr_purchase), the contract
end date (ebr_contract, which may be in the future), the
inquiry (ebr_inquiry), the relationship (nbr), or when you
observed the address (conspicuous_publication,
disclosed_address). Cannot be in the future except for
ebr_contract. Requires impliedConsentBasis.
Free-text evidence for the consent, such as an invoice number, a
form link or a reference (longer text is cut at 1,000 characters).
Required for conspicuous_publication and disclosed_address.
Send null or "" to clear it.
Examples
Update contact details
{ "firstName": "Jordan", "lastName": "Lee", "email": "jordan.lee@example.com", "business": "Lee Consulting", "tags": [ "vip", "newsletter" ], "customFields": { "plan": "enterprise" }}Record express consent
{ "consentStatus": "express", "consentMethod": "paper_signature", "consentMethodNote": "Signed the sign-up sheet at the front desk", "consentDate": "2026-09-01"}Responses
Section titled “ Responses ”The updated contact.
object
A contact record. POST /api/v2/contacts returns the compact subset
(id, uuid, phone_number, names, email, tags, consent_status,
consent_date, implied_consent_basis, implied_consent_basis_date,
consent_evidence, created_at);
the list/get/update endpoints return the full record below.
object
object
The declared CASL basis for implied consent; null = undeclared. See impliedConsentBasis on create.
The date the basis runs from (for ebr_contract, the contract end date).
Evidence recorded for the consent.
How the contact was created (e.g. api).
Example
{ "data": { "phone_number": "+14165550100", "consent_status": "implied", "implied_consent_basis": "ebr_purchase" }}A field was the wrong type, no updatable fields were provided, or
invalid consent fields: an unknown consentStatus or
consentMethod, consentMethod: other without consentMethodNote,
an unreadable or future consentDate, a consent method/date
without consentStatus, or invalid consent basis fields (the same
rules as on create; evidence and nbr are checked against what the
contact will have after the update).
Inline error shape used by the messaging API and management endpoints.
object
Example
{ "success": false, "error": "Recipient phone number (to) is required"}Missing or invalid API key.
Inline error shape used by the messaging API and management endpoints.
object
Example
{ "success": false, "error": "Recipient phone number (to) is required"}API access is not enabled on your plan.
Inline error shape used by the messaging API and management endpoints.
object
Example
{ "success": false, "error": "Recipient phone number (to) is required"}Contact not found in your organization.
Inline error shape used by the messaging API and management endpoints.
object
Example
{ "success": false, "error": "Recipient phone number (to) is required"}