Skip to main content
Every OrigoID endpoint returns the same envelope. This consistency is intentional — your parser is one helper that works for every operation.

Shape

{
  "status": "OK | ERROR",
  "type": "TYPE_CODE",
  "message": "Human-readable summary",
  "data": { /* payload, or null on errors */ },
  "errors": [ /* optional, present only on INVALID_REQUEST */ ],
  "transactionId": "550e8400-e29b-41d4-a716-446655440000",
  "processedAt": "2026-03-15T12:35:00-06:00",
  "billable": true
}

Fields

FieldTypeDescription
statusenumOK when the request was processed; ERROR when it was rejected or failed.
typestringStable result code. Use this for your business logic, not message.
messagestringHuman summary in English. For display only.
dataobject | nullEndpoint-specific payload. null on errors.
errorsarrayPresent only on INVALID_REQUEST. Lists per-field issues.
transactionIduuidUnique request identifier. Reference it when contacting support.
processedAtISO 8601Timestamp with Mexico City offset (-06:00).
billablebooleanWhether this call counts against your plan.

ErrorDetail (entries in errors[])

When type is INVALID_REQUEST, errors[] lists per-field issues. Each entry is:
FieldTypeDescription
fieldstringDot-notation path to the offending input (e.g. curp, address.street). body when the issue applies to the request as a whole (malformed JSON, payload exceeds size limit, oneOf with all alternatives present).
codestringStable machine code. Branch on this, never on message. See the full list in Errors → Validation error codes.
messagestringHuman-readable explanation in English. Display only.

HTTP status codes

OrigoID uses HTTP status codes that match the nature of the response:
HTTPWhen
200Request was processed. The envelope tells you whether the business result was a success or a known business condition (e.g. CURP_NOT_FOUND).
401Authentication failed. Envelope type will be UNAUTHORIZED.
404Path does not exist.
405Wrong method for an existing path.
429Rate limit exceeded. Envelope type will be RATE_LIMIT_EXCEEDED.
In every case where you receive a JSON body, it follows the envelope shape above.

Parsing pattern (any language)

const response = await fetch(url, { ... });
const env = await response.json();

if (env.status === "OK" && env.type === "SUCCESS") {
  // Happy path — use env.data
  return env.data;
}

if (env.type === "INVALID_REQUEST") {
  // Your request did not pass validation
  // env.errors lists per-field issues
  throw new ValidationError(env.errors);
}

if (env.type === "UNAUTHORIZED") {
  // Auth failed — check your API key or IP allow-list
  throw new AuthError();
}

if (env.type === "RATE_LIMIT_EXCEEDED") {
  // Implement exponential backoff and retry
  throw new RetryableError();
}

// Otherwise it is a business result (e.g. CURP_NOT_FOUND)
// Treat according to your domain logic
return env;

Common type codes

typeMeaning
SUCCESSSuccessful operation. Use data.
INVALID_REQUESTYour request body did not pass validation. See errors.
UNAUTHORIZEDAuthentication failed.
RATE_LIMIT_EXCEEDEDYou exceeded your rate limit.
SERVICE_UNAVAILABLEService temporarily unavailable. Retry with backoff.
INTERNAL_ERRORAn unexpected error occurred. Reference transactionId when contacting support.
Each endpoint also defines specific codes (e.g. CURP_NOT_FOUND, CFDI_CANCELED, INE_NOT_VALID). See each operation in the API reference for the complete list.