Skip to main content
The HTTP status sets the class of an error, and a string code carries the exact cause. That code arrives in the X-Error-Reason header and is repeated in the response body. The body is a standard google.rpc.Status, so its code field is a number (the gRPC code), not a string.
Branch on the X-Error-Reason header for programmatic handling. If headers are not available to you, the same code sits in details[].metadata.code, and details[].reason holds it with dots replaced by underscores. The message text is for humans and may change, so never match on it.
Do not branch on the numeric code in the body: that is the gRPC code, not the Doodocs error code. The 7 above means PermissionDenied, not “insufficient scope”.
For “resource not found” errors, details carries a second entry, google.rpc.ResourceInfo, with resourceType and resourceName.

Status codes

Error codes

Key and access

Lists and parameters

Employees

Documents

Files

Webhooks

Ingest

Why 404 instead of 403

So the API cannot be used as an oracle, “does not exist”, “no access”, and “draft/deleted” all return the same 404 for single resources — EMPLOYEE_NOT_FOUND for an employee, DOCUMENT_NOT_FOUND for a document. The response code cannot tell you whether a resource hidden from you exists.

Preview limitations

  • A rate-limit error (429) arrives with no X-Error-Reason and an empty details. Identify it by the status, and take the pause from the Retry-After header.
  • A typo in a query parameter name is handled by the transcoder before it reaches the API and returns 500 with an unknown field in field path message. An unknown parameter value still returns a proper 400.