docs(api): correct /docs/api against the v1 implementation (#999)

Audited every endpoint, param, header, request/response field, error code, and
webhook event in the public API docs against the v1 implementation and fixed the
drift; addressed two rounds of CodeRabbit review.

- Error envelope, idempotency, dry-run, and reversal-field corrections.
- Registered the missing articles/dimensions/inbox-items reference resources.
- Cookbook fixes: removed nonexistent endpoints, corrected params/fields, fixed
  the test-key vs live-key quickstart flow and the year-end lock/close sequence.
- Webhooks/changelog: retry window ~87h (incl. route metadata), shipped-vs-
  coming-soon, counts, API-key format, previous_attributes.
- export-docs-to-website.mts absolutises app-served links for the website.

The gnubok-website side is on branch docs/api-correctness (already deployed).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
Jakob Wennberg
2026-07-12 12:57:26 +02:00
committed by GitHub
parent 7d7f604e00
commit ee3c33c7a4
17 changed files with 457 additions and 416 deletions
+6 -9
View File
@@ -73,7 +73,7 @@ export function buildErrorReferenceMd(): string {
const lines: string[] = []
lines.push('# Errors')
lines.push('')
lines.push(`> Every error returned by the Accounted REST API uses a stable code from this catalogue. Codes never change once shipped: agents can pattern-match on them safely. The \`docs_url\` field on every error envelope points at the anchor for that specific code.`)
lines.push(`> Every error returned by the Accounted REST API uses a stable code from this catalogue. Codes never change once shipped: agents can pattern-match on them safely. The \`docs_url\` field on every error envelope points at the catalogue entry for that specific code.`)
lines.push('')
lines.push('## Envelope shape')
lines.push('')
@@ -83,18 +83,15 @@ export function buildErrorReferenceMd(): string {
lines.push(' "code": "PERIOD_LOCKED",')
lines.push(' "message": "Den valda perioden är låst.",')
lines.push(' "message_en": "The selected period is locked.",')
lines.push(' "remediation": {')
lines.push(' "description": "Unlock via /fiscal-periods/{id}/unlock or pick an open period.",')
lines.push(' "tool": "fiscal_periods.unlock"')
lines.push(' },')
lines.push(' "details": { "fiscal_period_id": "..." },')
lines.push(' "docs_url": "https://app.gnubok.se/docs/api/errors#period_locked"')
lines.push(' },')
lines.push(' "meta": { "request_id": "req_...", "api_version": "..." }')
lines.push(' "recovery_hint": "Unlock via /fiscal-periods/{id}/unlock or pick an open period.",')
lines.push(' "docs_url": "https://app.gnubok.se/docs/api/errors/PERIOD_LOCKED",')
lines.push(' "request_id": "req_..."')
lines.push(' }')
lines.push('}')
lines.push('```')
lines.push('')
lines.push(`The \`message\` field is Swedish (matches the dashboard); \`message_en\` is English (for agent and developer logs); \`remediation\` (when present) hints at the canonical fix and may include a \`tool\` reference into the MCP surface.`)
lines.push(`The \`message\` field is Swedish (matches the dashboard); \`message_en\` is English (for agent and developer logs). \`recovery_hint\` (when present) is a one-line description of the canonical fix. \`request_id\` echoes the request for support and log correlation — note it lives inside \`error\` on failures (there is no top-level \`meta\` block on an error response, unlike the success envelope). \`docs_url\` is built from the code (\`…/docs/api/errors/<CODE>\`).`)
lines.push('')
for (const label of orderedLabels) {