Updating records via internal IDs can be a bottleneck. Zoho Books allows you to bypass the contact_id by using a Custom Field as a unique identifier. This endpoint also supports the Upsert (Update or Insert) logic, making it perfect for high-speed data synchronization.
At Kalki LLP, we recommend this approach for enterprise integrations to minimize the need for "ID Mapping" tables in your middleware.
Before using this endpoint, ensure that:
Custom Field Creation: You have created a custom field in Zoho Books (e.g., "External_ID").
Uniqueness: The field must be configured as "Unique" (Does not allow duplicate values) in the Zoho Books Preferences.
API Name: You have the correct API Name of that custom field (e.g., cf_external_id).
Unlike standard updates, the unique value update does not include the Contact ID in the URL path. Instead, identification happens via HTTP headers.
Endpoint: PUT /contacts?organization_id={organization_id}
| Header Name | Description |
| X-Unique-Identifier-Key | The API Name of your unique custom field. |
| X-Unique-Identifier-Value | The Unique Value you are searching for. |
| X-Upsert | (Optional) Set to true to create a contact if the unique value is not found. |
The body of the request follows the same structure as the standard Update Contact API. You can update names, addresses, or tax treatments.
{
"contact_name": "Kalki Tech Solutions Ltd",
"company_name": "Kalki Tech Solutions",
"contact_type": "customer",
"billing_address": {
"address": "45 Technology Drive",
"city": "Gurugram",
"state": "Haryana"
},
"payment_terms": 30,
"currency_id": "460000000000097"
}
If you are performing this inside a Zoho automation, you must pass the custom headers in the invokeUrl task.
headers = Map();
headers.put("X-Unique-Identifier-Key", "cf_external_system_id");
headers.put("X-Unique-Identifier-Value", "EXT-9988");
headers.put("X-Upsert", "true");
response = invokeurl
[
url :"https://www.zohoapis.in/books/v3/contacts?organization_id=123456"
type :PUT
parameters :updateDataMap.toString()
headers :headers
connection :"kalki_books_connection"
];
if(response.get("code") == 0) {
info "Contact Updated/Created via Unique ID!";
}
This specific endpoint has unique failure scenarios. Use this table for debugging:
| Error Code | Meaning | Fix for Kalki LLP Developers |
| 3000 | Duplicate Name | A contact with that contact_name already exists, conflicting with the one you are trying to upsert. |
| 6024 | Field Not Unique | The custom field provided in X-Unique-Identifier-Key is not marked as "Unique" in Zoho Books. |
| 57 | Unauthorized | Your OAuth token has expired or lacks the ZohoBooks.contacts.UPDATE scope. |
| 1001 | Record Not Found | X-Upsert was false, and no contact matched the unique value. |
For kalkillp.com clients, this method reduces API latency by eliminating the "Search for Contact" step. One single request handles the search, identification, and the update (or creation), keeping your systems perfectly in sync with zero overhead.