Skip to content

Create a contact

POST
/api/v2/contacts
curl --request POST \
--url https://api.sipstack.com/api/v2/contacts \
--header 'Content-Type: application/json' \
--header 'x-api-key: <x-api-key>' \
--data '{ "phoneNumber": "+14165550100", "firstName": "Jordan", "lastName": "Lee", "email": "jordan.lee@example.com", "tags": [ "newsletter" ], "consentStatus": "express", "consentMethod": "web_form", "consentDate": "2026-09-01" }'

Creates a contact in your organization. Create-only — this endpoint never updates an existing contact. The phone number is normalized to E.164 before the uniqueness check; a live contact with the same number returns 409. Requires the contacts:write scope.

Media type application/json
object
phoneNumber
required

Contact phone number — normalized to E.164 (a leading 1 is added to 10-digit numbers).

string
firstName
string
nullable
lastName
string
nullable
email
string format: email
nullable
tags
Array<string>
customFields
object
key
additional properties
any
consentStatus

Consent to text. Defaults to implied. Marketing campaigns send to US numbers only with express consent. Every express contact gets a consent history entry recording the method, the date and the API key that set it.

string
Allowed values: implied express none
consentMethod

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.

string
Allowed values: web_form paper_signature verbal_recorded other
consentMethodNote

Free-text detail on how consent was obtained (longer text is cut at 500 characters). Required when consentMethod is other.

string
<= 500 characters
consentDate

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.

string
impliedConsentBasis

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 from impliedConsentBasisDate (the most recent purchase).
  • ebr_contract — existing business relationship from a written contract: 2 years after impliedConsentBasisDate, the date the contract ends (may be in the future).
  • ebr_inquiry — an inquiry or application: 6 months from impliedConsentBasisDate.
  • nbr — non-business relationship: 2 years from impliedConsentBasisDate. Only for organizations SIPSTACK has marked as a charity, political organization, club or association; anyone else gets a 400.
  • 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. consentEvidence is required.
  • disclosed_address — the person gave you their number without saying they do not want messages: no fixed expiry, same condition. consentEvidence is 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 and never more than 24 months after its consent date (or creation date, if it has none). Send null or "" to clear the basis. US numbers still need express consent for marketing whatever the basis.

string
nullable
Allowed values: ebr_purchase ebr_contract ebr_inquiry nbr conspicuous_publication disclosed_address
impliedConsentBasisDate

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.

string
nullable
consentEvidence

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.

string
nullable <= 1000 characters
Examples

A contact with express consent

{
"phoneNumber": "+14165550100",
"firstName": "Jordan",
"lastName": "Lee",
"email": "jordan.lee@example.com",
"tags": [
"newsletter"
],
"consentStatus": "express",
"consentMethod": "web_form",
"consentDate": "2026-09-01"
}

Contact created. data is the compact Contact subset (id, uuid, phone_number, names, email, tags, consent_status, consent_date, implied_consent_basis, implied_consent_basis_date, consent_evidence, created_at) — not the full record; read it back via GET /api/v2/contacts/{id} for the complete contact.

Media type application/json
object
success
boolean
data

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
id
string format: uuid
uuid
string format: uuid
phone_number
string
first_name
string
nullable
last_name
string
nullable
email
string
nullable
business
string
nullable
tags
Array<string>
custom_fields
object
key
additional properties
any
consent_status
string
Allowed values: implied express none
consent_date
string format: date-time
nullable
implied_consent_basis

The declared CASL basis for implied consent; null = undeclared. See impliedConsentBasis on create.

string
nullable
Allowed values: ebr_purchase ebr_contract ebr_inquiry nbr conspicuous_publication disclosed_address
implied_consent_basis_date

The date the basis runs from (for ebr_contract, the contract end date).

string format: date-time
nullable
consent_evidence

Evidence recorded for the consent.

string
nullable
is_opted_out
boolean
is_blocked
boolean
is_archived
boolean
is_starred
boolean
last_contacted_at
string format: date-time
nullable
total_messages_sent
integer
total_messages_received
integer
source

How the contact was created (e.g. api).

string
nullable
created_at
string format: date-time
updated_at
string format: date-time
Example
{
"data": {
"phone_number": "+14165550100",
"consent_status": "implied",
"implied_consent_basis": "ebr_purchase"
}
}

Phone number missing or invalid, or invalid consent fields: an unknown consentStatus or consentMethod, consentMethod: other without consentMethodNote, an unreadable or future consentDate, an unknown impliedConsentBasis, an impliedConsentBasis without implied consent, an impliedConsentBasisDate without a basis or unreadable or in the future (except ebr_contract), a missing consentEvidence for conspicuous_publication or disclosed_address, or nbr for an organization that is not eligible for it.

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}

Missing or invalid API key.

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}

API access is not enabled on your plan.

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}

A contact with this phone number already exists (including a soft-deleted one holding the key).

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}

Internal error.

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}

MESSAGING_SETUP_UNAVAILABLE — your organization’s messaging account is set up automatically on its first contact write, and that setup failed. Nothing was written; retry shortly.

Media type application/json

Inline error shape used by the messaging API and management endpoints.

object
success
boolean
error
string
Example
{
"success": false,
"error": "Recipient phone number (to) is required"
}