# Canonical RFC 9457 (application/problem+json) Problem Details schema block.
# Vendors the error-handling conventions already documented in this skill —
# see references/api-design.md § "Error envelope: RFC 9457 Problem Details"
# and references/openapi.md. Field names, status codes, and problem-type
# strings below match those references exactly; do not invent new ones.
# Usage: paste the `components` block into api/openapi.yaml, then reference
# `#/components/schemas/ProblemDetails` from each operation's error responses.
RFC 9457 Problem Details for HTTP APIs. Every error response uses
this shape — never a bare string, never an ad-hoc error object.
description: A URI identifying the problem type. Stable and dereferenceable.
example: "https://api.example.com/errors#payment-failed"
description: Short, human-readable summary of the problem type.
example: "Payment Processing Failed"
description: The HTTP status code for this occurrence of the problem.
description: Human-readable explanation specific to this occurrence.
example: "Card declined: insufficient funds"
description: URI identifying the specific occurrence (usually the request path).
example: "/invoices/inv-123"
description: Validation failed — malformed JSON or a missing required field.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#bad-request"
detail: "field 'amount' is required"
description: Authentication missing or invalid.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#unauthorized"
detail: "missing or invalid bearer token"
description: Authenticated but not authorized for this resource.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#forbidden"
detail: "caller lacks the invoices:write scope"
instance: "/invoices/inv-123"
description: Resource does not exist.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#not-found"
detail: "invoice inv-123 does not exist"
instance: "/invoices/inv-123"
description: State conflict — duplicate resource or failed precondition.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#conflict"
detail: "invoice inv-123 is already finalized"
instance: "/invoices/inv-123"
description: Semantic validation failed (e.g., a past date for a future deadline).
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#validation-error"
title: "Validation Error"
detail: "due_date must be in the future"
description: Rate limit hit. Response includes a Retry-After header.
description: Seconds to wait before retrying.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#rate-limit-exceeded"
title: "Rate Limit Exceeded"
detail: "more than 100 requests in 60s"
Server error. Never echo internal error text (stack traces, driver
errors, SQL) to the client — map to this generic shape instead.
application/problem+json:
$ref: "#/components/schemas/ProblemDetails"
type: "https://api.example.com/errors#internal-error"
title: "Internal Server Error"
detail: "an unexpected error occurred"
# Reference from an operation like this:
# operationId: getInvoice
# description: Invoice found.
# $ref: "#/components/responses/NotFound"
# $ref: "#/components/responses/InternalError"