Skip to main content

API guide

API Error Handling: Status Codes & Error Objects 2026

A practical guide to API error handling in 2026 — HTTP status codes, error response formats, client-side retry logic, and patterns from Stripe, GitHub, Twilio.

·APIScout Team
Share:
Hero image for API Error Handling: Status Codes & Error Objects 2026

How to Handle API Errors: Status Codes and Error Objects

An error response has two jobs: tell software what happened and give a developer enough context to choose the next action. Use HTTP semantics for the first job, then keep one stable error envelope for machine-readable codes, human-readable messages, field details, and a correlation ID.

TL;DR verdict

Use the narrowest accurate HTTP status, a consistent JSON error shape, and retry guidance tied to the request rather than to a status code alone. Treat 422 Unprocessable Content as the RFC 9110 name. A 429 response means the caller has been rate limited; it should explain the condition and may include Retry-After. Retry only when the operation is safe or protected by idempotency, cap the attempts, and add jitter.

API fit matrix

SituationStatus familyResponse guidanceClient action
Resource created201Return the resource or a stable reference; a Location header can identify itContinue with the created resource
Asynchronous work accepted202Return a job or operation identifierPoll or consume the documented completion signal
Malformed request400Explain the parse or shape problemCorrect the request before retrying
Missing or invalid credentials401Describe the authentication requirement without leaking secretsRefresh or replace credentials
Authenticated but not permitted403Name the denied action at a safe levelRequest access or choose another operation
Resource absent404Keep the same envelope used elsewhereCheck identifier, tenant, and lifecycle state
State conflict409Include the conflicting state or version when safeRe-read state and decide whether to retry
Semantically invalid content422Return field or domain validation detailsCorrect the supplied values
Rate limited429Explain the limit and any retry signalRespect provider guidance; retry only if safe
Server or upstream failure5xxReturn a correlation ID and avoid internal detailsApply bounded, request-safe retry policy

This is an implementation map, not a rule that every API needs every status. RFC 9110 defines the semantics; your API contract defines which conditions can occur.

A stable error envelope

Use one public shape across endpoints. The following is a house schema, not a cross-provider standard:

{
  "error": {
    "type": "validation_error",
    "code": "invalid_parameter",
    "message": "The 'email' field must be a valid email address.",
    "param": "email",
    "request_id": "req_abc123def456",
    "doc_url": "https://api.example.com/docs/errors#invalid_parameter"
  }
}
FieldContract role
typeBroad category for logging and handling
codeStable programmatic condition
messageConcise explanation suitable for a developer
request_idCorrelation value shared with server-side logs
param or fieldLocation of a validation problem when applicable
doc_urlDirect documentation link when one exists
metadataTyped, documented context such as allowed values

For multiple validation failures, keep the envelope and add a documented errors array. Do not make clients switch parsers by endpoint.

Auth matrix

ConditionStatusSafe response detailAvoid
Credential missing or invalid401Authentication scheme and a stable error codeEchoing tokens or signature material
Credential valid, action denied403Required permission or policy category when disclosure is safeConfirming hidden resource details
Tenant or resource intentionally concealed404 where the API contract chooses concealmentStandard not-found envelopeA different shape that reveals existence
Provider-specific auth failureProvider contractPreserve the provider's diagnostic code and correlation dataReclassifying every auth failure as retryable

Twilio currently documents 20003: Permission Denied and provides current causes and remediation. The page does not establish the exact legacy response body reproduced by older copies of this guide, so use the name and remediation rather than inventing a payload. The protected reference link remains available at Twilio error 20003.

SDK quality table for error handling

SDK behaviorWhat good support looks likeIntegration test
Typed errorsStable classes or discriminated types preserve status, code, and request IDAssert a validation response maps to the expected type
Field errorsMultiple field failures remain accessible without parsing proseExercise nested and array field paths
CorrelationResponse and logs share the same request IDTrace one synthetic failure end to end
Retry metadataThe client exposes provider headers and attempt informationSimulate 429 and transient 5xx responses
Unknown errorsNew server codes fall back safelyInject an unrecognized code without crashing the parser

Current provider patterns

Stripe documents conventional HTTP response classes and conditional fields including type, code, message, doc_url, and request_log_url. Conditional matters: clients should not assume every field appears on every error.

