{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:cede:schema:error:v0",
  "title": "CEDE error response, v0",
  "description": "Every non-2xx response the API produces, in one shape. SPEC.md section 3 requires every response to validate against the published schema; an error is a response, so it is published here rather than left to the framework's default. The shape is deliberately narrow: a machine-readable code, a human-readable message, and an optional list of details. It carries no field that could present a refusal as a commercial position — a refusal is a fact about a request, never a statement about risk appetite (SPEC.md section 3.1).",
  "type": "object",
  "additionalProperties": false,
  "required": ["schema_version", "error"],
  "properties": {
    "schema_version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Version of this error schema the payload conforms to."
    },
    "error": {
      "type": "object",
      "additionalProperties": false,
      "required": ["status", "code", "message"],
      "properties": {
        "status": {
          "type": "integer",
          "minimum": 400,
          "maximum": 599,
          "description": "The HTTP status of the response, restated in the body so a client that has lost the envelope still knows what happened."
        },
        "code": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9_]*$",
          "description": "Stable machine-readable identifier for the failure. A pattern rather than an enum: new failure modes must not require a schema version bump to be reported honestly, and a client switches on the codes it knows and falls back on status for the rest."
        },
        "message": {
          "type": "string",
          "minLength": 1,
          "description": "What went wrong, in the words a developer needs to fix it. Never a secret, never a stack trace."
        },
        "details": {
          "type": "array",
          "description": "Per-item detail where one request failed for several reasons at once (a malformed body with three faults). Absent when there is nothing to add beyond the message.",
          "items": {
            "type": "string",
            "minLength": 1
          }
        }
      }
    }
  }
}
