Update Contact & Entity Fields
Surgically patch one or more fields on an existing contact or entity without resending the entire record.
Update specific fields on a CRM contact, entity, or both in a single call. Supports all standard fields, boolean flags, custom fields, and tags with intelligent merge behavior.
Requires a valid api_key and developer_secret in the JSON request body. Requests must originate from a whitelisted IP address.
Tip: This endpoint is built for targeted updates — toggling a flag, changing a status, appending tags, or updating custom fields. For creating new contacts or full upsert operations, use the Add or Update Contact API instead.
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. |
contact_id |
body | string |
No | The UUID of the contact to update. At least one of contact_id or entity_id is required. |
entity_id |
body | string |
No | The UUID of the entity to update. At least one of contact_id or entity_id is required. |
fields |
body | object |
Yes | An object containing one or more field names (camelCase) and their new values. Contact-specific fields apply to the contact; entity-specific fields apply to the entity. See the field reference tables below. |
Info: Help mode: Send {"help": true} as your request body to receive the complete field reference, sample payloads, and usage notes directly from the API — no authentication required.
Request Body
Content-Type: application/json
Schema
{
"fields": {
"fieldName": "value",
"customFields": {
"cf_tag": "value"
}
},
"org_id": "string (required)",
"api_key": "string (required)",
"entity_id": "string (conditional)",
"contact_id": "string (conditional)",
"developer_secret": "string (required)"
}
Example
{
"fields": {
"tags": "vip,priority",
"status": "Warm",
"autoEngage": 0,
"customFields": {
"cf_lead_source": "Conference 2025",
"cf_company_size": "Enterprise"
},
"primaryPhone": "+1 555-123-4567"
},
"org_id": "your-org-uuid",
"api_key": "your_zyntro_api_key",
"contact_id": "contact-uuid-to-update",
"developer_secret": "your_developer_secret"
}
Code Samples
curl -X POST https://app.zyntrohq.com/apis/v2/public/crm/updateFieldData \
-H "Content-Type: application/json" \
-d '{
"api_key": "your_zyntro_api_key",
"developer_secret": "your_developer_secret",
"org_id": "your-org-uuid",
"contact_id": "contact-uuid",
"fields": {
"autoEngage": 0,
"status": "Warm",
"tags": "vip,priority"
}
}'
curl -X POST https://app.zyntrohq.com/apis/v2/public/crm/updateFieldData \
-H "Content-Type: application/json" \
-d '{
"api_key": "your_zyntro_api_key",
"developer_secret": "your_developer_secret",
"org_id": "your-org-uuid",
"entity_id": "entity-uuid",
"fields": {
"name": "Acme Corporation",
"status": "Active",
"website": "https://acme.com",
"score": 85.5
}
}'
curl -X POST https://app.zyntrohq.com/apis/v2/public/crm/updateFieldData \
-H "Content-Type: application/json" \
-d '{
"api_key": "your_zyntro_api_key",
"developer_secret": "your_developer_secret",
"org_id": "your-org-uuid",
"contact_id": "contact-uuid",
"entity_id": "entity-uuid",
"fields": {
"status": "Client",
"autoEngage": 1,
"customFields": {
"cf_onboarding_complete": "true"
}
}
}'
$response = file_get_contents(
'https://app.zyntrohq.com/apis/v2/public/crm/updateFieldData',
false,
stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => json_encode([
'api_key' => 'your_zyntro_api_key',
'developer_secret' => 'your_developer_secret',
'org_id' => 'your-org-uuid',
'contact_id' => 'contact-uuid',
'fields' => [
'autoEngage' => 0,
'status' => 'Warm',
],
]),
],
])
);
$result = json_decode($response, true);
const response = await fetch(
'https://app.zyntrohq.com/apis/v2/public/crm/updateFieldData',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
api_key: 'your_zyntro_api_key',
developer_secret: 'your_developer_secret',
org_id: 'your-org-uuid',
contact_id: 'contact-uuid',
fields: {
autoEngage: 0,
status: 'Warm',
tags: 'vip,priority',
},
}),
}
);
const result = await response.json();
Response
{
"data": {
"message": "5 fields updated successfully",
"entity_id": null,
"contact_id": "contact-uuid",
"updated_fields": [
"autoEngage",
"status",
"tags",
"primaryPhone",
"customFields"
]
},
"status": "success"
}
warnings array contains the validation messages for the fields that failed.
{
"data": {
"message": "1 field updated successfully",
"warnings": [
"primaryEmail is not a valid email address"
],
"entity_id": null,
"contact_id": "contact-uuid",
"updated_fields": [
"status"
]
},
"status": "success"
}
{
"data": [
"primaryEmail is not a valid email address",
"stageId must be a number"
],
"status": "error"
}
{
"data": "Contact not found",
"status": "error"
}
{
"data": [
"Missing API key",
"Missing org_id"
],
"status": "error"
}
Contact Fields — Personal Information
| Field Name | Type | Description |
|---|---|---|
| salutation | string (max 10) | e.g. Mr, Mrs, Dr |
| name | string (max 100) | Full name. Auto-updated when firstName or lastName changes. |
| firstName | string (max 100) | First name. |
| lastName | string (max 100) | Last name. |
| roleLabel | string (max 100) | Role or title label. |
Contact Fields — Contact Information
| Field Name | Type | Description |
|---|---|---|
| primaryEmail | Primary email. Validated as email format. | |
| secondaryEmail | Secondary email address. | |
| primaryPhone | phone | Primary phone. Accepts digits, spaces, +, -, (, ). |
| secondaryPhone | phone | Secondary phone number. |
Contact Fields — Address
| Field Name | Type | Description |
|---|---|---|
| address | string (max 255) | Street address line 1. |
| address2 | string (max 255) | Street address line 2. |
| city | string (max 100) | City. |
| state | string (max 55) | State or province. |
| zip | string (max 15) | Postal code. |
| country | string (max 100) | Country name. |
| countryCode | string (max 2) | 2-letter country code (e.g. US, GB). |
| timezone | string (max 80) | Timezone identifier (e.g. America/New_York). |
Contact Fields — CRM
| Field Name | Type | Description |
|---|---|---|
| source | string (max 100) | Lead source attribution. |
| stageId | int | Pipeline stage ID. |
| owner | string (max 36) | Owner member UUID. |
| members | json | Array of member UUIDs with access to this contact. |
| status | string (max 50) | Contact status, e.g. Lead, Warm, Client. |
| tags | string | Comma-separated tags. Appended to existing tags with case-insensitive dedup. Never replaced. |
| entityId | string (max 36) | Link the contact to a different entity by UUID. |
Contact Fields — Flags
| Field Name | Type | Description |
|---|---|---|
| isTest | bool (0/1) | Mark as test contact. |
| dnc | bool (0/1) | Do Not Contact flag. |
| autoEngage | bool (0/1) | Enable or disable SI auto-engagement for this contact. |
| emailOptout | bool (0/1) | Email opt-out. |
| smsOptout | bool (0/1) | SMS opt-out. |
| emailVerified | bool (0/1) | Email verification status. |
| phoneVerified | bool (0/1) | Phone verification status. |
| scoringEnabled | bool (0/1) | Enable or disable lead scoring. |
| showOthers | bool (0/1) | Visible to other team members. |
| editOthers | bool (0/1) | Editable by other team members. |
Contact Fields — JSON & Custom
| Field Name | Type | Description |
|---|---|---|
| profileData | json | Profile data object. |
| verificationNotes | json | Verification notes object. |
| customFields | object | Custom fields keyed by cf_ smart tag. Merged with existing — only keys you pass are updated, all others preserved. |
Entity Fields
| Field Name | Type | Description |
|---|---|---|
| name | string (max 255) | Entity or company name. |
| label | string (max 100) | Entity label, e.g. Household, Company. |
| location | string | Location text. |
| website | url | Website URL. Validated. |
| logo | string | Logo URL. |
| status | string (max 100) | Entity status, e.g. Lead, Active, Churned. |
| score | float | Entity score as a decimal number. |
| tags | json | Tags as a JSON array. |
| profile | json | Profile data object. |
| socials | json | Social links object. |
| customFields | object | Custom fields keyed by cf_ smart tag. Merged with existing. |
Warning: Shared field names: When you pass both contact_id and entity_id, field names that exist in both maps — like status and customFields — are applied to both records. Contact-only fields like autoEngage only affect the contact; entity-only fields like score only affect the entity.
Important: How tags work: Tags on contacts are always appended, never replaced. The API performs case-insensitive deduplication, so adding VIP when the contact already has vip will not create a duplicate. To remove tags, use the CRM interface directly.
How custom fields work: The customFields object is merged with the contact's existing custom fields. Only the keys you include are updated — all other custom field values are preserved. Custom field tags must start with cf_ (auto-prefixed if omitted).
How empty values work: Passing null or an empty string for any field will not overwrite existing data. The field is simply skipped. This means you can safely pass a partial fields object without worrying about blanking out data you did not intend to change.
How names work: When you update firstName or lastName, the full name field is automatically recalculated from the current first and last name values.
Errors
| Code | Message | Resolution |
|---|---|---|
MISSING_API_KEY |
Missing API key The api_key field was not included in the request body.
|
Include your Zyntro API key. Find it under Me > API Keys in your account. |
INVALID_API_KEY |
Invalid API Key The provided API key does not match any active Zyntro account. |
Verify the API key is correct and that the associated account is active. |
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. |
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. |
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. |
MISSING_ORG_ID |
Missing org_id The org_id field was not included in the request body.
|
Include your organization UUID. |
MISSING_TARGET |
At least one of contact_id or entity_id is required Neither contact_id nor entity_id was provided.
|
Include at least one record identifier to specify what to update. |
MISSING_FIELDS |
fields object is required and must contain at least one field to update The fields key was missing, empty, or not an object.
|
Pass a fields object with at least one key-value pair. |
CONTACT_NOT_FOUND |
Contact not found No contact with the given UUID exists in the specified organization. |
Verify the contact_id and org_id are correct. |
ENTITY_NOT_FOUND |
Entity not found No entity with the given UUID exists in the specified organization. |
Verify the entity_id and org_id are correct. |
VALIDATION_ERROR |
Field-specific validation error A field value did not pass type validation (e.g. invalid email format, value exceeds max length, non-numeric value for an integer field). These are returned as an array in the data field or in a warnings array if other fields succeeded.
|
Check the field type requirements in the tables above and correct the value. |
Tip: Readonly fields are safe to include. If you pass id, orgId, or createdAt in the fields object, they are silently ignored — no error is returned. Similarly, unknown field names that are not in the field map are skipped without error. This makes it safe to forward a partial contact object from another system without stripping fields first.
new: Pass unlink_entity (bool, optional) Set true to detach the contact from its entity. Requires contact_id. Sets the contact→entity link to unlinked. Takes precedence over fields.entityId.