[SPECIFICATION]

API Reference

The Archway REST API is namespaced under /api/v1. All endpoints accept and return JSON unless otherwise noted. Base URL: https://archdiagram.dev.

01

AUTHENTICATION

Every /api/v1 endpoint accepts either a session cookie (browser usage) or a Bearer API key. API keys are created from Dashboard → API Keys and are prefixed with ak_. The full key value is shown only once at creation time; only a salted hash is stored server-side.

curl https://archdiagram.dev/api/v1/diagrams \
  -H "Authorization: Bearer ak_..." \
  -H "Content-Type: application/json"

API keys carry one or more permission scopes: read, write, and generate. Mutating endpoints require write; AI-backed endpoints additionally require generate. A request with a missing scope returns 403.

02

RATE_LIMITS

Rate limits are per-user, per-minute, and apply to the union of session and API-key traffic. AI-backed endpoints (any call that accepts a prompt) consume against a separate ai bucket as well as the shared api bucket. When a limit trips, the response is 429 with X-RateLimit-Remaining: 0 and X-RateLimit-Reset (milliseconds).

PLAN
REQ / MIN
free
5
pro
40
team
100
enterprise
500
03

ENDPOINTS

The v1 surface today covers list, read, create, update, AI regeneration, and export. There is no v1 DELETE endpoint — deletions are currently performed through the dashboard UI or via the legacy /api/diagram routes used by the web app itself.

GET/api/v1/diagramsSCOPE: READ

List diagrams owned by the authenticated user, paginated and sorted by most recently updated.

Query parameters:

  • pageINTEGER11-indexed page number.
  • limitINTEGER20Page size, max 100.
  • typeSTRINGFilter by diagramType (cloud-arch, sequence, erd, data-flow, c4, flowchart, network).

200 OK

{
  "diagrams": [
    {
      "id": "65f1...",
      "title": "Checkout flow",
      "diagramType": "cloud-arch",
      "sourceType": "text",
      "tags": [],
      "visibility": "private",
      "createdAt": "2026-04-01T...",
      "updatedAt": "2026-04-12T..."
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 47, "totalPages": 3 }
}
POST/api/v1/diagramsSCOPE: WRITE (AND GENERATE, IF A PROMPT IS SUPPLIED)

Create a new diagram. Either pass dslSource for a deterministic create, or pass prompt to have the AI generate the DSL.

Request body

  • titleSTRINGRequired. Display title.
  • diagramTypeSTRINGcloud-archOne of the seven diagram types.
  • dslSourceSTRING""Raw DSL source. Used directly if provided.
  • promptSTRINGIf set, calls the AI generator. Counts against AI credits.
  • preferredProviderSTRINGOptional AI provider hint passed to the generator.
  • projectIdSTRINGProject to attach to. Falls back to the user's first project if omitted.

201 Created

{
  "id": "65f1...",
  "title": "Checkout flow",
  "diagramType": "cloud-arch",
  "dslSource": "diagram \"Checkout flow\" { ... }",
  "createdAt": "2026-04-14T..."
}

Errors

  • 400title missing or no project exists for the user
  • 403API key lacks write or generate scope
  • 429AI credit limit reached, or rate limit exceeded
GET/api/v1/diagrams/[id]SCOPE: READ

Fetch a single diagram, including the full DSL source and metadata.

200 OK

{
  "id": "65f1...",
  "title": "Checkout flow",
  "diagramType": "cloud-arch",
  "dslSource": "diagram \"...\" { ... }",
  "metadata": {
    "nodeCount": 14,
    "sourceType": "text",
    "lastAiModel": "claude-sonnet-4-5",
    "tags": []
  },
  "sharing": { "visibility": "private", "allowEmbed": false },
  "isFavorite": false,
  "createdAt": "...",
  "updatedAt": "..."
}

Errors

  • 404No diagram with that id owned by the caller
PATCH/api/v1/diagrams/[id]SCOPE: WRITE

Update a diagram. Only title, dslSource, and diagramType are accepted; other fields in the body are ignored.

Request body

  • titleSTRINGOptional new title.
  • dslSourceSTRINGOptional replacement DSL.
  • diagramTypeSTRINGOptional diagram-type change.

200 OK

{
  "id": "65f1...",
  "title": "Checkout flow v2",
  "diagramType": "cloud-arch",
  "dslSource": "diagram \"...\" { ... }",
  "updatedAt": "..."
}

Errors

  • 400No allowed fields were provided
  • 403API key lacks write scope
  • 404Diagram not found
POST/api/v1/diagrams/[id]/generateSCOPE: GENERATE

Regenerate the DSL of an existing diagram from a natural-language prompt. Replaces dslSource on success.

Request body

  • promptSTRINGRequired. Description of what the diagram should look like.
  • diagramTypeSTRING(diagram's current type)Optional override.
  • preferredProviderSTRINGOptional AI provider hint.

200 OK

{
  "id": "65f1...",
  "dsl": "diagram \"...\" { ... }",
  "diagramType": "cloud-arch",
  "description": "Short summary of the generated diagram",
  "model": "claude-sonnet-4-5",
  "retries": 0
}

Errors

  • 400prompt missing
  • 403API key lacks generate scope
  • 404Diagram not found
  • 429Rate limit or AI credit cap reached
  • 503AI service is not configured on the server
GET/api/v1/diagrams/[id]/exportSCOPE: READ

Export the diagram source. Today this returns the raw Archway DSL for text formats; mermaid/plantuml/d2 transpilation is not yet implemented and returns the same DSL with the matching file extension.

Query parameters:

  • formatSTRINGdslOne of: dsl, json, mermaid, plantuml, d2.

For format=json, the response is the full diagram document (id, title, diagramType, dslSource, metadata, timestamps). For all other formats, the response is a text/plain body containing the DSL source with a Content-Disposition: attachment header. Two extra response headers are set: X-Diagram-Type and X-Export-Format.

Errors

  • 400Unsupported format value
  • 404Diagram not found
04

API_KEY_MANAGEMENT

The endpoints under /api/keys are not part of v1 and are session-only (cookie auth). They power the dashboard UI: GET /api/keys lists the user's keys (without secrets), POST /api/keys issues a new key (returning the raw value exactly once, capped at 10 active keys per user), and DELETE /api/keys/[id] revokes a key by flipping isActive to false. Both creation and revocation emit security audit events.

05

ERROR_FORMAT

All error responses share the same envelope. Status codes follow standard HTTP semantics.

{
  "error": "Diagram not found"
}

Validation failures may include an additional details field with field-level information.