Add or Update Contact
Create new contacts, update existing ones, or upsert with automatic duplicate detection
Creates a new contact, updates an existing contact, or performs an upsert (create if not found, update if found). Supports full contact and entity data, custom fields, and respects your CRM mode (B2B/B2C) settings.
Requires a valid `api_key` and `developer_secret` in the JSON request body. Requests must originate from a whitelisted IP address.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
api_key |
body | string |
Yes | Your Zyntro API key |
developer_secret |
body | string |
Yes | Your developer secret (zdk_XXX). Issued during developer onboarding. |
org_id |
body | string |
Yes | Your organization UUID |
member_id |
body | string |
Yes | The member UUID performing the action. Must be a valid member in the organization. |
mode |
body | string |
No | Operation mode: `insert` (create only, fail if exists), `update` (update only, fail if not found), or `upsert` (create or update). Default: `upsert` |
lookup_by |
body | string |
No | How to find existing contacts in `update` or `upsert` mode: `email`, `phone`, or `contact_id`. Default: `email` |
skip_entity |
body | boolean |
No | Set to `true` to skip entity creation even in B2B mode. Default: `false` |
contact |
body | object |
Yes | Contact data object. See Contact Fields below. |
entity |
body | object |
No | Entity (company) data object. See Entity Fields below. In B2B mode, an entity name is auto-generated from the contact name if not provided. |
debug |
body | boolean |
No | Set to `true` to include debug information in the response. |
Info:
All contact and entity field names use **camelCase** in the request body (e.g., `firstName`, `primaryEmail`, `roleLabel`). The API maps these to the internal database column names automatically.
Request Body
Content-Type: application/json
Example
json
{
"mode": "upsert",
"entity": {
"name": "Acme Corp",
"label": "Company",
"status": "Active",
"website": "https://acme.com"
},
"org_id": "YOUR_ORG_ID",
"api_key": "YOUR_API_KEY",
"contact": {
"tags": [
"prospect",
"enterprise"
],
"source": "API Import",
"status": "Active",
"lastName": "Smith",
"firstName": "Jane",
"roleLabel": "Decision Maker",
"customFields": {
"industry": "Technology",
"company_size": "50-200"
},
"primaryEmail": "[email protected]",
"primaryPhone": "+1-555-0123"
},
"lookup_by": "email",
"member_id": "YOUR_MEMBER_ID",
"developer_secret": "YOUR_DEVELOPER_SECRET"
}
Code Samples
bash
curl -X POST https://app.zyntrohq.com/apis/v2/public/crm/addContactsFull \
-H "Content-Type: application/json" \
-d '{
"api_key": "YOUR_API_KEY",
"developer_secret": "YOUR_DEVELOPER_SECRET",
"org_id": "YOUR_ORG_ID",
"member_id": "YOUR_MEMBER_ID",
"mode": "upsert",
"contact": {
"firstName": "Jane",
"lastName": "Smith",
"primaryEmail": "[email protected]",
"source": "API Import",
"status": "Active"
},
"entity": {
"name": "Acme Corp",
"status": "Active"
}
}'
Response
200
Contact created or updated successfully
json
{
"data": {
"action": "created",
"message": "Contact created successfully",
"entity_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"contact_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"entity_action": "created"
},
"status": "success"
}
200
Validation errors
json
{
"data": [
"Missing required contact fields: firstName, primaryEmail"
],
"status": "error"
}
Errors
| Code | Message | Resolution |
|---|---|---|
MISSING_API_KEY |
API key is required The `api_key` field is missing. |
Include your API key. |
INVALID_API_KEY |
Invalid API key No active user matches the key. |
Verify your API key in **Me > API & Webhooks**. |
IP_NOT_WHITELISTED |
IP address not whitelisted The request originated from an IP not in the key's allowed list. |
Contact your client to add your IP to the developer key whitelist. |
INVALID_DEVELOPER_SECRET |
Invalid developer_secret The developer secret does not match any active key. |
Verify your developer secret. If lost, have your client revoke and reissue the key. |
MISSING_DEVELOPER_SECRET |
Missing developer_secret The `developer_secret` field is missing or empty. |
Include your developer secret in the request body. This is issued during developer onboarding. |
MISSING_CONTACT |
contact data is required The `contact` object is missing from the request body. |
Include a `contact` object with at least `firstName` and `primaryEmail`. |
MEMBER_NOT_FOUND |
Member not found in this organization The `member_id` does not belong to any member in the specified organization. |
Use a valid member ID from your organization. |
VALIDATION_ERROR |
Contact validation errors: ... One or more contact fields failed type or format validation. |
Check the error message for specific field issues (invalid email, phone format, exceeds max length, etc.). |
CUSTOM_FIELD_ERROR |
Contact custom field errors: ... A custom field key does not exist or its value is not in the allowed set. |
Verify custom field names and allowed values in your CRM settings. |
NOT_FOUND_UPDATE |
Contact not found for update In `update` mode, no existing contact matches the lookup criteria. |
Use `upsert` mode instead, or verify the contact exists. |
Tip:
In `upsert` mode with `lookup_by: "email"`, the API searches for an existing contact by `primaryEmail`. If found, it updates the record and merges custom fields (new keys are added, existing keys are overwritten). If not found, it creates a new contact.
Warning:
Custom field keys in `customFields` must exactly match the field tags defined in your CRM settings (**Settings > CRM > Custom Fields**). Unrecognized keys are rejected. For fields with predefined options, the value must be one of the allowed choices.