{
  "openapi": "3.1.1",
  "info": {
    "title": "Diagraming public API",
    "version": "1.0.0",
    "description": "Private Mermaid diagrams with explicit publication. Bootstrap bearer keys from signed-in /settings/account; secrets are shown once and stored as hashes. Keys cannot issue keys. Application scopes are described per operation, not OAuth scopes. All v1 JSON and asset responses, including errors, use Cache-Control: no-store. Request JSON is limited to 1 MiB actual bytes; source is limited to 50,000 UTF-16 code units. Rendering limits: 500 edges, 8192 per output axis, 16,000,000 actual pixels including PNG 2x scaling, 1,000,000-code-unit SVG, two active jobs/process with no queue and 20-second deadline. External resources and active SVG are unsupported. Rates are process-local guards across keys/formats, not distributed quotas. See docs/public-api.md for bootstrap, retries, publication/revocation and rollout notes. Free: 100 saved diagrams and 200 successful API renders per UTC calendar month, shared across REST/MCP and all keys. There is currently no self-service upgrade. Rate/size/resource safeguards still apply. Validation, raw source, browser exports and public snapshot downloads are excluded from monthly usage. Account settings shows usage."
  },
  "servers": [
    {
      "url": "/",
      "description": "Same origin as this OpenAPI document"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/api/v1/diagrams": {
      "get": {
        "operationId": "listDiagrams",
        "summary": "List owned diagrams",
        "description": "READ. 120 reads/minute/user/process. Live pagination: limit 1–100 (default 50), updatedAt DESC then ID DESC; follow nextCursor until null and deduplicate by ID across concurrent edits. q searches title/source case-insensitively and is trimmed; cursor must match the normalized query.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_READ"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "At most 200 UTF-16 code units before trimming.",
            "example": "Order"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "example": 25
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 1024
            },
            "description": "Opaque nextCursor; URL-encode it and keep the same normalized q."
          }
        ],
        "responses": {
          "200": {
            "description": "200 page of owned diagrams, including source and publication URLs.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiagramListResponse"
                },
                "example": {
                  "data": [
                    {
                      "id": "doc_123",
                      "title": "Order flow",
                      "source": "flowchart LR\nOrder --> Payment --> Delivery",
                      "updatedAt": "2026-10-23T14:00:00.000Z",
                      "folder": null,
                      "publishedCheckpoints": []
                    }
                  ],
                  "nextCursor": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "post": {
        "operationId": "createDiagram",
        "summary": "Create a private diagram",
        "description": "WRITE. 60 writes/minute/user/process. Saves exact source and an initial revision without publication or syntax validation. Idempotent retries create once: replay returns the current representation, including later edits, without reapplying source. Different payload returns 409; matching key after deletion returns 410. Authentication/validation failures and rolled-back creations do not reserve a key. Free accounts can store up to 100 diagrams. At the cap, new creation returns 403 plan_limit_reached; idempotent replays remain available.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_WRITE"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "JSON body, at most 1,048,576 streamed UTF-8 bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDiagramRequest"
              },
              "example": {
                "title": "Order flow",
                "source": "flowchart LR\nOrder --> Payment --> Delivery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "200 deduplicated creation; current diagram representation.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              },
              "Idempotency-Replayed": {
                "description": "Idempotent replay.",
                "schema": {
                  "type": "string",
                  "const": "true"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiagramResponse"
                },
                "example": {
                  "data": {
                    "id": "doc_123",
                    "title": "Order flow",
                    "source": "flowchart LR\nOrder --> Payment --> Delivery",
                    "updatedAt": "2026-10-23T14:00:00.000Z",
                    "folder": null,
                    "publishedCheckpoints": [],
                    "currentRevision": {
                      "id": "rev_123",
                      "version": 1
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "201 newly created private diagram.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              },
              "Idempotency-Replayed": {
                "description": "New creation, including requests without a retry key.",
                "schema": {
                  "type": "string",
                  "const": "false"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiagramResponse"
                },
                "example": {
                  "data": {
                    "id": "doc_123",
                    "title": "Order flow",
                    "source": "flowchart LR\nOrder --> Payment --> Delivery",
                    "updatedAt": "2026-10-23T14:00:00.000Z",
                    "folder": null,
                    "publishedCheckpoints": [],
                    "currentRevision": {
                      "id": "rev_123",
                      "version": 1
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Insufficient key scope or plan_limit_reached. Plan-limit errors include details.resource, details.limit and details.resetsAt for renders.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyConflict"
          },
          "410": {
            "$ref": "#/components/responses/IdempotencyDeleted"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/diagrams/{diagramId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DiagramId"
        }
      ],
      "get": {
        "operationId": "getDiagram",
        "summary": "Read an owned diagram",
        "description": "READ. 120 reads/minute/user/process. Includes current revision, exact source, folder and publication links.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_READ"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Diagram"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "patch": {
        "operationId": "updateDiagram",
        "summary": "Update title and source atomically",
        "description": "WRITE. 60 writes/minute/user/process. At least one change field required. Optional expectedUpdatedAt must match exactly to the millisecond, including title-only/no-op requests. Changes commit together; changed source creates one revision, title-only does not, no-op preserves timestamp/revision. Reconcile a 409 before retrying.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_WRITE"
        ],
        "requestBody": {
          "required": true,
          "description": "JSON body, at most 1,048,576 streamed UTF-8 bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDiagramRequest"
              },
              "example": {
                "title": "Updated order flow",
                "source": "flowchart LR\nOrder --> Payment --> Delivery",
                "expectedUpdatedAt": "2026-10-23T14:00:00.000Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Diagram"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/StaleDocument"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      },
      "delete": {
        "operationId": "deleteDiagram",
        "summary": "Delete a diagram and its publications",
        "description": "WRITE. 60 writes/minute/user/process. Future public lookups return 404. Repeated/missing delete returns 404; create retry receipts remain until account deletion.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_WRITE"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/diagrams/{diagramId}/export": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DiagramId"
        }
      ],
      "get": {
        "operationId": "exportDiagram",
        "summary": "Download a private diagram",
        "description": "READ; SVG/PNG/PDF additionally require MERMAID_RENDER on the same key. Raw source ignores theme, needs no browser and supports legacy oversized/invalid source. Defaults svg/dark. Raw: 120 reads/minute/user/process; visual: shared 20 renders/minute/user/process. SVG/PNG/PDF count toward the shared monthly API-render allowance (Free: 200; no self-service upgrade currently). Raw Mermaid is excluded. Exhaustion returns 403 plan_limit_reached with resetsAt.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_READ"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/Format"
          },
          {
            "$ref": "#/components/parameters/Theme"
          }
        ],
        "x-format-required-scopes": {
          "mermaid": [
            "DIAGRAMS_READ"
          ],
          "svg": [
            "DIAGRAMS_READ",
            "MERMAID_RENDER"
          ],
          "png": [
            "DIAGRAMS_READ",
            "MERMAID_RENDER"
          ],
          "pdf": [
            "DIAGRAMS_READ",
            "MERMAID_RENDER"
          ]
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/Asset"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Insufficient key scope or plan_limit_reached. Plan-limit errors include details.resource, details.limit and details.resetsAt for renders.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/RenderFailure"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/RendererUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/RenderTimeout"
          }
        }
      }
    },
    "/api/v1/diagrams/{diagramId}/publish": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DiagramId"
        }
      ],
      "post": {
        "operationId": "publishDiagram",
        "summary": "Publish saved source and theme explicitly",
        "description": "READ + SHARE. 60 writes/minute/user/process. Discloses source publicly, including .mmd. Snapshots saved content atomically without overwriting the draft; optional timestamp must match exactly. Same normalized slug updates the same checkpoint ID/URLs; draft edits do not change files. Does not validate syntax or promise archival bytes.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_READ",
          "DIAGRAMS_SHARE"
        ],
        "requestBody": {
          "required": true,
          "description": "JSON body, at most 1,048,576 streamed UTF-8 bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublishDiagramRequest"
              },
              "example": {
                "name": "release",
                "theme": "light",
                "expectedUpdatedAt": "2026-10-23T14:00:00.000Z"
              }
            }
          }
        },
        "responses": {
          "201": {
            "$ref": "#/components/responses/Published"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/StaleDocument"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/diagrams/{diagramId}/published/{checkpointId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/DiagramId"
        },
        {
          "$ref": "#/components/parameters/CheckpointId"
        }
      ],
      "delete": {
        "operationId": "revokePublishedCheckpoint",
        "summary": "Revoke a published checkpoint",
        "description": "SHARE. 60 writes/minute/user/process. Subsequent file lookups return 404. Recreating the name uses a new ID so old file URLs stay revoked; HTML slug is reusable. Cannot retract in-flight responses/downloaded copies. Revoking an API key alone does not revoke publication.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "DIAGRAMS_SHARE"
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Revoked"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    },
    "/api/v1/mermaid/validate": {
      "post": {
        "operationId": "validateMermaid",
        "summary": "Validate source without saving",
        "description": "RENDER. 120 validations/minute/user/process. Syntax errors return 200 with data.valid=false and diagnostic; input/resource/execution errors use the error envelope. Shares two renderer slots and the 20-second deadline.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "MERMAID_RENDER"
        ],
        "requestBody": {
          "required": true,
          "description": "JSON body, at most 1,048,576 streamed UTF-8 bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateMermaidRequest"
              },
              "example": {
                "source": "flowchart LR\nOrder --> Payment --> Delivery"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "200 valid source or syntax diagnostic; no persistence.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationResponse"
                },
                "examples": {
                  "valid": {
                    "value": {
                      "data": {
                        "valid": true
                      }
                    }
                  },
                  "invalid": {
                    "value": {
                      "data": {
                        "valid": false,
                        "diagnostic": {
                          "stage": "parse",
                          "title": "Line 2: Mermaid syntax error",
                          "summary": "Check the diagram syntax.",
                          "detail": null,
                          "technicalDetail": "Parse error on line 2.",
                          "line": 2,
                          "column": null,
                          "from": 13,
                          "to": 21,
                          "sourceLine": "Order -->",
                          "expectedTokens": [],
                          "foundToken": null
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/RendererUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/RenderTimeout"
          }
        }
      }
    },
    "/api/v1/mermaid/render": {
      "post": {
        "operationId": "renderMermaid",
        "summary": "Render source without saving",
        "description": "RENDER. Shared 20 renders/minute/user/process. Required format svg/png/pdf; theme defaults dark. Returns file bytes or JSON error, including 422 syntax diagnostics. No persistence/publication. Filename diagram-render.<format>. Each successful render counts toward the shared monthly API-render allowance (Free: 200; no self-service upgrade currently). Exhaustion returns 403 plan_limit_reached with resetsAt.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "x-required-scopes": [
          "MERMAID_RENDER"
        ],
        "requestBody": {
          "required": true,
          "description": "JSON body, at most 1,048,576 streamed UTF-8 bytes.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderMermaidRequest"
              },
              "example": {
                "source": "flowchart LR\nOrder --> Payment --> Delivery",
                "format": "png",
                "theme": "light"
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/RenderedAsset"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Insufficient key scope or plan_limit_reached. Plan-limit errors include details.resource, details.limit and details.resetsAt for renders.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/RenderFailure"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/RendererUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/RenderTimeout"
          }
        }
      }
    },
    "/api/v1/public/checkpoints/{checkpointId}/export": {
      "parameters": [
        {
          "$ref": "#/components/parameters/CheckpointId"
        }
      ],
      "get": {
        "operationId": "exportPublishedCheckpoint",
        "summary": "Download explicitly published source or rendered files",
        "description": "No authentication. Only format is accepted (default svg); theme/source/revision or other query overrides return 400. Resolves checkpoint on each request using its exact revision/published theme, never the live draft. Missing/deleted checkpoints return 404 before rendering. Republish can change files at the same ID. All anonymous public reads share 60/minute/process until trusted proxy identity is verified; visual exports also share 20 anonymous renders/minute/process with legacy anonymous export.",
        "security": [],
        "x-required-scopes": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/Format"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/Asset"
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/RenderFailure"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/RendererUnavailable"
          },
          "504": {
            "$ref": "#/components/responses/RenderTimeout"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "mdsk_ API key",
        "description": "Create in signed-in /settings/account; shown once. Send plaintext key in Authorization. Scopes apply to the user's diagrams; WRITE includes deletion. Rotate by creating a replacement, updating caller, then revoking old key."
      }
    },
    "parameters": {
      "DiagramId": {
        "name": "diagramId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Id"
        },
        "example": "doc_123"
      },
      "CheckpointId": {
        "name": "checkpointId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Id"
        },
        "example": "cp_123"
      },
      "Format": {
        "name": "format",
        "in": "query",
        "required": false,
        "schema": {
          "$ref": "#/components/schemas/AssetFormat"
        },
        "description": "Defaults to svg. mermaid returns exact raw source without a renderer.",
        "example": "png"
      },
      "Theme": {
        "name": "theme",
        "in": "query",
        "required": false,
        "schema": {
          "$ref": "#/components/schemas/Theme"
        },
        "description": "Defaults to dark; ignored for raw Mermaid. Public files always use the published theme."
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9._:-]{1,128}$"
        },
        "description": "One key per intended creation, scoped to the user across API keys with no expiry before account deletion. Reuse normalized title and exact source after network/retryable failures. Omission permits duplicate creation on retries.",
        "example": "report-2026-10-23-chart-1"
      }
    },
    "headers": {
      "NoStore": {
        "description": "Responses are not cached.",
        "schema": {
          "type": "string",
          "const": "no-store"
        }
      },
      "RetryAfter": {
        "description": "Seconds before retrying; render capacity/unavailability currently uses 1.",
        "schema": {
          "type": "integer",
          "minimum": 1
        },
        "example": 1
      },
      "ContentDisposition": {
        "description": "Raw: attachment; filename=\"diagram-<id>.mmd\". Visual: inline; filename=\"diagram-<id>.<format>\". Public files use checkpoint ID; stateless render uses render.",
        "schema": {
          "type": "string"
        }
      },
      "NoSniff": {
        "schema": {
          "type": "string",
          "const": "nosniff"
        },
        "description": "Disables content-type sniffing."
      },
      "SvgCsp": {
        "description": "Present for SVG only.",
        "schema": {
          "type": "string",
          "const": "sandbox; default-src 'none'; style-src 'unsafe-inline'; img-src data:"
        }
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "400 invalid_json or invalid_request. Correct JSON, fields, ID, name or query/cursor.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "invalid_request",
                "message": "Request payload is invalid.",
                "details": [
                  {
                    "code": "too_small",
                    "path": [
                      "name"
                    ],
                    "message": "Too small: expected string to have >=1 characters"
                  }
                ]
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "401 authentication_required or invalid_api_key. Supply an active bearer key.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "authentication_required",
                "message": "Send an API key as a Bearer token."
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "403 insufficient_scope. Use the required application scopes.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "insufficient_scope",
                "message": "API key is missing DIAGRAMS_READ."
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "404 not_found. Missing/nonowned private resource or revoked/missing public checkpoint; repeated deletes return 404.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "not_found",
                "message": "Document not found."
              }
            }
          }
        }
      },
      "StaleDocument": {
        "description": "409 stale_document. No partial write; re-read and reconcile before retrying.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "stale_document",
                "message": "The document changed. Reload before saving."
              }
            }
          }
        }
      },
      "IdempotencyConflict": {
        "description": "409 idempotency_conflict. Key previously used with a different normalized title or exact source, including after deletion.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "idempotency_conflict",
                "message": "Idempotency key was already used with a different request."
              }
            }
          }
        }
      },
      "IdempotencyDeleted": {
        "description": "410 idempotency_resource_deleted. Matching prior creation was deleted. No resurrection; a new intended creation needs a new key.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "idempotency_resource_deleted",
                "message": "The diagram created by this idempotency key was deleted."
              }
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "413 payload_too_large. Reduce streamed JSON body (1 MiB) or source (50,000 UTF-16 code units).",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "payload_too_large",
                "message": "Request body is too large."
              }
            }
          }
        }
      },
      "RenderFailure": {
        "description": "422 invalid_mermaid (diagnostic in details), render_too_large or unsupported_svg. Correct syntax or simplify/remove unsupported content.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "invalid_mermaid",
                "message": "Mermaid source is invalid.",
                "details": {
                  "stage": "parse",
                  "title": "Line 2: Mermaid syntax error",
                  "summary": "Check the diagram syntax.",
                  "detail": null,
                  "technicalDetail": "Parse error on line 2.",
                  "line": 2,
                  "column": null,
                  "from": 13,
                  "to": 21,
                  "sourceLine": "Order -->",
                  "expectedTokens": [],
                  "foundToken": null
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "429 rate_limited. Wait Retry-After seconds; buckets are process-local.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "rate_limited",
                "message": "Too many requests. Please wait and try again."
              }
            }
          }
        }
      },
      "RendererUnavailable": {
        "description": "503 renderer_busy or renderer_unavailable. Honor Retry-After, then bounded backoff.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "renderer_busy",
                "message": "Renderer is busy. Please retry."
              }
            }
          }
        }
      },
      "RenderTimeout": {
        "description": "504 render_timeout. 20-second deadline elapsed; simplify or use bounded backoff.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "render_timeout",
                "message": "Diagram rendering exceeded its deadline."
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "500 internal_error. Generic failure; use bounded backoff and retain any creation retry key.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "code": "internal_error",
                "message": "Request failed."
              }
            }
          }
        }
      },
      "Diagram": {
        "description": "200 committed or current owned diagram detail.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DiagramResponse"
            },
            "example": {
              "data": {
                "id": "doc_123",
                "title": "Order flow",
                "source": "flowchart LR\nOrder --> Payment --> Delivery",
                "updatedAt": "2026-10-23T14:00:00.000Z",
                "folder": null,
                "publishedCheckpoints": [],
                "currentRevision": {
                  "id": "rev_123",
                  "version": 1
                }
              }
            }
          }
        }
      },
      "Published": {
        "description": "201 saved source/theme published without draft overwrite.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/PublishResponse"
            },
            "example": {
              "data": {
                "checkpoint": {
                  "id": "cp_123",
                  "name": "release",
                  "slug": "release",
                  "updatedAt": "2026-10-23T14:01:01.000Z",
                  "revisionId": "rev_123",
                  "version": 1,
                  "publishedTheme": "light",
                  "publicUrl": "https://app.example/docs/doc_123/published/release",
                  "exports": {
                    "mermaid": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=mermaid",
                    "svg": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=svg",
                    "png": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=png",
                    "pdf": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=pdf"
                  }
                }
              }
            }
          }
        }
      },
      "Deleted": {
        "description": "200 diagram deleted.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/DeleteResponse"
            },
            "example": {
              "data": {
                "ok": true
              }
            }
          }
        }
      },
      "Revoked": {
        "description": "200 publication revoked; summary has no URLs.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/RevokeResponse"
            },
            "example": {
              "data": {
                "ok": true,
                "checkpoint": {
                  "id": "cp_123",
                  "name": "release",
                  "slug": "release",
                  "updatedAt": "2026-10-23T14:01:01.000Z",
                  "revisionId": "rev_123",
                  "version": 1,
                  "publishedTheme": "light"
                }
              }
            }
          }
        }
      },
      "Asset": {
        "description": "200 file bytes for the selected format. Failures use the JSON error envelope.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          },
          "Content-Disposition": {
            "$ref": "#/components/headers/ContentDisposition"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/NoSniff"
          },
          "Content-Security-Policy": {
            "$ref": "#/components/headers/SvgCsp"
          }
        },
        "content": {
          "text/plain; charset=utf-8": {
            "schema": {
              "type": "string"
            },
            "example": "flowchart LR\nOrder --> Payment --> Delivery"
          },
          "image/svg+xml; charset=utf-8": {
            "schema": {
              "type": "string"
            },
            "example": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100\" height=\"50\"><text x=\"5\" y=\"25\">Order</text></svg>"
          },
          "image/png": {
            "schema": {
              "contentMediaType": "image/png",
              "description": "Raw PNG file bytes, not base64 or JSON."
            }
          },
          "application/pdf": {
            "schema": {
              "contentMediaType": "application/pdf",
              "description": "Raw PDF file bytes, not base64 or JSON."
            }
          }
        }
      },
      "RenderedAsset": {
        "description": "200 file bytes for the selected format. Failures use the JSON error envelope.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          },
          "Content-Disposition": {
            "$ref": "#/components/headers/ContentDisposition"
          },
          "X-Content-Type-Options": {
            "$ref": "#/components/headers/NoSniff"
          },
          "Content-Security-Policy": {
            "$ref": "#/components/headers/SvgCsp"
          }
        },
        "content": {
          "image/svg+xml; charset=utf-8": {
            "schema": {
              "type": "string"
            },
            "example": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100\" height=\"50\"><text x=\"5\" y=\"25\">Order</text></svg>"
          },
          "image/png": {
            "schema": {
              "contentMediaType": "image/png",
              "description": "Raw PNG file bytes, not base64 or JSON."
            }
          },
          "application/pdf": {
            "schema": {
              "contentMediaType": "application/pdf",
              "description": "Raw PDF file bytes, not base64 or JSON."
            }
          }
        }
      }
    },
    "schemas": {
      "Id": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[A-Za-z0-9_-]{1,128}$"
      },
      "Theme": {
        "type": "string",
        "enum": [
          "light",
          "dark"
        ],
        "default": "dark"
      },
      "AssetFormat": {
        "type": "string",
        "enum": [
          "mermaid",
          "svg",
          "png",
          "pdf"
        ],
        "default": "svg"
      },
      "RenderFormat": {
        "type": "string",
        "enum": [
          "svg",
          "png",
          "pdf"
        ]
      },
      "SourceInput": {
        "type": "string",
        "minLength": 1,
        "maxLength": 50000,
        "pattern": "\\S",
        "x-maxUtf16CodeUnits": 50000,
        "description": "Exact source, preserving whitespace and line endings. Must contain non-whitespace content. Limit is 50,000 JavaScript UTF-16 code units (supplementary characters count twice); oversize returns 413. Saving does not validate Mermaid syntax.",
        "examples": [
          "flowchart LR\nOrder --> Payment --> Delivery"
        ]
      },
      "TitleInput": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120,
        "description": "Trimmed before validation; 1–120 UTF-16 code units after trimming. Omitted create title becomes Untitled Diagram."
      },
      "ExpectedUpdatedAt": {
        "type": "string",
        "format": "date-time",
        "pattern": "Z$",
        "description": "Optional exact millisecond precondition from data.updatedAt, including title-only and no-op writes. A stale/future token or write race returns 409 stale_document. Omission accepts state read at transaction start; reconcile a conflict before retrying."
      },
      "CreateDiagramRequest": {
        "type": "object",
        "properties": {
          "title": {
            "$ref": "#/components/schemas/TitleInput"
          },
          "source": {
            "$ref": "#/components/schemas/SourceInput"
          }
        },
        "required": [
          "source"
        ],
        "examples": [
          {
            "title": "Order flow",
            "source": "flowchart LR\nOrder --> Payment --> Delivery"
          }
        ]
      },
      "UpdateDiagramRequest": {
        "type": "object",
        "properties": {
          "title": {
            "$ref": "#/components/schemas/TitleInput"
          },
          "source": {
            "$ref": "#/components/schemas/SourceInput"
          },
          "expectedUpdatedAt": {
            "$ref": "#/components/schemas/ExpectedUpdatedAt"
          }
        },
        "required": [],
        "anyOf": [
          {
            "type": "object",
            "properties": {
              "title": {
                "$ref": "#/components/schemas/TitleInput"
              }
            },
            "required": [
              "title"
            ]
          },
          {
            "type": "object",
            "properties": {
              "source": {
                "$ref": "#/components/schemas/SourceInput"
              }
            },
            "required": [
              "source"
            ]
          }
        ],
        "examples": [
          {
            "title": "Updated order flow",
            "source": "flowchart LR\nOrder --> Payment --> Delivery",
            "expectedUpdatedAt": "2026-10-23T14:00:00.000Z"
          }
        ]
      },
      "PublishDiagramRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "1–80 UTF-16 code units after trimming; internal whitespace is collapsed. Must yield a nonempty ASCII letter/number slug after accent normalization. Same slug addresses the same checkpoint."
          },
          "theme": {
            "$ref": "#/components/schemas/Theme"
          },
          "expectedUpdatedAt": {
            "$ref": "#/components/schemas/ExpectedUpdatedAt"
          }
        },
        "required": [
          "name"
        ],
        "examples": [
          {
            "name": "release",
            "theme": "light",
            "expectedUpdatedAt": "2026-10-23T14:00:00.000Z"
          }
        ]
      },
      "ValidateMermaidRequest": {
        "type": "object",
        "properties": {
          "source": {
            "$ref": "#/components/schemas/SourceInput"
          }
        },
        "required": [
          "source"
        ],
        "examples": [
          {
            "source": "flowchart LR\nOrder --> Payment --> Delivery"
          }
        ]
      },
      "RenderMermaidRequest": {
        "type": "object",
        "properties": {
          "source": {
            "$ref": "#/components/schemas/SourceInput"
          },
          "format": {
            "$ref": "#/components/schemas/RenderFormat"
          },
          "theme": {
            "$ref": "#/components/schemas/Theme"
          }
        },
        "required": [
          "source",
          "format"
        ],
        "examples": [
          {
            "source": "flowchart LR\nOrder --> Payment --> Delivery",
            "format": "png",
            "theme": "light"
          }
        ]
      },
      "Folder": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "CheckpointSummary": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "revisionId": {
            "$ref": "#/components/schemas/Id"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "publishedTheme": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "slug",
          "updatedAt",
          "revisionId",
          "version",
          "publishedTheme"
        ],
        "examples": [
          {
            "id": "cp_123",
            "name": "release",
            "slug": "release",
            "updatedAt": "2026-10-23T14:01:01.000Z",
            "revisionId": "rev_123",
            "version": 1,
            "publishedTheme": "light"
          }
        ]
      },
      "PublishedCheckpoint": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CheckpointSummary"
          },
          {
            "type": "object",
            "properties": {
              "publicUrl": {
                "type": "string",
                "format": "uri"
              },
              "exports": {
                "type": "object",
                "properties": {
                  "mermaid": {
                    "type": "string",
                    "format": "uri"
                  },
                  "svg": {
                    "type": "string",
                    "format": "uri"
                  },
                  "png": {
                    "type": "string",
                    "format": "uri"
                  },
                  "pdf": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "mermaid",
                  "svg",
                  "png",
                  "pdf"
                ]
              }
            },
            "required": [
              "publicUrl",
              "exports"
            ]
          }
        ],
        "description": "Public HTML permalink and checkpoint-ID file URLs. Republish changes these files; revocation/recreation leaves old file URLs at 404.",
        "examples": [
          {
            "id": "cp_123",
            "name": "release",
            "slug": "release",
            "updatedAt": "2026-10-23T14:01:01.000Z",
            "revisionId": "rev_123",
            "version": 1,
            "publishedTheme": "light",
            "publicUrl": "https://app.example/docs/doc_123/published/release",
            "exports": {
              "mermaid": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=mermaid",
              "svg": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=svg",
              "png": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=png",
              "pdf": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=pdf"
            }
          }
        ]
      },
      "DiagramSummary": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/Id"
          },
          "title": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Exact saved source; legacy diagrams may exceed current input limits."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "folder": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Folder"
              },
              {
                "type": "null"
              }
            ]
          },
          "publishedCheckpoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublishedCheckpoint"
            }
          }
        },
        "required": [
          "id",
          "title",
          "source",
          "updatedAt",
          "folder",
          "publishedCheckpoints"
        ],
        "examples": [
          {
            "id": "doc_123",
            "title": "Order flow",
            "source": "flowchart LR\nOrder --> Payment --> Delivery",
            "updatedAt": "2026-10-23T14:00:00.000Z",
            "folder": null,
            "publishedCheckpoints": []
          }
        ]
      },
      "DiagramDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DiagramSummary"
          },
          {
            "type": "object",
            "properties": {
              "currentRevision": {
                "type": "object",
                "properties": {
                  "id": {
                    "$ref": "#/components/schemas/Id"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "id",
                  "version"
                ]
              }
            },
            "required": [
              "currentRevision"
            ]
          }
        ],
        "examples": [
          {
            "id": "doc_123",
            "title": "Order flow",
            "source": "flowchart LR\nOrder --> Payment --> Delivery",
            "updatedAt": "2026-10-23T14:00:00.000Z",
            "folder": null,
            "publishedCheckpoints": [],
            "currentRevision": {
              "id": "rev_123",
              "version": 1
            }
          }
        ]
      },
      "DiagramResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/DiagramDetail"
          }
        },
        "required": [
          "data"
        ],
        "examples": [
          {
            "data": {
              "id": "doc_123",
              "title": "Order flow",
              "source": "flowchart LR\nOrder --> Payment --> Delivery",
              "updatedAt": "2026-10-23T14:00:00.000Z",
              "folder": null,
              "publishedCheckpoints": [],
              "currentRevision": {
                "id": "rev_123",
                "version": 1
              }
            }
          }
        ]
      },
      "DiagramListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DiagramSummary"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 1024,
            "description": "Opaque cursor; null ends traversal. Keep the same normalized q."
          }
        },
        "required": [
          "data",
          "nextCursor"
        ],
        "examples": [
          {
            "data": [
              {
                "id": "doc_123",
                "title": "Order flow",
                "source": "flowchart LR\nOrder --> Payment --> Delivery",
                "updatedAt": "2026-10-23T14:00:00.000Z",
                "folder": null,
                "publishedCheckpoints": []
              }
            ],
            "nextCursor": null
          }
        ]
      },
      "PublishResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "checkpoint": {
                "$ref": "#/components/schemas/PublishedCheckpoint"
              }
            },
            "required": [
              "checkpoint"
            ]
          }
        },
        "required": [
          "data"
        ],
        "examples": [
          {
            "data": {
              "checkpoint": {
                "id": "cp_123",
                "name": "release",
                "slug": "release",
                "updatedAt": "2026-10-23T14:01:01.000Z",
                "revisionId": "rev_123",
                "version": 1,
                "publishedTheme": "light",
                "publicUrl": "https://app.example/docs/doc_123/published/release",
                "exports": {
                  "mermaid": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=mermaid",
                  "svg": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=svg",
                  "png": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=png",
                  "pdf": "https://app.example/api/v1/public/checkpoints/cp_123/export?format=pdf"
                }
              }
            }
          }
        ]
      },
      "DeleteResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean",
                "const": true
              }
            },
            "required": [
              "ok"
            ]
          }
        },
        "required": [
          "data"
        ],
        "examples": [
          {
            "data": {
              "ok": true
            }
          }
        ]
      },
      "RevokeResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "ok": {
                "type": "boolean",
                "const": true
              },
              "checkpoint": {
                "$ref": "#/components/schemas/CheckpointSummary"
              }
            },
            "required": [
              "ok",
              "checkpoint"
            ]
          }
        },
        "required": [
          "data"
        ],
        "examples": [
          {
            "data": {
              "ok": true,
              "checkpoint": {
                "id": "cp_123",
                "name": "release",
                "slug": "release",
                "updatedAt": "2026-10-23T14:01:01.000Z",
                "revisionId": "rev_123",
                "version": 1,
                "publishedTheme": "light"
              }
            }
          }
        ]
      },
      "MermaidDiagnostic": {
        "type": "object",
        "properties": {
          "stage": {
            "type": "string",
            "enum": [
              "parse",
              "render"
            ]
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "technicalDetail": {
            "type": "string"
          },
          "line": {
            "type": [
              "integer",
              "null"
            ]
          },
          "column": {
            "type": [
              "integer",
              "null"
            ]
          },
          "from": {
            "type": [
              "integer",
              "null"
            ]
          },
          "to": {
            "type": [
              "integer",
              "null"
            ]
          },
          "sourceLine": {
            "type": [
              "string",
              "null"
            ]
          },
          "expectedTokens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "foundToken": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "stage",
          "title",
          "summary",
          "detail",
          "technicalDetail",
          "line",
          "column",
          "from",
          "to",
          "sourceLine",
          "expectedTokens",
          "foundToken"
        ],
        "examples": [
          {
            "stage": "parse",
            "title": "Line 2: Mermaid syntax error",
            "summary": "Check the diagram syntax.",
            "detail": null,
            "technicalDetail": "Parse error on line 2.",
            "line": 2,
            "column": null,
            "from": 13,
            "to": 21,
            "sourceLine": "Order -->",
            "expectedTokens": [],
            "foundToken": null
          }
        ]
      },
      "ValidationResponse": {
        "type": "object",
        "properties": {
          "data": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "valid": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "valid"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "valid": {
                    "type": "boolean",
                    "const": false
                  },
                  "diagnostic": {
                    "$ref": "#/components/schemas/MermaidDiagnostic"
                  }
                },
                "required": [
                  "valid",
                  "diagnostic"
                ]
              }
            ]
          }
        },
        "required": [
          "data"
        ],
        "examples": [
          {
            "data": {
              "valid": true
            }
          },
          {
            "data": {
              "valid": false,
              "diagnostic": {
                "stage": "parse",
                "title": "Line 2: Mermaid syntax error",
                "summary": "Check the diagram syntax.",
                "detail": null,
                "technicalDetail": "Parse error on line 2.",
                "line": 2,
                "column": null,
                "from": 13,
                "to": 21,
                "sourceLine": "Order -->",
                "expectedTokens": [],
                "foundToken": null
              }
            }
          }
        ]
      },
      "ValidationIssue": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "path": {
            "type": "array",
            "items": {
              "type": [
                "string",
                "number"
              ]
            }
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "path",
          "message"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_json",
                  "invalid_request",
                  "authentication_required",
                  "invalid_api_key",
                  "insufficient_scope",
                  "not_found",
                  "stale_document",
                  "idempotency_conflict",
                  "idempotency_resource_deleted",
                  "payload_too_large",
                  "invalid_mermaid",
                  "render_too_large",
                  "unsupported_svg",
                  "rate_limited",
                  "renderer_busy",
                  "renderer_unavailable",
                  "render_timeout",
                  "internal_error",
                  "plan_limit_reached"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "description": "Optional Mermaid diagnostic object, schema issue array or domain error object.",
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/MermaidDiagnostic"
                  },
                  {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ValidationIssue"
                    }
                  },
                  {
                    "type": "object"
                  }
                ]
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
