Revision External API
REST API for managing architecture documentation in Revision workspaces.
Prerequisites
Before making any API calls, the user must provide two things:
- Organization URL: Each organization has its own subdomain, e.g.
https://acme-company.revision.app/
. This is the base URL for all API requests. Always ask the user for their organization URL — there is no default.
- API key: A Bearer token from the workspace settings.
Authentication
All requests require a Bearer token (API key from workspace settings):
Authorization: Bearer <api-key>
Base URL
The base URL is the organization's own Revision URL. Every organization has a unique subdomain:
https://{organization}.revision.app
For example:
https://acme-company.revision.app
Important: Do not use a generic URL. Always use the organization-specific subdomain provided by the user.
Resources
| Resource | Endpoints | Description |
|---|
| Components | CRUD + batch upsert + filter | Architecture components (services, databases, etc.) |
| Diagrams | CRUD + batch upsert + filter | Architecture diagrams with component instances, relations, textareas |
| Attributes | CRUD + batch upsert | Custom attribute definitions on components |
| Tags | CRUD + batch upsert | Tags for categorizing diagrams |
| Types | Read-only | Component type definitions |
| Template | POST | Bulk sync of components + diagrams in a single transaction |
Quick Start
List components
bash
curl -H "Authorization: Bearer $API_KEY" \
https://acme-company.revision.app/api/external/components
Create a component
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "User Service", "state": "ACTIVE"}' \
https://acme-company.revision.app/api/external/components
Create a component with a predictable ID
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "user-service", "name": "User Service", "state": "ACTIVE"}' \
https://acme-company.revision.app/api/external/components
Update a component
bash
curl -X PATCH -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "User Service", "state": "ACTIVE", "desc": "Handles user auth"}' \
https://acme-company.revision.app/api/external/components/component-id
Standard CRUD Pattern
Every resource (components, diagrams, attributes, tags) follows the same pattern:
| Method | Path | Action |
|---|
| GET | | List all (with optional query filters on components, diagrams, types) |
| POST | | Create (single item) |
| GET | /api/external/{resource}/{id}
| Get by ID |
| PATCH | /api/external/{resource}/{id}
| Update by ID |
| PATCH | /api/external/{resource}/upsert-batch
| Batch upsert (items with are updated, without are created) |
Note: DELETE endpoints exist but are not yet implemented (return 501).
ID behavior: If you provide an
when creating, that exact ID is used (predictable). If you omit
, one is auto-generated. Providing a predictable
is useful when you need to reference the resource elsewhere (e.g. a component's
in a component instance's
).
Create requests accept a single object (not an array). Returns 201 on success.
Batch upsert is the most powerful pattern: send items with
to update, without
to create, all in one request.
Component Schema
json
{
"id": "string",
"name": "string",
"state": "DRAFT | ACTIVE | ARCHIVED",
"desc": "string | null",
"inlineDesc": false,
"typeId": "string | null",
"apiContext": "string",
"attributes": [{ "id": "string", "value": "boolean | number | string | null" }],
"linksTo": ["diagram-id-1", "diagram-id-2"]
}
- : Optional on create — provide it for a predictable ID, omit for auto-generated
- : Optional label to group related imports (defaults to current UTC timestamp if omitted)
- : Array of diagram IDs this component links to
- : Component attribute values (reference attribute definitions by )
Diagram Schema
json
{
"id": "string",
"name": "string",
"state": "DRAFT | ACTIVE | ARCHIVED",
"url": "string",
"desc": "string | null",
"level": "C0 | C1 | C2 | C3 | C4 | D1 | P0 | null",
"tags": ["tag-id-1"],
"apiContext": "string",
"componentInstances": [],
"relations": [],
"textareas": []
}
Diagram Levels
| Level | Meaning |
|---|
| C0 | Landscape |
| C1 | System Context |
| C2 | Container |
| C3 | Component |
| C4 | Code |
| D1 | Deployment |
| P0 | Process |
Component Instances
A
component is part of the architecture model — a reusable entity that can be referenced across many diagrams. A
component instance is a visual placeholder on a diagram. It can optionally link to a component via
, but it doesn't have to — unlinked instances are just standalone placeholders with a name and type.
Two types:
Important:
,
, and
are all optional. When omitted, Revision will automatically lay out and size the instances.
Prefer omitting them unless the user explicitly asks for specific positioning or sizing — auto-layout produces better results.
Non-container (default):
json
{
"ref": "unique-ref",
"componentId": "component-id | null",
"parent": "container-ref",
"isContainer": false,
"placeholder": { "text": "Name", "typeId": "type-id" }
}
Container (groups other instances):
json
{
"ref": "unique-ref",
"componentId": "component-id | null",
"isContainer": true,
"placeholder": { "text": "Name", "typeId": "type-id" }
}
- is required and must be unique within the diagram
- links the instance to a component definition (null for placeholders)
- Non-containers can reference a container via the container's
- Containers cannot have a parent
- , , are optional — omit them to let Revision auto-layout and auto-size
Relations
Directed edges between component instances:
json
{
"fromRef": "instance-ref-1",
"toRef": "instance-ref-2",
"label": "string | null",
"desc": "string | null",
"linksTo": ["diagram-id"]
}
Textareas
Free text on diagrams:
json
{
"position": { "x": 100, "y": 100 },
"width": 300,
"text": "string | null"
}
Attribute Schema
Custom fields on components:
json
{
"id": "string",
"name": "string",
"desc": "string | null",
"type": "STRING | NUMBER | BOOLEAN | LINK | USERLIST | LIST",
"list": ["option1", "option2"],
"forTypes": ["type-id-1"],
"required": false,
"apiContext": "string"
}
- is only valid when is (and required for LIST)
- : Restrict attribute to specific component types
Tag Schema
json
{
"id": "string",
"name": "string",
"desc": "string | null",
"color": "gray | red | orange | yellow | green | blue | purple",
"apiContext": "string"
}
Type Schema (Read-Only)
json
{
"id": "string",
"name": "string"
}
Types are managed in the Revision UI. List via
. Supports optional
query parameter for filtering.
Template Sync
Bulk sync components and diagrams in a single transaction:
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"components": [...], "diagrams": [...]}' \
https://acme-company.revision.app/api/external/template
Accepts both JSON and YAML. Components and diagrams follow their standard schemas.
Filtering & Dependencies
Filtering Components
GET /api/external/components?name=...&typeId=...&tagId=...&attributeId=...&attributeValue=...&state=...
All filters optional.
requires
.
Filtering Diagrams
GET /api/external/diagrams?componentId=...&tagId=...&name=...&level=...&state=...
All filters optional.
Filtering Types
GET /api/external/types?name=...
Component Dependencies
GET /api/external/components/{id}/dependencies
Returns
— upstream and downstream direct dependencies for a component.
Workflow: Create a Diagram with Components
A typical end-to-end flow: search for duplicates, create components, then create a diagram that references them.
-
Search for existing duplicates — MUST do this before creating anything:
- For each component you plan to create, search by name:
GET /api/external/components?name=<name>
- For the diagram, search by name:
GET /api/external/diagrams?name=<name>
- If matches are found → ask the user whether to reuse the existing resource or create a new one
- If the user chooses to reuse → use the existing resource's instead of creating a new one
- If no matches → proceed to create
- Skip ONLY when the user explicitly says "create a new..." or "update the existing..."
-
List types to find the right
values:
bash
curl -H "Authorization: Bearer $API_KEY" \
https://acme-company.revision.app/api/external/types
- Create components (skip any that the user chose to reuse from step 1):
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "user-service", "name": "User Service", "state": "ACTIVE"}' \
https://acme-company.revision.app/api/external/components
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"id": "user-db", "name": "User Database", "state": "ACTIVE"}' \
https://acme-company.revision.app/api/external/components
- Create a diagram with component instances and a relation:
bash
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "User Service Context",
"level": "C2",
"state": "ACTIVE",
"componentInstances": [
{ "ref": "us", "componentId": "user-service" },
{ "ref": "udb", "componentId": "user-db" }
],
"relations": [
{ "fromRef": "us", "toRef": "udb", "label": "Reads/writes" }
]
}' \
https://acme-company.revision.app/api/external/diagrams
- Verify by fetching the diagram back:
bash
curl -H "Authorization: Bearer $API_KEY" \
https://acme-company.revision.app/api/external/diagrams/<returned-id>
For bulk operations, use the template endpoint to sync everything in a single transaction instead.
Output Summary
After every mutation (create, update, batch upsert, or template sync), print a summary that clearly separates what was created from what was updated.
Format:
Created:
- Component "User Service" (id: user-service)
- Diagram "System Context" (id: system-context)
Updated:
- Component "Auth Service" (id: auth-service) — updated name, desc
Rules:
- Use Created for POST (201) responses and batch upsert items that had no provided
- Use Updated for PATCH (200) responses and batch upsert items that had an provided
- Always include the resource type, name, and ID
- For updates, briefly note which fields changed
- Omit a section if it's empty (e.g. don't print "Updated:" if nothing was updated)
Error Responses
All errors return:
json
{ "error": "description" }
| Status | Meaning |
|---|
| 400 | Validation error |
| 401 | Missing or invalid API key |
| 404 | Resource not found |
| 405 | Method not allowed |
| 501 | Not implemented (e.g. DELETE endpoints) |
Error Recovery
When an API call fails:
- 401: Confirm the API key is correct and the Authorization header uses prefix.
- 400: Read the field — it describes the validation issue. Fix the request body and retry.
- 404: Verify the resource ID. Use the list endpoint (
GET /api/external/{resource}
) to confirm the resource exists.
- 501: DELETE is not implemented. Use PATCH to set instead.
Always verify mutations by fetching the resource back after create/update to confirm the change took effect.
Full OpenAPI Spec
For the complete OpenAPI 3.0.3 specification with all request/response schemas, see OPENAPI.md.