Public API
Small, stateless JSON endpoints on this same Next.js deployment. There is no authentication, no database, and no retention: each request is computed and forgotten. Same markdown emitters as the generator (formatNygardMarkdown, formatMadrMarkdown, etc.). API index and OpenAPI 3.0. Per-IP rate limits apply (rough in-process windows; response 429 with Retry-After). POST /api/generate-adrbodies are capped at 32 KiB (413 if larger).
Endpoints
GET https://www.adr.zone/api— service name, version, endpoint listGET https://www.adr.zone/api/formats— supported formats, required/optional fieldsGET https://www.adr.zone/api/openapi.json— OpenAPI 3.0.3 document (paths, schemas, examples)POST https://www.adr.zone/api/generate-adr— JSON in,markdownplusslugout
Example
curl -s -X POST "https://www.adr.zone/api/generate-adr" \
-H "Content-Type: application/json" \
-d '{"title":"Use PostgreSQL for new services","context":"We need one default DB for new work.","decision":"Default to PostgreSQL 15+ for new stateful services."}' | jqSupported formats
Default format is nygard. iso-42010 is an ISO/IEC/IEEE 42010–inspired record, not a formal “ISO 42010 ADR standard.”
nygard— Nygard ADRClassic markdown ADR: status, context, decision, and consequences. Matches the shape popularized in engineering blogs and adr-tools-style workflows.
Required: title, context, decision
Optional: format, status, consequences, moreInformation, notes
madr— MADR (Markdown ADR) v4.0.0MADR layout: YAML front matter, drivers, options, decision outcome with nested consequences/confirmation, per-option pros/cons, and more information. Use variant=minimal for the lean template.
Required: title, context, decision
Optional: format, variant, status, date, decisionMakers, consulted, informed, consequences, decisionDrivers, consideredOptions, confirmation, moreInformation, madrOptions, notes
y-statement— Y-StatementSingle reviewable Y-style sentence plus a field list. Optional fields map to the sentence content.
Required: title, context, decision
Optional: format, status, consequences, concern, decisionAgainst, outcome, tradeoff, notes, moreInformation
outcome-first— Outcome-FirstA low-ceremony ADR format for async engineering decisions: outcome, decision, primary tradeoff, why, and decision boundaries visible before the reasoning chain.
Required: title, context, decision
Optional: format, status, outcome, primaryTradeoff, tradeoff, decisionDrivers, impacted, notImpacted, assumptions, guardrails, notes
iso-42010— ISO 42010 CompanionAn advanced companion structure using ISO/IEC/IEEE 42010 vocabulary: stakeholders, concerns, views, and traceability. Not a standard ADR format—use to connect decisions to architecture descriptions.
Required: title, context, decision
Optional: format, status, consequences, system, stakeholders, concerns, viewpoint, rationale, architecturalImpact, traceability, moreInformation, notes
On this site
Generator · Templates · Examples · Raw /api/formats JSON · Raw /api/openapi.json
OpenAPI (Swagger-style)
The contract below matches the live route handlers. Import the JSON into Swagger Editor, Redoc, or any OpenAPI 3 toolchain. Same limits as other GET endpoints (rate limit, no auth).
Show OpenAPI 3.0.3 JSON (embedded)
{
"openapi": "3.0.3",
"info": {
"title": "adr.zone public API",
"version": "0.1.0",
"description": "Stateless ADR markdown generation. No authentication. Per-IP rate limits (429 + Retry-After). POST bodies max 32 KiB (413).",
"contact": {
"name": "adr.zone",
"url": "https://www.adr.zone"
}
},
"servers": [
{
"url": "https://www.adr.zone"
}
],
"tags": [
{
"name": "meta"
},
{
"name": "generate"
}
],
"paths": {
"/api": {
"get": {
"tags": [
"meta"
],
"summary": "API index",
"description": "Service name, version, and endpoint list.",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"version",
"endpoints"
],
"properties": {
"name": {
"type": "string",
"example": "adr.zone API"
},
"version": {
"type": "string"
},
"endpoints": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
"/api/openapi.json": {
"get": {
"tags": [
"meta"
],
"summary": "OpenAPI document",
"description": "Machine-readable OpenAPI 3.0.3 JSON for this API.",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object"
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
"/api/formats": {
"get": {
"tags": [
"meta"
],
"summary": "Supported ADR formats",
"description": "Lists format ids, human descriptions, and required/optional JSON fields for POST /api/generate-adr.",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"formats"
],
"properties": {
"formats": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"name",
"shortDescription",
"requiredFields",
"optionalFields"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"shortDescription": {
"type": "string"
},
"requiredFields": {
"type": "array",
"items": {
"type": "string"
}
},
"optionalFields": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
},
"/api/generate-adr": {
"post": {
"tags": [
"generate"
],
"summary": "Generate ADR markdown",
"description": "Validates JSON, renders markdown with the same templates as the on-site generator, returns markdown plus a filename slug.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"title",
"context",
"decision"
],
"properties": {
"format": {
"type": "string",
"enum": [
"nygard",
"madr",
"y-statement",
"outcome-first",
"iso-42010"
],
"description": "Output template. Defaults to nygard."
},
"variant": {
"type": "string",
"enum": [
"full",
"minimal"
],
"description": "MADR only: full template (default) or minimal template. Ignored for other formats."
},
"title": {
"type": "string",
"minLength": 1
},
"context": {
"type": "string",
"minLength": 1
},
"decision": {
"type": "string",
"minLength": 1
},
"status": {
"type": "string"
},
"date": {
"type": "string",
"description": "MADR YAML front matter: date"
},
"decisionMakers": {
"type": "string",
"description": "MADR YAML: decision-makers"
},
"consulted": {
"type": "string"
},
"informed": {
"type": "string"
},
"consequences": {
"type": "string"
},
"decisionDrivers": {
"type": "array",
"items": {
"type": "string"
}
},
"consideredOptions": {
"type": "array",
"items": {
"type": "string"
}
},
"confirmation": {
"type": "string"
},
"moreInformation": {
"type": "string"
},
"madrOptions": {
"type": "array",
"description": "MADR per-option pros/cons blocks (title, optional description, optional items markdown).",
"items": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"items": {
"type": "string"
}
}
}
},
"notes": {
"type": "string"
},
"concern": {
"type": "string"
},
"decisionAgainst": {
"type": "string"
},
"outcome": {
"type": "string"
},
"tradeoff": {
"type": "string"
},
"primaryTradeoff": {
"type": "string"
},
"impacted": {
"type": "array",
"items": {
"type": "string"
}
},
"notImpacted": {
"type": "array",
"items": {
"type": "string"
}
},
"assumptions": {
"type": "array",
"items": {
"type": "string"
}
},
"guardrails": {
"type": "array",
"items": {
"type": "string"
}
},
"system": {
"type": "string"
},
"stakeholders": {
"type": "array",
"items": {
"type": "string"
}
},
"concerns": {
"type": "array",
"items": {
"type": "string"
}
},
"viewpoint": {
"type": "string"
},
"rationale": {
"type": "string"
},
"architecturalImpact": {
"type": "string"
},
"traceability": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"examples": {
"nygardMinimal": {
"summary": "Minimal Nygard",
"value": {
"title": "Use PostgreSQL for new services",
"context": "We need one default DB for new work.",
"decision": "Default to PostgreSQL 15+ for new stateful services."
}
}
}
}
}
},
"responses": {
"200": {
"description": "Generated markdown",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"format",
"title",
"slug",
"markdown"
],
"properties": {
"format": {
"type": "string"
},
"title": {
"type": "string"
},
"slug": {
"type": "string"
},
"markdown": {
"type": "string"
}
}
}
}
}
},
"400": {
"description": "Invalid JSON or validation error",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
},
"413": {
"description": "Request body larger than 32 KiB",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
},
"429": {
"description": "Rate limited",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"examples": [
"invalid_json",
"validation_error",
"rate_limited",
"payload_too_large"
]
},
"message": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
}Try it
Send real requests from your browser to this deployment (same origin). For POST /api/generate-adr, edit the JSON body, then Send request.