ArchTruth / docs / api
ArchTruth API & MCP
Both surfaces expose the same operations and share one implementation. Authenticate with an org-scoped API key created by a workspace owner under Settings · API keys. Keys are hashed at rest and shown once.
Authorization: Bearer as_live_…
| Scope | Allows |
|---|---|
read | list, get, search, render, validate |
write | + create, patch (typed ops), replace (whole DSL) |
Every write creates a version and an audit row attributed to the key (versions.api_key_id, audit_log.api_key_id).
Concurrency
GET /diagrams/{id} returns ETag: "<revision>". Send it back as If-Match on PATCH/PUT; a stale value returns 412 and nothing is written. Omit If-Match for unconditional writes (not recommended for agents).
Rate limits
Per key, per minute: 120 read requests, 30 write requests. Every authenticated /api/v1 response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds); a 429 adds Retry-After. Counters live in api_requests, one row per key and minute, pruned hourly by pg_cron after 24 h.
REST — /api/v1
OpenAPI 3.1: GET /api/v1/openapi (public).
BASE=https://archtruth.app/api/v1
H='Authorization: Bearer as_live_…'
curl -s $BASE/diagrams -H "$H"
curl -s $BASE/diagrams/<id> -H "$H" # → dsl, layout, diagnostics, layers, ETag
curl -s $BASE/diagrams/<id>/render?layer=future -H "$H" # → image/svg+xml
curl -s "$BASE/search?q=checkout" -H "$H"
curl -s $BASE/validate -H "$H" -H 'content-type: application/json' -d '{"dsl":"service a"}'
curl -s $BASE/diagrams -H "$H" -H 'content-type: application/json' \
-d '{"name":"Orders","dsl":"service a \"A\"\nservice b \"B\"\na -> b"}'
curl -s -X PATCH $BASE/diagrams/<id> -H "$H" -H 'If-Match: 3' -H 'content-type: application/json' \
-d '{"ops":[{"op":"addNode","id":"c","kind":"queue","label":"Events"},{"op":"addEdge","from":"b","to":"c"}],"message":"add event bus"}'Ops
addNode {id, kind, label?, parent?, props?, layer?} · removeNode {path, layer?} · setNode {path, label?, kind?, props?, unset?} · moveNode {path, parent} · addEdge {from, to, dir?, label?, props?, layer?} · removeEdge {id, layer?} · setEdge {id, label?, props?, unset?} · setTitle {title} · setDiagramProps {props?, unset?} · addLayer {id, label?} · removeLayer {id} · setLayer {id, label?, props?}
Ops are applied through the CST-preserving printer: untouched lines (comments, spacing, order) stay byte-identical. layer on add/remove ops records the change in that layer (base removals become ! lines).
MCP — /api/mcp (Streamable HTTP)
Tools: list_diagrams, get_diagram, search_diagrams, render_diagram, validate_dsl, create_diagram, patch_diagram, replace_diagram. Same key, same scopes, same 412 semantics (expectedRevision).
Claude Code:
claude mcp add --transport http archtruth https://archtruth.app/api/mcp \ --header "Authorization: Bearer as_live_…"
Cowork / other clients (mcp.json):
{ "mcpServers": { "archtruth": { "url": "https://archtruth.app/api/mcp", "headers": { "Authorization": "Bearer as_live_…" } } } }Suggested agent loop: get_diagram → reason over dsl → patch_diagram with expectedRevision → on 412, re-read and retry.
Share links — /s/<token>
Editors create view-only links from the editor's Share panel (optional expiry, revocable). Anonymous viewers get the rendered diagram with SVG/PNG export — never the DSL, versions or linked CMDB records.
Machine-readable spec: OpenAPI 3.1 JSON · New to the product? Start with the user guide.