The error envelope
Every error response has the same JSON shape:errorCode— a stable enum value. Branch your code on this, never onmessage. Codes are never repurposed; changed semantics always get a new code.message— human-readable detail, safe to log and to show to operators.correlationId— identifies this request across Passlet’s systems. Include it when you contact support about a failed request.
VALIDATION_ERROR) additionally include fieldErrors pinpointing the offending fields.
Common error codes
| HTTP | Codes | Notes |
|---|---|---|
| 400 | VALIDATION_ERROR, INVALID_INPUT, MISSING_REQUIRED_FIELD, INVALID_FORMAT | Malformed request or filter grammar violation |
| 401 | UNAUTHORIZED, TOKEN_EXPIRED, TOKEN_INVALID | Missing or bad access token |
| 403 | FORBIDDEN | Token valid but lacks the required scope |
| 404 | NOT_FOUND, PASS_NOT_FOUND, TEMPLATE_NOT_FOUND, WEBHOOK_NOT_FOUND | Resource doesn’t exist in your workspace |
| 409 | CONFLICT, VERSION_CONFLICT, DUPLICATE_PASS, IDEMPOTENCY_CONFLICT, TEMPLATE_VERSION_NOT_NEWER, SCAN_REVERSAL_WINDOW_EXPIRED | State conflicts — e.g. re-using an externalPassId with different data |
| 409 | PASS_ALREADY_ISSUED, PASS_ALREADY_VOIDED, PASS_NOT_ISSUED | Lifecycle-state conflicts |
| 429 | RATE_LIMITED | Slow down and retry with backoff |
| 5xx | INTERNAL_ERROR, PROVIDER_UNAVAILABLE | Retry with backoff; report persistent failures with the correlationId |
Retry guidance
- 4xx (except 429) — don’t retry unchanged; fix the request.
- 429 / 5xx — retry with exponential backoff and jitter.
- Batch endpoints report per-item outcomes — a failed item never aborts the whole batch, so check the per-item results rather than the HTTP status alone.