Error Handling
The API uses standard HTTP status codes and returns errors in a consistent JSON format.Error response format
Error codes
Handling errors
Check the HTTP status code first, then useerror.code for programmatic handling:
Validation errors
When request validation fails, themessage field describes which fields are invalid:
Conflict errors
Delete operations on configuration resources (stages, tiers, categories, tags, custom fields) return409 Conflict if the resource is currently in use:
Custom field validation
Creating or updating a lead, deal, or partner with custom field values — whether inline on the entity itself, or viaPOST/PATCH/DELETE /v1/custom-field-values and the per-entity custom-field endpoints (PUT/
PATCH/DELETE /v1/leads/:uuid/custom-fields, .../deals/:uuid/custom-fields,
.../partners/:uuid/custom-fields) — is validated server-side against each
field’s required flag, its partner_type scope, and any active custom
field rules (visibility, locking, auto-population). A violation returns a
400 validation_error with a details array — one entry per rejected
field:
reason is one of:
Deleting a custom field value
DELETE is treated as submitting an empty value for the field, so the same
checks apply:
- Deleting a visible, required value returns
required_cannot_blank— clearing it would leave the entity without a value a required field demands. - Deleting a value that’s currently locked by an active custom field rule
returns
locked_by_rule— the value can’t be changed (including to empty) while the rule that sets it is active. - Deleting a hidden field’s value, or a value with no active constraints,
succeeds normally (
204).
400):
Partnership locks
On the partner API, a vendor can disable editing of lead status or deal stage for a partnership. While a lock is on, a request that would change the locked value returns403 forbidden and nothing in the request is saved. The lock
that applies is the calling partner’s own partnership. The details array
holds one entry with reason locked_by_partnership, and field is one of:
Re-sending the current value, or omitting
stage_uuid on create (the deal then
starts in the default stage), still succeeds. For rejected_reason and
accepted_reason, the current value is the one the lead response shows you:
it is null when the vendor hides the reason from partners or the lead is not
in that reason’s status, so echoing null back is not a change.
Example response (403):