GitHub documents 422 validation responses with an errors property containing diagnostic code values. Existing integrations may also link to the broader GitHub REST documentation, but the current troubleshooting page in Sources is the evidence for this pattern.

These are provider examples, not a ranking and not a universal envelope.

Rate-limit box

A 429 response indicates rate limiting. RFC 6585 says the representation should explain the condition and may include Retry-After; the header is not guaranteed.

Client policy:

  1. Read the provider's documented headers and body.
  2. Confirm the request is idempotent or carries a provider-supported idempotency key.
  3. Honor a valid retry delay when supplied; otherwise use bounded exponential backoff with jitter.
  4. Cap attempts and total elapsed time.
  5. Surface the final response, request ID, and attempt count to logs.

GitHub notes that rate-limit responses can use 403 or 429, so a client that keys only on 429 can miss provider-specific handling.

Client-side handling

Separate failures by what the client actually observed:

  • A network failure has no HTTP response. Retrying can be unsafe if the server processed the request before the connection failed.
  • An HTTP error has a response and should follow the provider contract.
  • A validation failure needs correction, not delay.
  • A conflict may be resolvable after re-reading state; it is not inherently terminal.

For user-facing copy, translate the developer response without discarding support context. "Invalid email address" is clearer than the raw status. "This [thing] doesn't exist" can be appropriate for a product screen. A transient state may say "Something went wrong, trying again..." while the log retains the technical error. Avoid exposing raw internals by default, but a support-friendly reference ID can be useful. Generic labels such as "Something went wrong" or "Server Error" should not be the only diagnostic information.

Integration risk box

The most expensive error-contract failures are semantic drift and unsafe retries:

  • The same code changes meaning between endpoints.
  • A field changes from scalar to array without versioning.
  • A client treats all 5xx responses as safe to replay.
  • Logs omit the response request ID.
  • Stack traces or credential fragments enter the public response.
  • User interfaces display provider prose as if it were stable product copy.

Version the error contract like any other API interface. Add new optional fields freely only when clients are documented to ignore unknown fields; reserve breaking changes for a versioned migration.

Source-backed evidence

Standards

RFC 9110 supplies current HTTP semantics, including the name 422 Unprocessable Content. RFC 6585 defines 429 and makes Retry-After optional.

Provider examples

GitHub supplies a current validation and rate-limit troubleshooting pattern. Stripe documents response classes, conditional error attributes, and backoff guidance. Twilio confirms the current name and remediation for error 20003.

Editorial limits

The recommended envelope, starter status set, monitoring thresholds, and retry budgets are architecture choices. Test them against your methods, idempotency model, traffic, and support workflow.

Methodology

APIScout reviewed the five primary sources below on 2026-08-21. Standards define protocol semantics; vendor documentation supports only the named provider examples. Unsupported rankings, timing claims, universal retry categories, and unverified test claims were removed. No cross-provider error schema is presented as a standard.

Source-backed FAQ

Should an API use 422 or 400 for validation?

RFC 9110 defines 422 for content whose syntax is understood but whose instructions cannot be processed. An API can still use 400 for documented validation cases; consistency in the published contract matters more than copying another provider.

Must a 429 response include Retry-After?

No. RFC 6585 says it may include the header. Clients need a bounded fallback and must still check whether replay is safe.

Should every 5xx response be retried?

No. The client needs the method, idempotency guarantees, provider guidance, and an attempt budget. A lost response to a successful mutation can make an automatic replay harmful.

What should support ask for?

Ask for the request or correlation ID, timestamp, endpoint, and safe reproduction details. Do not ask customers to paste credentials.

Sources

Designing API error handling? Explore API best practices and tools on APIScout — architecture guides, comparisons, and developer resources.

{/* Sources: err-rfc9110, err-rfc6585, err-github-troubleshooting, err-stripe-errors, err-twilio-20003. Claims: err-a01, err-a02, err-a03, err-a04, err-a05. */}

The API Integration Checklist (Free PDF)

Step-by-step checklist: auth setup, rate limit handling, error codes, SDK evaluation, and pricing comparison for 50+ APIs. Used by 200+ developers.

Join 200+ developers. Unsubscribe in one click.