Contacts & Companies
Create or update contact
Creates a new contact or updates an existing one using external IDs.
/api/v1/contactsBefore you start
Provide a name and an existing ID, UUID or external reference when updating.
Result
Store the returned contact identity and inspect the saved fields.
Charges and safe retries
Check the existing contact before retrying an uncertain create; do not assume a new request is harmless.
Authentication
Send your account API key in the X-Api-Key header. Keep it on your server; never embed it in browser code.
Request examples
Replace the example values with your own inputs. Examples do not run on this page. Production requests can change your account or incur charges.
cURL
curl -X POST "https://api.illyvoip.com/api/v1/contacts" \
-H "X-Api-Key: ${ILLYVOIP_API_KEY:?Set ILLYVOIP_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"external_source": "crm",
"external_id": "YOUR_EXTERNAL_CONTACT_ID",
"name": "Alice Example",
"phone": "+15551230003",
"email": "alice@example.test",
"company_id": "YOUR_COMPANY_ID",
"shared_user_ids": [
"YOUR_TEAM_MEMBER_ID"
],
"call_status": "callback",
"custom_fields": {
"crm_id": "C-1001",
"source": "trade show"
}
}'Node.js
const response = await fetch("https://api.illyvoip.com/api/v1/contacts", {
method: "POST",
headers: {
"X-Api-Key": process.env.ILLYVOIP_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"external_source": "crm",
"external_id": "YOUR_EXTERNAL_CONTACT_ID",
"name": "Alice Example",
"phone": "+15551230003",
"email": "alice@example.test",
"company_id": "YOUR_COMPANY_ID",
"shared_user_ids": [
"YOUR_TEAM_MEMBER_ID"
],
"call_status": "callback",
"custom_fields": {
"crm_id": "C-1001",
"source": "trade show"
}
})
});
const data = await response.json();
console.log(response.status, data);PHP
<?php
$ch = curl_init('https://api.illyvoip.com/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . getenv('ILLYVOIP_API_KEY'),
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => '{
"external_source": "crm",
"external_id": "YOUR_EXTERNAL_CONTACT_ID",
"name": "Alice Example",
"phone": "+15551230003",
"email": "alice@example.test",
"company_id": "YOUR_COMPANY_ID",
"shared_user_ids": [
"YOUR_TEAM_MEMBER_ID"
],
"call_status": "callback",
"custom_fields": {
"crm_id": "C-1001",
"source": "trade show"
}
}',
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $status . PHP_EOL;
echo $response;Python
import os
import json
import requests
response = requests.request(
"POST",
"https://api.illyvoip.com/api/v1/contacts",
headers={
"X-Api-Key": os.environ["ILLYVOIP_API_KEY"],
'Content-Type': 'application/json'
},
json=json.loads("{\n \"external_source\": \"crm\",\n \"external_id\": \"YOUR_EXTERNAL_CONTACT_ID\",\n \"name\": \"Alice Example\",\n \"phone\": \"+15551230003\",\n \"email\": \"alice@example.test\",\n \"company_id\": \"YOUR_COMPANY_ID\",\n \"shared_user_ids\": [\n \"YOUR_TEAM_MEMBER_ID\"\n ],\n \"call_status\": \"callback\",\n \"custom_fields\": {\n \"crm_id\": \"C-1001\",\n \"source\": \"trade show\"\n }\n}"),
)
print(response.status_code)
print(response.json())Node.js examples run on the server (Node.js 22.17+). Python examples require requests; PHP examples require cURL. Set the environment variables referenced in each example.
Request body
application/json
Body required.
external_sourcestringoptionalExternal system name, for example crm.
external_idstringoptionalExternal system ID.
namestringrequiredDisplay name.
phonestringoptionalPrimary phone number.
emailstringoptionalcompany_idintegeroptionalshared_user_idsarray<integer>optionalView nested fields
Array items
Type: integer
call_statusstringoptionalcustom_fieldsobjectoptionalView nested fields
crm_idstringrequiredsourcestringrequiredAdditional properties: not allowed.
idintegeroptionalContact ID returned by this API for direct updates.
uuidstringoptionalExisting contact UUID for direct updates.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"properties": {
"external_source": {
"type": "string",
"description": "External system name, for example `crm`."
},
"external_id": {
"type": "string",
"description": "External system ID."
},
"name": {
"type": "string",
"description": "Display name."
},
"phone": {
"type": "string",
"description": "Primary phone number."
},
"email": {
"type": "string"
},
"company_id": {
"type": "integer"
},
"shared_user_ids": {
"type": "array",
"items": {
"type": "integer"
}
},
"call_status": {
"type": "string"
},
"custom_fields": {
"type": "object",
"additionalProperties": false,
"properties": {
"crm_id": {
"type": "string"
},
"source": {
"type": "string"
}
},
"required": [
"crm_id",
"source"
]
},
"id": {
"type": "integer",
"description": "Contact ID returned by this API for direct updates."
},
"uuid": {
"type": "string",
"description": "Existing contact UUID for direct updates."
}
},
"required": [
"name"
]
}Example body
{
"external_source": "crm",
"external_id": "contact_123",
"name": "Alice Example",
"phone": "+15551230003",
"email": "alice@example.test",
"company_id": 88,
"shared_user_ids": [
42
],
"call_status": "callback",
"custom_fields": {
"crm_id": "C-1001",
"source": "trade show"
}
}Request behavior
Recommended for syncing from external CRMs because it is idempotent when external_source and external_id are stable. Supports company, sharing, status, and dynamic custom field data. Send the complete custom-field values for create/update, using existing field IDs or slugs. Configured required extra fields must be supplied. Invalid or unknown fields return HTTP 422 without saving the contact; valid values are not rewritten. Number fields use a dot decimal without grouping separators, dates use YYYY-MM-DD, and URLs require http:// or https://.
Response fields
status: Request outcome. Read the resource state separately; success does not always mean delivery or completion.contact: The saved or selected contact, including its public IDs and available fields.
HTTP responses
Expand a status to inspect its documented response format and examples. Example prices, IDs and timestamps are illustrative values, not quotes or account records.
200 Successful customer-facing response.
application/json
{
"status": "success",
"contact": {
"id": 123,
"uuid": "0c3a6f9e-3b2c-4c22-9c25-9b6f9c0b2a11",
"firstname": "Alice",
"lastname": "Example",
"phone": "+15551230003",
"email": "alice@example.test",
"address": "",
"zip": "",
"country": "US",
"call_status": "callback",
"company": {
"id": 88,
"name": "Example Corp"
},
"shared_users": [
{
"id": 42,
"name": "Alice Agent"
}
],
"custom_fields": [
{
"id": 5,
"slug": "crm_id",
"value": "C-1001"
}
],
"external": {
"source": "crm",
"id": "contact_123"
},
"created_at": "2026-03-01T09:00:00+00:00",
"updated_at": "2026-03-31T09:15:00+00:00",
"deleted_at": null
}
}statusstringrequiredcontactobjectrequiredView nested fields
idintegerrequireduuidstringrequiredOpaque contact UUID when assigned. Legacy contacts may return null; use the stable id selector.
firstnamestringrequiredlastnamestringrequiredphonestringrequiredemailstringrequiredaddressstringrequiredzipstringrequiredcountrystringrequiredcall_statusstringrequiredcompanyobjectrequiredView nested fields
idintegerrequirednamestringrequiredAdditional properties: not allowed.
shared_usersarray<object>requiredView nested fields
Array items
idintegerrequirednamestringrequiredAdditional properties: not allowed.
custom_fieldsarray<object>requiredView nested fields
Array items
idintegerrequiredslugstringrequiredvaluestringrequiredAdditional properties: not allowed.
externalobjectrequiredView nested fields
sourcestringrequiredidstringrequiredAdditional properties: not allowed.
created_atstringrequiredupdated_atstringrequireddeleted_atstringrequiredAdditional properties: not allowed.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"properties": {
"status": {
"type": "string",
"enum": [
"success"
]
},
"contact": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "integer"
},
"uuid": {
"type": "string",
"nullable": true,
"description": "Opaque contact UUID when assigned. Legacy contacts may return null; use the stable id selector."
},
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"phone": {
"type": "string"
},
"email": {
"type": "string"
},
"address": {
"type": "string"
},
"zip": {
"type": "string"
},
"country": {
"type": "string"
},
"call_status": {
"type": "string"
},
"company": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
]
},
"shared_users": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
]
}
},
"custom_fields": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "integer"
},
"slug": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"id",
"slug",
"value"
]
}
},
"external": {
"type": "object",
"additionalProperties": false,
"properties": {
"source": {
"type": "string"
},
"id": {
"type": "string"
}
},
"required": [
"source",
"id"
]
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"deleted_at": {
"type": "string",
"nullable": true
}
},
"required": [
"id",
"uuid",
"firstname",
"lastname",
"phone",
"email",
"address",
"zip",
"country",
"call_status",
"company",
"shared_users",
"custom_fields",
"external",
"created_at",
"updated_at",
"deleted_at"
]
}
},
"required": [
"status",
"contact"
]
}400 The request failed validation.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}401 The API key or browser token is missing or invalid.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}403 The account is not allowed to perform this operation.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}404 The requested owned resource was not found.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}409 The request conflicts with the current resource or operation state.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}429 The request rate limit was exceeded.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}500 An unexpected service error occurred.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}503 The service is temporarily unavailable.
application/json
statusstringrequiredmessagestringrequirederror_codestringoptionalPublic incident or validation code when the endpoint provides one.
fieldsobjectoptionalPublic validation details when supplied by the endpoint.
Additional properties: not allowed.
Full schema
{
"type": "object",
"additionalProperties": false,
"required": [
"status",
"message"
],
"properties": {
"status": {
"type": "string",
"enum": [
"error"
]
},
"message": {
"type": "string"
},
"error_code": {
"type": "string",
"nullable": true,
"description": "Public incident or validation code when the endpoint provides one."
},
"fields": {
"type": "object",
"additionalProperties": true,
"description": "Public validation details when supplied by the endpoint."
}
}
}Sandbox scenarios
Use https://sandbox-api.illyvoip.com with Sandbox credentials and the X-Illyvoip-Sandbox-Scenario header. Omit the header for the documented success default. This header belongs to sandbox requests.
success, not-found, rate-limited, forbidden, service-unavailable
Try this operation in Sandbox · Environment setup and limitations