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. 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"
}