API Error Generator Guide: Design Helpful Error Responses
Technical Mastery Overview
How to Use the Generator
1. Choose a response standard
Select one of the four formats from the Response Standard toggle:
| Format | Best for |
|---|---|
| RFC 7807 | New REST APIs — IETF standard, widely understood |
| Stripe | SaaS/payment APIs — nested error object with type, code, doc_url |
gRPC-compatible or Google AIP–style APIs — typed details array |
|
| Simple | Internal or mobile-first APIs — flat success/error/message format |
2. Select the error condition
Pick an HTTP status code from the Error Condition dropdown. Available codes: 400, 401, 403, 404, 405, 408, 409, 410, 415, 422, 429, 500, 502, 503, 504.
3. Write a custom message (optional)
Type your own error message in the Custom Message field to override the default. Leave it blank to use the built-in default for that status code. Use this to write the exact detail or message field your API will send.
4. Add field-level validation errors (400 / 422 only)
When 400 or 422 is selected, an Add Field button appears. Each field error has:
- field — the dot-path name (
email,user.age,items[0].quantity) - code — machine-readable error code (
REQUIRED,INVALID_FORMAT,OUT_OF_RANGE,TOO_SHORT,TOO_LONG,INVALID_ENUM,DUPLICATE) - message — human-readable explanation
The generated errors[] array is injected into the output at the correct path for each format (top-level for RFC 7807/Simple, inside error for Stripe, as a BadRequest detail entry for Google).
5. Toggle trace ID inclusion
Enable Include Trace / Request ID to add a trace_id or request_id field to the output. This is the field developers use to look up the failing request in your server logs — always include it in production error responses.
6. Switch output tabs
The output panel has three tabs:
JSON — Syntax-highlighted JSON with color-coded keys (blue), string values (green), numbers (orange), booleans (purple), and null (red). Click copy to copy the full JSON.
Headers — Recommended HTTP response headers for the selected status code. Each header has an inline note explaining why it's needed. Hover any row to copy just that header. Key headers: Content-Type: application/problem+json (RFC 7807), WWW-Authenticate (401), Allow (405), Retry-After + rate limit headers (429), Retry-After (503).
Code — A working server snippet in your language of choice. Switch between Express (Node.js), FastAPI (Python), and Go with the language tabs. The snippet includes the correct status code, Content-Type header, and the full generated JSON body — ready to paste into your implementation.
7. Copy and Reset
The copy icon in the top-right of the output panel copies whatever is currently shown (JSON, headers as plain text, or the code snippet). Click Reset in the header to return all controls to defaults (RFC 7807, 400 Bad Request, no custom message, trace off, no field errors).
Why Error Design Matters
When an API fails, the consumer needs to answer three questions:
- What went wrong? (category of error)
- Why did it go wrong? (specific cause)
- What should I do about it? (actionable guidance)
A response of {"error": "Bad Request"} answers none of these. A well-designed error response answers all three and lets the client decide whether to show a user-friendly message, retry automatically, or escalate.
Bad error design is one of the most common API integration complaints from developers. It multiplies support tickets, extends integration timelines, and makes your API frustrating to use.
RFC 7807 — Problem Details for HTTP APIs
RFC 7807 defines a standard JSON format for API error responses:
{
"type": "https://api.example.com/errors/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "One or more fields failed validation.",
"instance": "/orders/ord_abc123",
"errors": [
{
"field": "quantity",
"message": "Must be a positive integer",
"value": -1
},
{
"field": "email",
"message": "Invalid email format",
"value": "not-an-email"
}
]
}
| Field | Required | Purpose |
|---|---|---|
type |
Required | A URI identifying the error type — should resolve to documentation |
title |
Required | Short human-readable summary of the error type |
status |
Recommended | The HTTP status code |
detail |
Recommended | Specific explanation for this occurrence |
instance |
Optional | URI identifying the specific request instance |
| Custom fields | Optional | Anything useful to the consumer (e.g., errors, requestId) |
The type URI is the machine-readable key. Clients can identify error types programmatically and handle them specifically — without string-matching on title or detail (which you might translate).
HTTP Status Code Selection
Selecting the wrong status code is the most common error design mistake:
| Scenario | Correct code | Common mistake |
|---|---|---|
| Request body fails schema validation | 422 | 400 |
| Missing authentication header | 401 | 403 |
| Valid auth, insufficient permissions | 403 | 401 |
| Resource doesn't exist | 404 | 400 |
| Client sent no body within timeout | 408 | 504 |
| Duplicate resource (email already registered) | 409 | 400 |
| Resource permanently deleted | 410 | 404 |
Wrong Content-Type header |
415 | 400 |
| Rate limit exceeded | 429 | 400 or 503 |
| Upstream service returned garbage | 502 | 500 |
| Upstream dependency timeout | 504 | 500 |
| Planned maintenance | 503 | 500 |
Reference our HTTP Status Code guide for the full taxonomy. The general rule: 4xx errors mean the client did something wrong; 5xx errors mean your server failed at something valid.
Validation Error Format
Validation errors are the most common error type. The response should identify every failing field — not just the first one:
{
"type": "https://api.example.com/errors/validation",
"title": "Validation Error",
"status": 422,
"detail": "The request body contains invalid fields.",
"errors": [
{
"field": "user.email",
"code": "INVALID_FORMAT",
"message": "Must be a valid email address"
},
{
"field": "user.age",
"code": "OUT_OF_RANGE",
"message": "Must be between 18 and 120",
"constraints": { "min": 18, "max": 120 }
},
{
"field": "plan",
"code": "INVALID_ENUM",
"message": "Must be one of: basic, pro, enterprise",
"allowedValues": ["basic", "pro", "enterprise"]
}
]
}
Key decisions:
- Return all errors at once — don't force clients to fix one error, resubmit, and discover another
- Include field paths for nested objects (
user.email,items[2].quantity) - Include machine-readable codes (
INVALID_FORMAT) alongside human-readable messages - Include constraints where helpful (
min,max,allowedValues) so clients can update validation without reading docs
Authentication and Authorization Errors
{
"type": "https://api.example.com/errors/authentication-required",
"title": "Authentication Required",
"status": 401,
"detail": "This endpoint requires a valid Bearer token. Obtain one at /auth/token."
}
{
"type": "https://api.example.com/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "Your account does not have permission to access this resource. Contact your admin to request the 'orders:write' permission."
}
401 errors should include a WWW-Authenticate header: WWW-Authenticate: Bearer realm="api". This tells HTTP clients what authentication scheme to use.
Rate Limiting Errors
{
"type": "https://api.example.com/errors/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded the limit of 100 requests per minute.",
"retryAfter": 47,
"limits": {
"requestsPerMinute": 100,
"remaining": 0,
"resetAt": "2025-03-10T14:30:00Z"
}
}
Include a Retry-After HTTP header alongside the body field. Clients can implement automatic retry with the correct delay. Also include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers on all responses (not just 429s) so clients can manage their budget proactively.
Server Error Format
For 5xx errors, return minimal information to the client and log the full detail server-side:
{
"type": "https://api.example.com/errors/internal",
"title": "Internal Server Error",
"status": 500,
"detail": "An unexpected error occurred. Use the requestId to report this issue.",
"requestId": "req_2f3a4b5c6d7e8f"
}
Never expose stack traces, database error messages, internal paths, or server version info in production 500 responses — these are information leakage vulnerabilities. Log everything server-side; return only the requestId that lets you look it up.
Internationalizing Error Messages
If your API serves international clients, separate machine-readable codes from human-readable messages:
{
"errors": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Must be a valid email address"
}
]
}
The code field (INVALID_FORMAT) is stable and language-independent. The message field can be translated by the client using the code as a lookup key. This lets your API serve a single error format while letting frontends display localized messages.
Testing Your Error Responses
After designing an error format:
- Validate the JSON structure with our JSON Formatter
- Validate against your schema with our JSON Schema Validator
- Test the actual endpoint using our cURL Generator — confirm the error is returned with the correct status code and headers
- Check the status code semantics against our HTTP Status Code reference
- Document the error types in your API docs — each
typeURI should resolve to a page explaining the error, common causes, and resolution steps
Consistent, well-documented errors reduce developer support burden more than almost any other API design investment.
Experience it now.
Use the professional-grade API Error Generator with zero latency and 100% privacy in your browser.