Reusable RFC 9457 Problem Details components for all Jentic APIs.
All Jentic APIs use application/problem+json for error responses. This repository provides:
- OpenAPI schemas and response definitions — for referencing in API specifications
- Python package (
jentic-problem-details) — Pydantic models and FastAPI utilities - TypeScript package (
@jentic/problem-details) — Type definitions and utilities for frontend applications
Rather than inlining schemas and responses in every API, all Jentic OpenAPI descriptions reference this repository's components directly.
Reference components directly from your OpenAPI description:
responses:
'400':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/400-bad-request.yaml'
'401':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/401-unauthorized.yaml'
'403':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/403-forbidden.yaml'
'404':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/404-not-found.yaml'
'409':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/409-conflict.yaml'
'422':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/422-validation-error.yaml'
'429':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/429-too-many-requests.yaml'
'500':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/500-server-error.yaml'
'503':
$ref: 'https://raw.githubusercontent.com/jentic/api-problem-details/refs/heads/main/responses/503-service-unavailable.yaml'Install the package:
pip install jentic-problem-detailsUse in your FastAPI application:
from fastapi import FastAPI, Request
from jentic.problem_details import (
BadRequest,
NotFound,
ProblemDetailException,
problem_detail_exception_handler,
)
app = FastAPI()
app.add_exception_handler(ProblemDetailException, problem_detail_exception_handler)
@app.get("/users/{user_id}")
async def get_user(user_id: str):
user = await db.get_user(user_id)
if not user:
raise NotFound(
detail=f"User '{user_id}' not found",
instance=f"/users/{user_id}"
)
return user
@app.post("/users")
async def create_user(request: Request):
data = await request.json()
errors = []
if not data.get("name"):
errors.append({"detail": "Field 'name' is required", "pointer": "#/name"})
if not data.get("email"):
errors.append({"detail": "Field 'email' is required", "pointer": "#/email"})
if errors:
raise BadRequest(
detail="The request body is missing required fields",
instance="/users",
errors=errors
)
return await db.create_user(data)See the Python package README for complete documentation.
Install the package:
npm install @jentic/problem-detailsUse in your application:
import { createProblemDetail, ProblemDetailError } from '@jentic/problem-details';
// Create a problem detail
const problem = createProblemDetail.notFound('User not found', {
instance: '/api/users/123',
});
// Handle errors from fetch
try {
const response = await fetch('/api/users/123');
if (!response.ok) {
throw await ProblemDetailError.fromResponse(response);
}
return await response.json();
} catch (err) {
if (err instanceof ProblemDetailError) {
console.error('API Error:', err.problemDetail);
// Access structured error data
if (err.problemDetail.errors) {
err.problemDetail.errors.forEach(error => {
console.log(`${error.pointer}: ${error.detail}`);
});
}
}
}See the TypeScript package README for complete documentation.
Jentic uses about:blank as the type for most problem responses, per RFC 9457 guidance. When type is about:blank, the title SHOULD be the standard HTTP status phrase and detail MUST provide a human-readable explanation specific to the occurrence.
Where a specific IANA-registered problem type applies, it SHOULD be used. See the IANA HTTP Problem Types Registry.
| Package | Language | Status | Installation |
|---|---|---|---|
jentic-problem-details |
Python | ✅ Available | pip install jentic-problem-details |
@jentic/problem-details |
TypeScript | ✅ Available | npm install @jentic/problem-details |
openapi-domain.yaml # Primary artifact — all components bundled
schemas/
problem-details.yaml # ProblemDetails schema
error-item.yaml # ErrorItem schema (errors[] array entries)
responses/
400-bad-request.yaml
401-unauthorized.yaml
403-forbidden.yaml
404-not-found.yaml
409-conflict.yaml
422-validation-error.yaml
429-too-many-requests.yaml
500-server-error.yaml
503-service-unavailable.yaml
python/ # Python package (jentic-problem-details)
src/jentic/problem_details/
tests/
pyproject.toml
README.md
typescript/ # TypeScript package (@jentic/problem-details)
src/
tests/
package.json
tsconfig.json
README.md
LICENSE # Apache 2.0 License
NOTICE # Copyright and attribution notices