Skip to content
API Error Handling: Building APIs That Fail Gracefully 3 min

API Error Handling: Building APIs That Fail Gracefully

SD
ScaleDojo
May 11, 2026
3 min read647 words
API Error Handling: Building APIs That Fail Gracefully

The Goal of Good Error Messages

You're integrating a payment API at 11pm, racing to launch tomorrow. You send a request and get back {"error": true}. That's it. No code, no message, no field-level detail. This is a textbook case of poor API error handling, and it leaves you with no idea what went wrong. Was it your card number? Your API key? A server crash? You spend two hours guessing before finding a typo in the currency field.

Now compare that with Stripe's error response: it tells you the exact field, the exact problem, a machine-readable code for your error handler, and a link to the docs. You fix it in 30 seconds. That's the difference good API error handling makes, and it's one of the clearest signals of a well-designed API.

API Error Handling: Building APIs That Fail Gracefully - Architecture Diagram

Architecture overview

A Standard Error Response Format

Every error response from your API should follow a consistent structure. Here's a battle-tested format used by Stripe, Twilio, and other best-in-class APIs:

ChatGPT Image Jul 20, 2026, 05_31_44 PM.png

This response answers the three questions a developer actually needs answered. What went wrong (a validation error in two fields). Is it my fault (422 means yes, client error). How do I fix it (email format is wrong, age is out of range).

Error Response Best Practices

  • Always use appropriate HTTP error status codes (4xx for client errors, 5xx for server errors), never wrap errors in a 200

  • Include a machine-readable error code (like VALIDATION_ERROR) that client code can switch on

  • Include a human-readable message for developers reading logs

  • For validation errors, specify which fields failed and why, this lets frontends highlight the right form fields

  • Include a request_id for traceability. "My request req_abc123 is failing" is infinitely more useful in a support ticket than "it doesn't work"

  • Never expose stack traces or internal paths in production, attackers use these to map your system

  • Never expose sensitive data in error messages. "No user with password X exists" quietly confirms the password was checked

If you're weighing these decisions against broader questions like where validation should live (gateway vs. service) or how errors should propagate across a BFF layer, it's worth reading API Gateway, BFF, tRPC, and the Multi-Protocol Architecture.

Common Error Patterns

ChatGPT Image Jul 20, 2026, 05_34_45 PM.png

Retry Guidance

Your error responses should help clients decide whether to retry at all. Build this logic into your client SDKs rather than leaving every caller to guess:

ChatGPT Image Jul 21, 2026, 12_00_48 AM.png

This kind of retry semantics matters even more once you're dealing with asynchronous or event-driven APIs, where a failed delivery might need to be replayed rather than retried inline. AMQP, Kafka, and Event Sourcing: The Async API Story covers how that changes the error-handling picture.

Security Considerations

Error messages can leak information to attackers if you're not careful. Watch for these patterns:

  • Login errors: say "Invalid email or password", not "No user with that email" (which confirms the email has no account)

  • Permission errors: sometimes return 404 instead of 403 to avoid revealing that a resource exists to unauthorized users

  • Internal errors: return a generic "Internal server error" with a request_id, and log the actual error server-side only

  • Enumeration attacks: rate-limit endpoints like /forgot-password and return the same response whether the email exists or not

Interview Tip

When designing an API in an interview, sketch the error response format alongside the success response. Say: "Every error returns a consistent JSON structure with type, code, message, and details. For validation errors, details is an array of per-field errors. Every response includes a request_id for tracing." Then add: "4xx errors should not be retried, 5xx should be retried with exponential backoff." This shows production-level thinking, and it pairs well with the kind of API exception handling discussion covered in LLD: Master the Building Blocks of Low-Level Design.

Key Takeaway

Good error responses are structured, specific, and actionable. Use proper HTTP status codes, include machine-readable codes alongside human-readable messages, enumerate field-level validation errors, and never expose internal details. Your API's error responses will be read ten times more often than its documentation, so treat REST API error handling as a first-class design decision, not an afterthought.

Enjoyed this article?

Share it with your network to help others level up their system design skills.

Discussion0

Join the Discussion

Sign in to leave comments, reply to others, or like insights.

Sign In to ScaleDojo

No comments yet. Be the first to start the thread!

Related Articles

Enjoyed this content?

Your support keeps us creating free resources

We put a lot of hours into researching and writing these guides. If it helped you, consider buying us a coffee. Every bit goes toward keeping ScaleDojo's content free and growing.

$

One-time payment via Stripe. ScaleDojo account required.

ScaleDojo Logo
Initializing ScaleDojo