Skip to main content

Errors and Validation

Public API v2 returns a consistent error envelope for requests under /api/v2.
{
  "status_code": 400,
  "error_type": "validation_error",
  "code": "field_value_invalid",
  "message": "Invalid request",
  "details": {
    "field": "primary_email"
  }
}

Error fields

FieldMeaning
status_codeHTTP status code mirrored in the response body
error_typeBroad category, such as validation_error, not_found, or forbidden
codeMachine-readable error code
messageHuman-readable summary
detailsOptional structured data that varies by error code

Common error types

HTTP statuserror_typeCommon causes
400validation_errorUnknown field, invalid filter, invalid value, unsupported sub-resource, invalid cursor, or out-of-range limit
401unauthorizedMissing, invalid, or expired API key
403forbiddenAPI key does not have the required permission
404not_foundRecord, record type, or relationship does not exist
405method_not_allowedThe resource is read-only or the endpoint does not support that method
409conflictA match request found more than one possible record
413payload_too_largeRequest body exceeds the allowed size
415unsupported_media_typeRequest body is not JSON
422unprocessableRequest is structurally valid but cannot be applied, such as a blocked stage transition
429rate_limitedToo many requests
500internal_errorServer-side failure

Recovery guide

codeWhat to check before retrying
unknown_fieldVerify the field API name with GET /api/v2/_schema/{record_type}.
field_not_creatableRemove read-only, computed, or system-managed fields from create requests.
field_not_updatableRemove read-only, computed, or system-managed fields from patch requests.
field_required_missingInclude required create fields. Opportunity create requests require display_name, stage, and account_id; contact create requests require stage.
field_value_invalidCheck the field’s value type and write shape.
invalid_filter_fieldConfirm the field is filterable for this record type.
invalid_filter_operatorUse an operator compatible with the field value type.
invalid_filter_valueCoerce the filter value into the expected type before retrying.
invalid_cursorRestart pagination from the first page with the same filter and sort.
target_record_not_foundRe-query or create the target record before writing a reference or relationship.
ambiguous_matchMatch by ID or choose a more specific unique field.
unknown_relationshipVerify the relationship API name with schema introspection.
stage_entrance_criteria_not_metFix the missing stage prerequisites before retrying.
rate_limit_exceededRetry with backoff and reduce request concurrency.

Validation examples

Unknown fields are rejected:
{
  "status_code": 400,
  "error_type": "validation_error",
  "code": "unknown_field",
  "message": "Unknown field",
  "details": {
    "field": "not_a_real_field"
  }
}
Read-only or system-managed fields are rejected on writes:
{
  "status_code": 400,
  "error_type": "validation_error",
  "code": "field_not_updatable",
  "message": "Field is not updatable",
  "details": {
    "field": "created_by_user_id"
  }
}

Query limits

_query endpoints default to limit: 50. The accepted range is 1 through 500. If a query response includes next_cursor, pass it back in the next request:
{
  "cursor": "<next_cursor>",
  "limit": 50
}
Treat cursors as opaque strings. Do not parse or modify them.