YOUR IDEAS. YOUR WORKFLOW.

Presentations,
programmable.

Create with Markdown. Collaborate through versions.
Bring the same workspace to your people, tools, and agents.

BASE PATH/api/v1AUTHENTICATIONBearer token / browser sessionFORMATJSON + multipart uploads

01 / DEVELOPER GUIDE

From the first request to a complete workflow.

Read as Markdown ↗

web-slides API guide

Create Markdown slide decks, preserve their revision history, generate images, and download PDF, PowerPoint, individual-slide PNG, or all-slide PNG ZIP files through the same authenticated API used by the application. Every resource operation described here supports a web-slides Bearer API token, including asset and export downloads, provider connection management, and token management. Google sign-in bootstraps an account and its first token; subsequent automation does not need browser cookies.

This guide describes the implemented /api/v1 API. Use the deployed service's OpenAPI schema for machine-readable request schemas. Examples use fabricated UUIDs, synthetic timestamps, and placeholders; they do not identify real users or resources. Catalog activation, provider capabilities, and deployment-configurable limits can change. Read their current API responses before submitting work.

Machine-readable discovery

The public /llms.txt links to this guide and /openapi.json. /llms-full.txt serves the complete current guide as plain text. /sitemap.xml lists only public informational pages. /robots.txt discourages crawling private application paths and shared-file URLs; these responses also carry X-Robots-Tag: noindex. Crawler directives are guidance, not access control: private API routes still require authentication, and no user documents or tokens appear in discovery files.

Contents

Authentication and the first token

Two different credentials

Credential Purpose Where it belongs
web-slides token, beginning wst_ Authenticate to this service as the issuing user Authorization: Bearer <web-slides-token>
OpenRouter API key Pay for and authorize image generation upstream The api_key body field when creating or replacing a connection

Do not put an OpenRouter key in the web-slides Authorization header. A web-slides token is not an OpenRouter credential. The connection API encrypts the provider key and returns only masked connection metadata. An agent uses a connection UUID for generation; generation responses never contain the provider key.

GET /api/v1/me HTTP/1.1
Authorization: Bearer wst_REPLACE_WITH_YOUR_SERVICE_TOKEN

Use HTTPS for remote services. Plain HTTP is appropriate only for local development on loopback. Do not put a token in a query string, Markdown, a generation prompt, a URL, or an idempotency key. Bearer clients need no CSRF header or session cookie. An invalid Authorization header returns 401 even if the request also contains a valid browser cookie; there is no cookie fallback.

Bootstrap through Google sign-in

  1. Visit /auth/google/login in a browser and complete Google sign-in.
  2. The callback creates or finds your account and establishes an HttpOnly ws_session cookie.
  3. Call GET /api/v1/me in that signed-in browser to obtain the session's csrf_token.
  4. Call POST /api/v1/tokens with that cookie and the X-CSRF-Token header.
  5. Save the returned token immediately in a private file or secret store. It is returned only once.

There is no anonymous endpoint that issues a service token, and the API does not accept a Google access token as its Bearer credential. The OAuth callback verifies the identity before creating the application session.

The following same-origin browser JavaScript demonstrates the two API calls after sign-in:

const identityResponse = await fetch('/api/v1/me', {credentials: 'same-origin'});
if (!identityResponse.ok) throw new Error('Sign in first');
const identity = await identityResponse.json();
const tokenResponse = await fetch('/api/v1/tokens', {
  method: 'POST',
  credentials: 'same-origin',
  headers: {'Content-Type': 'application/json', 'X-CSRF-Token': identity.csrf_token},
  body: JSON.stringify({name: 'My automation'})
});
if (!tokenResponse.ok) throw new Error('Token creation failed');
const issuedCredential = await tokenResponse.json();
// Securely save issuedCredential.token. Do not log the response or share it.

Identity response

GET /api/v1/me returns 200:

{
  "id": "11111111-1111-4111-8111-111111111111",
  "email": "example@example.invalid",
  "name": "Example User",
  "actor_type": "agent",
  "csrf_token": null
}

Bearer authentication sets actor_type to agent; session authentication sets it to human and returns a CSRF token. In revision records, an agent's actor_id is the service-token UUID, not its secret value. For human edits, actor_id is the user's UUID.

Token endpoints

Method and path Request Success
POST /api/v1/tokens {"name":"My automation"}; name is 1–100 characters 201; token metadata plus the one-time token
GET /api/v1/tokens No body 200; metadata array, newest first, including revoked tokens
DELETE /api/v1/tokens/{token_id} No body 200; {"id":"...","revoked":true}

Creation response, with deliberately fake credential text:

{
  "id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
  "name": "My automation",
  "prefix": "wst_EXAMPLE_",
  "created_at": "2026-01-01T00:00:00Z",
  "last_used_at": null,
  "revoked_at": null,
  "token": "wst_EXAMPLE_ONLY_REPLACE_ME"
}

The list endpoint returns these fields except token. The server stores a hash of the service token; it cannot return the original later. There is a maximum of 30 active tokens per account; another creation returns 409. A Bearer token can create and revoke tokens within its account, including itself. Revocation is idempotent for an existing owned token; later authenticated requests using it return 401.

Browser CSRF and logout

Cookie-authenticated API writes require X-CSRF-Token from /api/v1/me. This applies to POST, PATCH, DELETE, and other methods except GET, HEAD, and OPTIONS. When an Origin header is present, it must match the configured application origin. Missing or invalid CSRF values and an incorrect Origin return 403.

POST /auth/logout is a separate browser-session endpoint: send the CSRF value as a form field named csrf, not as the API header. Successful logout redirects with 303 and removes the session. It does not revoke separately issued service tokens. The default browser-session lifetime is 24 hours, configurable by the deployment.

Conventions and errors

URLs, identifiers, and data types

  • Prefix resource paths with the service origin, https://webslides.parklab.work, or your own deployment's origin.
  • Resource IDs are opaque UUID strings. A revision ID, asset ID, asset-version ID, and job ID are different identifiers.
  • JSON is UTF-8. Korean and other Unicode Markdown text is supported.
  • Timestamps are ISO 8601 date-time strings; nullable timestamps are JSON null until set.
  • JSON endpoints use Content-Type: application/json. Asset uploads use multipart form data.
  • Collection responses are plain arrays, not {items: ...} envelopes.
  • Do not send owner or actor fields to create resources; authentication determines them.
  • Content request models reject unknown fields. Do not rely on other request models accepting extra fields.

The following fabricated IDs recur in examples:

Resource Example UUID
Project 22222222-2222-4222-8222-222222222222
Deck 33333333-3333-4333-8333-333333333333
Revision 44444444-4444-4444-8444-444444444441
Branch 55555555-5555-4555-8555-555555555555
Asset 66666666-6666-4666-8666-666666666666
Asset version 77777777-7777-4777-8777-777777777777
Issue 88888888-8888-4888-8888-888888888888
Job 99999999-9999-4999-8999-999999999999
OpenRouter connection aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa

HTTP status codes

Status Meaning and client action
200 Successful read, update, archive, revoke, or binary download
201 Created a resource or appended a revision, including restore and merge
202 A job was accepted or an existing job was returned; inspect its actual status
400 Examples include failed OAuth verification or an invalid request host
401 Missing, invalid, or revoked service token; missing or expired browser session
403 Browser CSRF or Origin check failed
404 Resource missing, owned by another account, or incompatible with the requested parent resource
409 Version/revision conflict, merge conflict, incompatible idempotency key, quota conflict, inactive connection/model, unavailable snapshot, or download not ready
422 Invalid fields, unsupported options, rejected Markdown/image, or invalid asset references
429 Account request limit, pending-job limit, daily generation limit, or preview contention
503 A required service component is unavailable; see the affected endpoint

Worker failures are different from HTTP request failures. A job GET usually returns 200 even when its body has "status":"failed". Provider errors, missing installed fonts, insufficient worker disk space, and renderer failures are reported through job.error after execution. Do not expect a provider's upstream HTTP status to become the status of the job GET response.

Error bodies

Most request errors have a string detail. Conflict endpoints may use an object:

{
  "detail": {
    "code": "version_conflict",
    "message": "The head changed; read the current version before retrying",
    "current_version_id": "44444444-4444-4444-8444-444444444442"
  }
}

Schema-validation errors use a detail array containing loc, type, and msg. The application suppresses the submitted input from these validation responses. Many deployed messages are Korean; do not branch application logic on translated prose. Use the HTTP status and structured code when available. There is no universal machine-readable code for every error.

Endpoint index

All paths below require an authenticated owner except the public service-information endpoints listed afterward.

Area Methods and paths
Identity GET /api/v1/me
Tokens GET, POST /api/v1/tokens; DELETE /api/v1/tokens/{token_id}
Projects GET, POST /api/v1/projects; GET, PATCH, DELETE /api/v1/projects/{project_id}
Project gallery GET /api/v1/gallery; POST /api/v1/gallery/projects/{project_id}/thumbnails; GET /api/v1/gallery/thumbnails/{job_id}/{slide_number}
Decks GET, POST /api/v1/decks; GET, PATCH, DELETE /api/v1/decks/{deck_id}
Revisions GET, POST /api/v1/decks/{deck_id}/versions; GET /api/v1/decks/{deck_id}/versions/{version_id}
History operations GET /api/v1/decks/{deck_id}/diff; POST /api/v1/decks/{deck_id}/restore
Branches GET, POST /api/v1/decks/{deck_id}/branches; POST /api/v1/decks/{deck_id}/merge
Assets GET /api/v1/assets; POST /api/v1/assets/upload; GET /api/v1/assets/{asset_id}
Asset versions GET /api/v1/assets/{asset_id}/versions/{version_id} and the same path plus /download
Shared image library GET /api/v1/library/images, /library/categories, /library/tags; GET /library/images/{image_id}, /library/images/{image_id}/versions, /library/images/{image_id}/versions/{version_id} and the version path plus /download
Preview POST /api/v1/preview
Export jobs POST /api/v1/decks/{deck_id}/exports; GET /api/v1/exports/{job_id} and the same path plus /download
Public-link management POST /api/v1/exports/{job_id}/public-links; GET /api/v1/public-links; GET, DELETE /api/v1/public-links/{link_id}
Job management GET /api/v1/jobs; POST /api/v1/jobs/{job_id}/retry
Provider connections GET, POST /api/v1/connections; PATCH, DELETE /api/v1/connections/{connection_id}; POST /api/v1/connections/{connection_id}/verify
Catalogs GET /api/v1/fonts; GET /api/v1/models; GET /api/v1/diagrams/catalog
Generation jobs POST /api/v1/image-generations; GET /api/v1/image-generations/{job_id}
Issues GET, POST /api/v1/projects/{project_id}/issues; GET, PATCH, DELETE /api/v1/issues/{issue_id}
Audit GET /api/v1/audit

Public GET /healthz returns {"status":"ok"}. Public GET /readyz returns {"status":"ready","database":"ok"} or a 503 not-ready response. Readiness checks database access, not successful execution of an export or image-generation job. Public GET /api/v1/version returns service, version, git_sha, environment, and google_oauth_configured. The browser OAuth routes are /auth/google/login, /auth/google/callback, and /auth/logout. Explicitly published PDF/PPTX files also support anonymous GET/HEAD /s/{token}/download.

Projects

A project groups decks and provides one issue collection. It is account-owned, not a shared-team permission boundary.

Create and read

POST /api/v1/projects accepts:

Field Required Type and default
name Yes Nonblank string, 1–255 characters; surrounding whitespace is trimmed
description No String up to 20,000 characters; default ""
{"name":"Quarterly review","description":"Slides and preparation tasks"}

201 response:

{
  "id":"22222222-2222-4222-8222-222222222222",
  "owner_id":"11111111-1111-4111-8111-111111111111",
  "name":"Quarterly review",
  "description":"Slides and preparation tasks",
  "archived":false,
  "created_at":"2026-01-01T00:00:00Z",
  "updated_at":"2026-01-01T00:00:00Z"
}

GET /api/v1/projects returns nonarchived projects, oldest first. Add ?include_archived=true to include archived records. GET /api/v1/projects/{project_id} returns the same object, including when archived.

Update and archive

PATCH /api/v1/projects/{project_id} accepts any of name, description, and archived; explicit null values are rejected. It returns the updated project with 200. There is no project revision precondition field. DELETE /api/v1/projects/{project_id} archives it and returns the project with archived:true and 200. Restore its visibility with PATCH and {"archived":false}. Archiving a project does not recursively archive its decks or issues and does not erase their history.

The studio opens on a project gallery. All gallery endpoints require a session or Bearer token and return only the current account's projects and export artifacts.

GET /api/v1/gallery?sort=updated_desc returns {"items": [...], "sort": "updated_desc", "total": 3}. Unlike /projects, this response is an object, not a bare array. Available sort keys:

Key Order
updated_desc (default) Latest project or active-document edit first
name_asc Case-insensitive project name ascending
created_desc Most recently created project first
slides_desc Total slides across active documents, descending
slides_asc Total slides across active documents, ascending

Each item includes project_id, name, description, created_at, updated_at, deck_count, slide_count, representative_deck, and thumbnail. Archived projects/documents are omitted. Ties are deterministic by name and project ID. The representative is the most recently edited active document. Its preview shows the cover and three evenly distributed pages through the last page. Documents with four or fewer slides show each page once. These are positional samples, not an AI ranking of slide importance. Empty projects have representative_deck: null.

thumbnail contains status, job_id, and slides: [{"number": 1, "url": "..."}]. States are empty, missing, queued, running, succeeded, or failed. GET /gallery does not start rendering. To prepare images, send POST /api/v1/gallery/projects/{project_id}/thumbnails with no body; the 202 response contains job_id, status, deck_id, version_id, and slide_numbers. Poll the gallery or GET /api/v1/exports/{job_id} until the job succeeds. Preparation reuses an exact-revision, default-font PNG ZIP export and the normal worker quotas. Empty projects return 409; capacity limits return 429. Failed jobs are not automatically retried; an explicit preparation request can start another attempt. No paid image-generation model is called.

GET /api/v1/gallery/thumbnails/{job_id}/{slide_number} returns an authenticated PNG, at most 640×480 pixels, with X-Content-SHA256. Foreign artifacts and nonexistent slides return 404; unfinished or corrupt artifacts return 409. A new document revision uses new thumbnails; old revision artifacts are never silently replaced. The studio prepares visible missing thumbnails one job at a time and stops polling when you leave the gallery. API clients can use the same three endpoints.

Decks

Create a deck

POST /api/v1/decks returns 201 and immediately creates the first revision, even when Markdown is empty.

Field Required Type and default
name Yes Nonblank string, 1–255 characters
description No String, maximum 20,000; default ""
project_id No Owned project UUID or null; default null
markdown No String, maximum 200,000 characters; default ""
message No String, maximum 10,000; default "Initial version"
asset_versions No Map of asset UUID to asset-version UUID; default null
{
  "name":"Quarterly review",
  "project_id":"22222222-2222-4222-8222-222222222222",
  "markdown":"# Quarterly review\n\nOpening slide.\n\n---\n\n# Results\n\nDetails.\n",
  "message":"Initial draft"
}

Deck response, with empty asset references and an abbreviated font array for readability:

{
  "id":"33333333-3333-4333-8333-333333333333",
  "owner_id":"11111111-1111-4111-8111-111111111111",
  "project_id":"22222222-2222-4222-8222-222222222222",
  "name":"Quarterly review",
  "description":"",
  "current_version_id":"44444444-4444-4444-8444-444444444441",
  "archived":false,
  "created_at":"2026-01-01T00:00:00Z",
  "updated_at":"2026-01-01T00:00:00Z",
  "markdown":"# Quarterly review\n\nOpening slide.\n\n---\n\n# Results\n\nDetails.\n",
  "asset_versions":{},
  "font_versions":[],
  "renderer_version":"web-slides-v1/marp-4.4.0/mermaid-12.1.0"
}

Actual saved revisions contain the installed font manifest in font_versions; do not submit the abbreviated example as a snapshot. markdown, asset_versions, font_versions, and renderer_version in a deck response describe its current main revision.

List and retrieve

GET /api/v1/decks returns deck objects, including current Markdown, oldest first. Use ?project_id=<project UUID> to filter by an owned project and ?include_archived=true to include archived decks. GET /api/v1/decks/{deck_id} returns one deck, including an archived deck. There are no page or cursor parameters on these collection endpoints.

Update metadata or Markdown

PATCH /api/v1/decks/{deck_id} requires expected_version_id. Optional fields are name, description, project_id, archived, markdown, message, and asset_versions. The limits match creation; message defaults to "Update document". Omitted Markdown is copied from the current revision. Send project_id:null to detach a deck from a project. Explicit null values for fields such as name, description, markdown, and archived are rejected.

{
  "expected_version_id":"44444444-4444-4444-8444-444444444441",
  "name":"Quarterly review — approved",
  "message":"Rename after review"
}

Success returns a deck object with 200 and a new current_version_id. Even a metadata-only PATCH appends a revision, so other editors' old preconditions become stale. Deck name, description, project membership, and archive status are mutable deck metadata; revision history does not snapshot those fields.

Archive without deleting history

DELETE /api/v1/decks/33333333-3333-4333-8333-333333333333?expected_version_id=44444444-4444-4444-8444-444444444442
Authorization: Bearer wst_REPLACE_WITH_YOUR_SERVICE_TOKEN

The precondition is a query parameter on DELETE, not a JSON body. Success is 200 with a deck object, archived:true, and another appended revision. Unarchive with PATCH, the latest expected_version_id, and {"archived":false}. Archive status controls default listing; historical revision reads remain available.

Revisions and optimistic concurrency

Append a revision

POST /api/v1/decks/{deck_id}/versions requires both expected_version_id and markdown. It accepts message (default ""), branch_id (default null), and asset_versions (default null). Markdown is limited to 200,000 characters; message is limited to 10,000. The request field is expected_version_id, not parent_id.

{
  "expected_version_id":"44444444-4444-4444-8444-444444444441",
  "markdown":"# Quarterly review\n\nRevised opening.\n",
  "message":"Clarify the opening slide"
}

201 response:

{
  "id":"44444444-4444-4444-8444-444444444442",
  "deck_id":"33333333-3333-4333-8333-333333333333",
  "parent_id":"44444444-4444-4444-8444-444444444441",
  "merge_parent_id":null,
  "markdown":"# Quarterly review\n\nRevised opening.\n",
  "message":"Clarify the opening slide",
  "actor_type":"agent",
  "actor_id":"bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
  "created_at":"2026-01-01T00:01:00Z",
  "renderer_version":"web-slides-v1/marp-4.4.0/mermaid-12.1.0",
  "asset_versions":{},
  "font_versions":[]
}

The example abbreviates font_versions as above. The response is a revision, not a deck: use its id as the next head. Without branch_id, success advances the deck's main current_version_id. With branch_id, it advances only that branch's head_version_id. The server locks the deck and compares the relevant head before saving; a stale head returns 409 without appending a revision. On conflict, fetch the current content, reconcile your changes, and explicitly submit against the new head. Blindly replacing the expected ID while retaining stale Markdown can overwrite changes at the application level.

Read the immutable history

GET /api/v1/decks/{deck_id}/versions returns all revision metadata, newest first, across main and branches. Each object has the revision fields above except markdown. GET /api/v1/decks/{deck_id}/versions/{version_id} includes Markdown. A version UUID from another deck returns 404, even if you own that other deck. There is no API for updating or deleting a historical revision in place.

Diff two revisions

GET /api/v1/decks/33333333-3333-4333-8333-333333333333/diff?from_version_id=44444444-4444-4444-8444-444444444441&to_version_id=44444444-4444-4444-8444-444444444442

Both query parameters are required. The 200 response is {"diff":"..."} containing unified Markdown diff text. Diff labels are revision IDs. Missing final newlines are represented with the usual No newline at end of file marker. This endpoint compares Markdown only: changes exclusively to asset-version pins or font metadata need inspection of the revision objects.

Restore a historical snapshot

POST /api/v1/decks/{deck_id}/restore:

{
  "expected_version_id":"44444444-4444-4444-8444-444444444442",
  "version_id":"44444444-4444-4444-8444-444444444441",
  "message":"Restore the original draft"
}

message is optional and defaults to "Restore version". Success returns a new revision with 201 and advances main; it does not move main backward to the old UUID. Its parent_id is the previously current head. The restored Markdown, asset pins, font snapshot, and renderer version come from the selected historical revision. The new record has the restoring actor and a new timestamp. Current validation and asset ownership checks still run. Restoring content does not restore historical deck names, descriptions, project membership, or archive status.

Branches and three-way merging

Main is represented by deck.current_version_id; it is not an automatically created branch-list record. An omitted target_branch_id means main. Do not invent a branch named main to address the main head.

Create, list, and edit a branch

POST /api/v1/decks/{deck_id}/branches requires name and from_version_id:

{"name":"agent-review","from_version_id":"44444444-4444-4444-8444-444444444441"}

201 response:

{
  "id":"55555555-5555-4555-8555-555555555555",
  "deck_id":"33333333-3333-4333-8333-333333333333",
  "name":"agent-review",
  "head_version_id":"44444444-4444-4444-8444-444444444441",
  "created_at":"2026-01-01T00:02:00Z"
}

Names are nonblank, at most 255 characters, and unique within a deck; a duplicate returns 409. GET /api/v1/decks/{deck_id}/branches returns branch objects oldest first. There are currently no branch rename or delete endpoints. To edit, call the normal versions POST with branch_id and that branch's current head:

{
  "branch_id":"55555555-5555-4555-8555-555555555555",
  "expected_version_id":"44444444-4444-4444-8444-444444444441",
  "markdown":"# Quarterly review\n\nBranch proposal.\n",
  "message":"Propose a new opening"
}

Merge a branch

POST /api/v1/decks/{deck_id}/merge accepts:

Field Required Meaning
source_branch_id Yes Owned branch within this deck
target_branch_id No Target branch UUID; null or omitted targets main
expected_version_id Yes Current target head, not the source head
message No Up to 10,000 characters; default "Merge branch"
markdown No Complete manually resolved Markdown, up to 200,000 characters
asset_versions No Explicit asset-version resolutions
{
  "source_branch_id":"55555555-5555-4555-8555-555555555555",
  "expected_version_id":"44444444-4444-4444-8444-444444444442",
  "message":"Merge reviewed changes"
}

The server finds a common ancestor by following both parent links and performs a three-way text merge. Success returns a new revision with 201: parent_id is the old target head and merge_parent_id is the source head. Only the target head advances; the source branch remains unchanged. The same source and target branch returns 422. No common ancestor or multiple best common ancestors returns 409. An ambiguous-base response is not an automatic recursive merge; reorganize the branch history around one shared base before retrying.

Resolve a conflict explicitly

A conflicting merge returns 409 and does not append a revision or advance a head:

{
  "detail": {
    "code":"merge_conflict",
    "markdown":"<<<<<<< target\nTarget text\n||||||| base\nOriginal text\n=======\nSource text\n>>>>>>> source\n",
    "conflict_markdown":"<<<<<<< target\nTarget text\n||||||| base\nOriginal text\n=======\nSource text\n>>>>>>> source\n",
    "asset_conflicts":{},
    "base_version_id":"44444444-4444-4444-8444-444444444441",
    "current_version_id":"44444444-4444-4444-8444-444444444442",
    "source_version_id":"44444444-4444-4444-8444-444444444443",
    "message":"Resolve Markdown and asset versions, then retry with the current head"
  }
}

Submit the complete resolved document, not a patch or only the conflicted lines:

{
  "source_branch_id":"55555555-5555-4555-8555-555555555555",
  "expected_version_id":"44444444-4444-4444-8444-444444444442",
  "markdown":"# Quarterly review\n\nAgreed wording from both edits.\n",
  "message":"Resolve opening-slide conflict"
}

Unresolved conflict-marker lines are rejected with 422. If both sides selected different versions of the same image, asset_conflicts maps each asset ID to {base,target,source} version IDs. Resolve those entries with asset_versions:{"<asset UUID>":"<chosen owned version UUID>"}. Manual Markdown alone cannot resolve an asset-version disagreement for a retained reference. The source branch head is read at merge time; there is no expected_source_version_id field. If the source branch is still changing, coordinate that activity before submitting a manual resolution.

Image assets and frozen references

Upload a new asset or append an image version

POST /api/v1/assets/upload accepts multipart form data and returns 201.

Part Required Meaning
file Yes PNG, JPEG, WebP, or the static SVG subset below
name No At most 200 characters; default "Image"
asset_id No Existing owned asset UUID; omit to create a new logical asset

The example uses the authenticated ws curl helper defined in the complete curl workflow:

ws "$WS_BASE/api/v1/assets/upload" \
  -F 'name=Revenue chart' -F 'file=@chart.png;type=image/png'

To add a new version of the same asset, add -F 'asset_id=66666666-6666-4666-8666-666666666666'. Do not set the multipart Content-Type manually; curl supplies its boundary. New versions update the asset's current_version_id; previous versions remain available. The name form field names a newly created asset; uploading a version does not rename the existing asset.

Raster images are decoded, stripped of metadata/animation, converted to RGB or RGBA, and saved as PNG. Raster limits are 12 MiB for input and normalized output and 16,777,216 pixels (4096 × 4096). Static SVG retains its separate 10 MiB limit below. The returned hash describes the normalized stored PNG, not necessarily your original JPEG/WebP bytes. Unsupported or malformed image files return 422.

Static vector assets

Use the same upload/version/download endpoints with file=@diagram.svg;type=image/svg+xml. Vectors remain SVG in storage and preview; exports render them through the same offline browser. They use the same owner checks, storage quota, immutable versions and asset:// references as raster assets. The returned hash is of the normalized stored SVG, not the original upload. SVG downloads use an .svg attachment filename, nosniff and a restrictive sandbox CSP.

This is deliberately not general-purpose SVG support. The accepted subset is:

  • A root <svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720">. Width and height are integers from 1 to 4096; the optional viewBox must exactly match 0 0 width height.
  • <path> geometry. d supports absolute M, L, C, Z commands and decimal numbers (no exponent notation), with correct coordinate counts. Coordinates must be within ±1,000,000.
  • fill and stroke: six-digit hex colors or none. Separate opacity, fill-opacity and stroke-opacity are in 0–1. stroke-width is 0–4096; stroke-miterlimit is 1–1000.
  • fill-rule: nonzero or evenodd; stroke-linecap: butt, round, square; stroke-linejoin: miter, round, bevel; stroke-dasharray: 1–32 numbers in 0–4096.
  • At most 25,000 paths, 300,000 total command segments, and 10 MiB before and after normalization. Coordinates are normalized to five decimal places. Existing per-document image limits still apply.
  • An optional first <defs> child may contain linearGradient, radialGradient and clipPath. IDs use [A-Za-z][A-Za-z0-9_-]{0,39}, must be unique, and must exist with the correct type. Only fill="url(#gradientId)" and clip-only <g clip-path="url(#clipId)"> references are allowed.
  • Gradients require gradientUnits="userSpaceOnUse". Linear coordinates are x1,y1,x2,y2 (distinct endpoints); radial coordinates are cx,cy,r,fx,fy with positive r, zero inner radius (fr="0") and focus strictly inside the outer circle. Coordinate transforms are not supported. Only spreadMethod="pad" and color-interpolation="sRGB" are accepted; both are defaults.
  • Each gradient has 2–2048 <stop offset="0.5" stop-color="#123456" /> children. Offsets are decimal fractions in nondecreasing order from 0 to 1 (not percentages), including both endpoints. Equal adjacent offsets are allowed; stop opacity is not supported.
  • Each clipPath requires clipPathUnits="userSpaceOnUse" and exactly one compound <path> with d and optional clip-rule="nonzero" or "evenodd". Open subpaths close for clipping. Nested clip-only groups intersect their clip regions; they cannot carry styles or transforms.
  • Additional limits: 512 definitions, 50,000 total stops, 4096 groups, group depth 8, and 80,000 XML elements. Clip paths count toward the same path/segment budgets.

Scripts, event handlers, external URLs, href/template references, CSS, unrestricted groups, transforms, text, raster images, fonts, patterns, masks, XML declarations/DTDs/entity declarations/comments and all unlisted attributes/elements are rejected. Keep text editable in Markdown/HTML alongside the vector geometry. These assets are not accepted as OpenRouter image-generation references; use a raster reference for that operation.

<svg xmlns="http://www.w3.org/2000/svg" width="320" height="180" viewBox="0 0 320 180">
  <path d="M 20 20 L 300 20 L 300 160 L 20 160 Z" fill="#087f83" />
  <path d="M 40 90 C 100 20 220 160 280 90" fill="none" stroke="#ffffff" stroke-width="4" />
</svg>

An internal gradient example (upload this SVG, then reference its immutable asset version):

<svg xmlns="http://www.w3.org/2000/svg" width="320" height="180">
  <defs>
    <linearGradient id="wash" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="320" y2="0">
      <stop offset="0" stop-color="#087f83" />
      <stop offset="0.5" stop-color="#a3e4d7" />
      <stop offset="1" stop-color="#ffffff" />
    </linearGradient>
  </defs>
  <path d="M 0 0 L 320 0 L 320 180 L 0 180 Z" fill="url(#wash)" />
</svg>

Gradient/clip assets preserve static appearance, not editable text semantics. A glyph converted to path outlines remains non-editable geometry and must not be reported as native text.

Asset and asset-version responses

The upload response contains asset fields plus the created version object:

{
  "id":"66666666-6666-4666-8666-666666666666",
  "name":"Revenue chart",
  "current_version_id":"77777777-7777-4777-8777-777777777777",
  "created_at":"2026-01-01T00:03:00Z",
  "reference":"asset://66666666-6666-4666-8666-666666666666",
  "download_url":"/api/v1/assets/66666666-6666-4666-8666-666666666666/versions/77777777-7777-4777-8777-777777777777/download",
  "version": {
    "id":"77777777-7777-4777-8777-777777777777",
    "asset_id":"66666666-6666-4666-8666-666666666666",
    "mime_type":"image/png", "size":1024, "width":96, "height":54,
    "sha256":"0000000000000000000000000000000000000000000000000000000000000000",
    "source":"upload", "prompt":null, "model_id":null, "provider":null,
    "parameters":{}, "references":[], "usage":null,
    "created_at":"2026-01-01T00:03:00Z",
    "download_url":"/api/v1/assets/66666666-6666-4666-8666-666666666666/versions/77777777-7777-4777-8777-777777777777/download"
  }
}

The zero hash and dimensions above are illustrative, not a downloadable fixture. GET /api/v1/assets returns up to 500 assets, newest first, without nested versions. GET /api/v1/assets/{asset_id} adds a versions array, newest first. GET /api/v1/assets/{asset_id}/versions/{version_id} returns one version object. There is no separate GET /assets/{asset_id}/versions collection route and no asset-deletion API.

Reference and pin an image

![Revenue chart](asset://66666666-6666-4666-8666-666666666666)

At save time, the revision freezes each referenced asset to one asset-version UUID. For an existing reference, normal revision saves inherit the parent's pin unless you explicitly change it. For a newly introduced reference without an override, the current asset version is selected. Later image uploads do not silently alter old revisions or inherited pins.

Explicitly select another version in the revision request:

{
  "expected_version_id":"44444444-4444-4444-8444-444444444442",
  "markdown":"# Results\n\n![Chart](asset://66666666-6666-4666-8666-666666666666)\n",
  "asset_versions": {
    "66666666-6666-4666-8666-666666666666":"77777777-7777-4777-8777-777777777777"
  }
}

The profile also accepts asset://<asset UUID>@<asset-version UUID> inline. An inline version takes precedence when resolving that reference; keep it consistent with any explicit mapping. One revision can use only one version of a given asset. Conflicting inline versions are rejected. Private assets must belong to the authenticated owner. Reviewed shared-library images are also accepted; the selected version must belong to that image and remain usable under its current policy. Explicit mapping entries for assets absent from Markdown are rejected; removed inherited references are dropped from a new revision's snapshot.

Download images with authentication

GET /api/v1/assets/{asset_id}/versions/{version_id}/download returns the stored PNG or static SVG bytes with 200. Raster responses include Content-Type:image/png, Content-Disposition:inline; filename="<version UUID>.png", and X-Content-SHA256. Static SVG versions use the SVG MIME type and attachment headers described above. The returned relative download_url is an authenticated API path, not a public or signed URL. Use the same Bearer header when downloading it, and compare the downloaded SHA-256 with both metadata and the response header. There is no need to pass a provider key or create a cookie session to download an image.

Shared image library

The curated library is shared across accounts, separate from private uploads. "Shared" does not mean anonymous access: every endpoint below requires a session or Bearer token. Account holders can search, download, and reuse approved images, but cannot create, overwrite, or delete shared originals. Catalog maintenance is an operator-only import. Do not hardcode the presence of a particular image: search and inspect usable. The packaged dataset contains 250 country/territory flags and reusable marks for the European Union, W3C, and Creative Commons, subject to each recorded policy. UN, WHO, UNICEF, UNESCO, World Bank Group, and OECD entries are metadata-only until authorization is available: they do not include downloadable logo files. Country/territory labels are not a claim of recognition or statehood. Afghanistan's packaged image is explicitly labelled as the Islamic Republic tricolour; Antarctica's image is a territorial illustration, not an official national flag. The complete current inventory is available through the paginated API, not a static count.

Search and discover

ws "$WS_BASE/api/v1/library/images?q=korea&category=flags&usable=true&limit=20&offset=0"
ws "$WS_BASE/api/v1/library/categories"
ws "$WS_BASE/api/v1/library/tags"

GET /api/v1/library/images returns a bare array, ordered by case-insensitive name, then stable image UUID. Use limit (1–200, default 50) and offset (0–100000, default 0) to paginate. There is no total or continuation token. A shorter page ends the result set; empty search results return [] with 200.

Parameter Meaning
q Case-insensitive substring of name, description, aliases, category, tags, or catalog key; max 200 characters. % and _ are literal, not SQL wildcards.
category Exact category slug, max 80 characters.
tag Exact tag slug, max 80 characters.
usable true: approved images with a usable current version; false: unavailable or metadata-only entries; omit for both.

Categories and tags return [{"value":"flags","count":250}]-shaped arrays; counts include metadata-only entries and are not filtered by the search parameters. Use GET /api/v1/library/images/{image_id} for one entry. Fields include:

  • id, stable key, name, description, category, tags, aliases;
  • source_url, license, license_url, attribution (creator or holding institution), restrictions, rights_status, and reusable;
  • current_version_id, usable, asset_uri, download_url, sha256, mime_type, size, width, height, created_at, and updated_at.

Always check usable, not merely the presence of an image record. Approved rights states are public_domain and licensed; requires_permission and blocked are not reusable. Logos may carry trademark or endorsement restrictions even when their image copyright permits reuse. Read the entry's source, license, attribution, and restrictions before use. Catalog inclusion is not endorsement or blanket permission.

Pin, download, and insert

Use the returned asset_uri, such as asset://66666666-6666-4666-8666-666666666666@77777777-7777-4777-8777-777777777777, directly in Markdown:

![Approved library image](asset://66666666-6666-4666-8666-666666666666@77777777-7777-4777-8777-777777777777)

The existing deck creation, revision, preview, and export APIs all accept this form. An unversioned asset://<image UUID> pins the current version when saving a revision. An explicit version or asset_versions mapping pins that exact snapshot. Private and shared images can be mixed in one deck; private images retain owner-only access.

GET /api/v1/library/images/{image_id}/versions returns an array of immutable versions, newest first (same limit/offset bounds). Append /{version_id} for version metadata, or /{version_id}/download for the PNG bytes. A version includes its immutable provenance snapshot, hash, size, dimensions, usable, and reuse URLs. Download with the same Bearer header and verify X-Content-SHA256 against sha256. No Google cookie or OpenRouter key is needed.

Content or provenance changes create a new version; old snapshots are not overwritten. A newer catalog version does not silently replace images in old deck revisions. If reuse rights are withdrawn, old bytes/provenance are retained but further library downloads and rendering of those references are blocked. Already downloaded files cannot be recalled. This policy does not retroactively rewrite deck Markdown.

Unknown IDs or mismatched image/version pairs return 404; unavailable reuse returns 403 with detail.code: "public_image_not_reusable". Corrupt stored library bytes return 503 with detail.code: "public_image_integrity_error". Invalid query bounds return 422. There is no public library mutation endpoint, and uploading a private asset with a shared image ID does not overwrite the shared record.

Markdown and rendering profile

Markdown is the stored source. Preview and exports are derived from that source and its frozen assets. Read the complete renderer_version from responses rather than hardcoding it; suffixes identify geometry, asset, and architecture-diagram revisions. This is a constrained profile, not arbitrary Slidev/Vue or full Marp directive execution.

Supported content includes headings, paragraphs, lists, tables, quotations, fenced code, safe images, links, fenced Mermaid diagrams, and declarative diagrams architecture diagrams. Use a line containing --- to separate slides. Separators inside code fences are not interpreted as slide boundaries. An opening --- starts YAML frontmatter and requires a closing ---.

---
title: Quarterly review
lang: en
paginate: true
theme: default
---
# Overview

Prepared with the web-slides API.

---

# Process

```mermaid
flowchart LR
  A[Draft] --> B[Review] --> C[Publish]
```

Allowed frontmatter keys are title, description, author, lang, font_id, paginate, theme, and size. Values must be strings except paginate, which must be boolean. Only theme: default is supported. Frontmatter must be a flat mapping without duplicate keys, YAML aliases, anchors, custom tags, nested mappings, or sequences. Its size limit is 10,000 characters. The whole document is limited to 200,000 characters and 100 slides.

Per-slide style options

Store style choices in the Markdown revision itself, using at most one reserved slide code fence on each slide. The fence contains a strict, flat JSON object and is not rendered as visible code. It participates in revision history, diffs, branches, merges and restores like the rest of the source.

---
title: A composed slide
size: "16:9"
font_id: pretendard
---
```slide
{"layout":"canvas","background":"#F7F4ED","color":"#172B3A","padding":0,"font_size":30,"heading_size":64}
```

<h1 style="position:absolute;left:72px;top:90px;width:900px;margin:0">Editable layout</h1>
<p data-font-id="arimo" style="position:absolute;left:72px;top:270px;width:760px;margin:0">Text stays in the versioned source.</p>
Style key Allowed values
layout flow or canvas; flow is the default
background, color Three- or six-digit hexadecimal color strings, such as #fff or #172B3A
padding Integer pixels from 0 through 160
font_size Integer body-text pixels from 8 through 100
heading_size Integer heading pixels from 12 through 160
text_align left, center, or right
vertical_align top, center, or bottom; applies to flow layout
font_id A reviewed font ID from GET /api/v1/fonts

Unknown keys, duplicate keys, arrays, nested objects, non-finite numbers and invalid types are rejected before rendering. Missing options keep the renderer defaults; options apply only to their own slide. Canvas layout gives content a positioned container. With padding:0, coordinates are relative to the complete slide. Flow layout keeps normal document order; vertical alignment positions the content group inside the slide padding. These are web-slides profile options, not arbitrary Marp directives or executable Slidev components.

Safe inline layout properties include position:absolute or relative, top, left, right, bottom (pixel values from -1280 through 2560), known display values including flex and grid, bounded gap, flex-direction, flex-wrap, justify-content, align-items, object-fit, and opacity from 0 through 1. Fixed positioning, arbitrary CSS functions, remote resources and unreviewed font IDs remain prohibited. An element may use data-font-id="arimo" to select a reviewed font independently of its slide; this is not a URL or a system-font lookup.

For measured placement or reconstruction, these additional numeric-only properties are supported:

Property Accepted subset
transform One matrix(a,b,c,d,e,f); six decimal numbers, a–d within ±16 and e–f within ±4096 pixels
transform-origin Exactly two pixel coordinates, each within ±4096; use 0px 0px for a top-left origin
clip-path polygon(xpx ypx,...) with 3–64 vertices, each coordinate within ±4096; optional first argument evenodd or nonzero
overflow hidden only, for a bounded clipping container

Values may not use scientific notation, percentages, URLs, variables, nested functions, 3D transforms, animations, calc(), or arbitrary CSS. A geometry declaration is limited to 4096 characters. Transforms affect display geometry, not document order. Clipping also clips visible text: do not count hidden or off-canvas text as readable content. Keep an element's untransformed dimensions explicit when mapping source coordinates. For example:

<div style="position:absolute;left:100px;top:200px;width:400px;height:240px;overflow:hidden;clip-path:polygon(0px 0px,400px 20px,380px 240px,0px 240px)">
  <p style="margin:0;transform-origin:0px 0px;transform:matrix(0.98,0.2,-0.2,0.98,30,20)">Editable, rotated text</p>
</div>

The document-wide YAML size chooses "16:9" (default, 1280 × 720), "4:3" (1280 × 960), or "16:10" (1280 × 800). It also accepts an exact integer-pixel canvas, for example size: "1254x969" (22:17, matching a landscape US Letter page). Use a lowercase x, no spaces, units, decimals, or leading zeros. Each dimension must be 320–1280 pixels and the total area must not exceed 1,228,800 pixels (the existing 4:3 maximum). Thus "960x1280" and "1000x1000" are valid; "1280x990" and "1280x1280" exceed the area budget and are rejected. All slides in one document share this canvas; choose explicit dimensions that preserve your source aspect ratio. Preview metadata exposes width and height; all export formats preserve those dimensions and aspect ratio. PNG pixels and PPTX slide dimensions use the exact canvas. Chromium's PDF paper-unit rounding can differ from the nominal size by less than one CSS pixel (0.75 pt). Do not assume every PNG is 1280 × 720 when a document declares another size.

  • Images must use internal asset:// references; external image URLs and data URLs in Markdown are rejected.
  • Normal links may use HTTPS URLs without embedded credentials or local #fragments; HTTP, JavaScript, file, and data links are rejected.
  • HTTPS links are navigation links, not permission for renderer network access or remote image fetching.
  • Allowed HTML elements include paragraphs, headings, lists, tables, inline emphasis, code, div, span, a, and img.
  • Scripts, iframes, arbitrary attributes, event handlers, HTML comments, declarations, and processing instructions are rejected.
  • title, alt, restricted dimensions, safe href/src, and a restricted inline style are supported where applicable.
  • CSS permits selected text, spacing, size, border, alignment, and color properties; arbitrary selectors, imports, functions, and scripts are not supported.
  • Mermaid blocks are limited to 20,000 characters each. Click handlers, initialization directives, embedded HTML, URL-like content, and unsupported directives are rejected.
  • Passing profile validation does not guarantee a syntactically valid diagram; inspect preview errors and export job results.

The renderer defaults to 16:9 slides at 1280 × 720 pixels; size selects other supported ratios. PDF preserves the rendered page appearance; current PPTX exports contain slide images, not individually editable text and diagram shapes. Repeated image references count toward a 48 MiB embedded-data budget in addition to the 36 MiB total decoded asset limit. The image map is limited to 200 entries.

Architecture diagrams: mingrammer/diagrams

Use a top-level diagrams fence containing JSON, not Python. The service uses mingrammer/diagrams 0.25.1 and Graphviz. This is a constrained adapter, not execution of arbitrary upstream Python examples. GET /api/v1/diagrams/catalog (Bearer or session authentication) returns the supported node kinds, limits, font/icon provenance, and the complete JSON Schema.

# Service architecture

```diagrams
{
  "version": 1,
  "title": "Agent-first slide generation",
  "direction": "LR",
  "theme": "light",
  "groups": [{"id": "backend", "label": "web-slides"}],
  "nodes": [
    {"id": "agent", "kind": "client", "label": "Agent / 사용자"},
    {"id": "api", "kind": "service", "label": "FastAPI", "group": "backend"},
    {"id": "db", "kind": "database", "label": "PostgreSQL", "group": "backend"},
    {"id": "assets", "kind": "aws.s3", "label": "S3 assets"}
  ],
  "edges": [
    {"from": "agent", "to": "api", "label": "Bearer token"},
    {"from": "api", "to": "db", "arrow": "both"},
    {"from": "api", "to": "assets", "style": "dashed"}
  ]
}
```

Save this Markdown with POST /api/v1/decks, edit it with POST /api/v1/decks/{deck_id}/versions and expected_version_id, then use the same preview and export endpoints as any other deck. Pin version_id for reproducible source selection. Branches, diffs, restoration, and human Markdown editing also apply: there is no separate unversioned diagram state or external editor account. No image-generation credits or OpenRouter key are needed for diagrams.

Field Supported values and bounds
version Integer 1 (default); other versions are rejected
title, node/group/edge label Up to 80 characters, including Korean; node/group labels must be nonempty; newline allowed, other controls rejected
direction LR (default), RL, TB, BT
theme light (default) or dark; match the surrounding slide background yourself
nodes 1–30; each has unique id, label, optional kind (default service), optional existing group
Node kinds client, service, database, queue, cloud, aws.ec2, aws.lambda, aws.s3, aws.rds, aws.elb, aws.sqs
groups Up to 8 flat groups, each with unique id and label; nesting is not supported
edges Up to 60, with existing from/to node IDs, optional label, style: solid|dashed, arrow: forward|both|none
IDs ASCII letter followed by up to 39 letters, digits, _ or -

At most 8 diagram blocks per document, each at most 20,000 UTF-8 bytes. Duplicate JSON keys, unknown properties/kinds, custom Graphviz attributes, Python, imports, custom image/font paths, and nested fences in lists/quotes are rejected. Labels are literal text, never HTML or Graphviz code; a URL in a label is not fetched.

Graphviz runs in a separate credential-free process, with a 6-second per-diagram wall deadline, 15-second shared diagram budget, CPU/file limits (plus a 192 MiB address-space limit on production Linux), and a temporary working directory. Diagram time counts toward the existing 30-second render deadline. Each generated PNG is at most 2 MiB and 2048 × 1152 pixels; generated assets also count toward document image budgets. Oversized/failed renders return a safe slide-numbered error, not a successful empty diagram.

Preview, PDF, PPTX, single-slide PNG, and PNG ZIP use the same diagram PNG. The JSON source remains editable/versioned, but diagram labels and shapes in downloads are raster images, not native editable PPTX objects or PDF text. Graphviz versions can affect layout across runtime upgrades; retain downloaded exports for byte-exact archival copies. Diagram labels use bundled NanumGothic, independently of slide font_id (project, unmodified source and OFL license).

AWS icons come from the pinned diagrams distribution and are used for architecture illustrations under AWS's architecture icon guidance. They are not a claim of current branding or endorsement. AWS trademarks remain with their owners; the engine's MIT license does not relicense provider marks. Other provider libraries are not exposed by this initial allowlist.

Fonts

GET /api/v1/fonts returns the reviewed installed catalog with 200.

GET /api/v1/fonts/{font_id}/file returns the verified WOFF2 bytes with the same session or Bearer authentication. The response has Content-Type: font/woff2 and X-Content-SHA256; unknown IDs return 404. The studio uses this endpoint to show actual font samples, loading each font when its card becomes visible. Each entry includes id, name, family, version, sha256, source_url, license, license_url, review_status, weights, and styles. Local filesystem names are excluded from the response.

[
  {
    "id":"pretendard", "name":"Pretendard Regular", "family":"Pretendard",
    "version":"1.3.9",
    "sha256":"0000000000000000000000000000000000000000000000000000000000000000",
    "source_url":"https://example.invalid/font-source.woff2",
    "license":"SIL Open Font License 1.1",
    "license_url":"https://example.invalid/font-license",
    "review_status":"approved", "weights":[400], "styles":["normal"]
  }
]

This is a schema illustration; read real hashes and source/license URLs from the catalog. Select a font with font_id in preview/export options or font_id in Markdown frontmatter. An explicit preview/export option takes precedence over frontmatter; otherwise the first installed catalog entry is the default. Per-slide font_id and element data-font-id are more specific overrides. The catalog includes 21 self-hosted OFL font families, with bundled licenses and verified bytes:

Use Font IDs
Korean sans-serif pretendard, notosanskr, wantedsans
Korean serif notoserifkr, nanummyeongjo
Latin sans-serif arimo, carlito, inter, roboto, opensans, lato, montserrat, poppins, sourcesans3, ibmplexsans
Latin serif / display sourceserif4, lora, merriweather, playfairdisplay
Monospace / code ibmplexmono, jetbrainsmono

category, languages, and variable describe the catalog; language lists are curated usage hints, not exhaustive glyph guarantees. designer names the credited creators. project_url links to the official project or publisher for background and documentation; source_url remains the exact versioned font file, and license_url remains the license reference. Read weights for actual supplied weights: Arimo supplies 400–700, while other variable families have their own ranges. Wanted Sans (wantedsans) supplies its official, unmodified Korean/Latin variable WOFF2 with weights 400–1000. Select it with font_id: wantedsans; this does not change the default font. Regular-only fonts use browser synthesis for bold; italic styles are synthesized because the catalog currently supplies normal faces. Only fonts selected by the document, a slide, or an HTML element are embedded, with no runtime font CDN requests. New revisions snapshot the installed font manifest. Restore preserves the selected historical font snapshot. The export worker compares the job's font snapshot with the revision and checks recorded versions/hashes against installed fonts. If a required version is unavailable, the job fails rather than silently rendering with a substituted font. If an export explicitly selects a font introduced after the historical revision, its version and hash are pinned in the export job and its cache key too.

Preview

POST /api/v1/preview is synchronous and returns 200 with HTML and rendering metadata.

Field Type Behavior
markdown String or null, maximum 200,000 If supplied, preview this unsaved text
deck_id UUID or null Resolve an owned deck as context
version_id UUID or null Select that deck's revision; requires deck_id
asset_versions Object or null Explicit asset-version pins; otherwise inherit relevant revision pins
font_id String or null Override the document's font selection

Saved-revision request:

{"deck_id":"33333333-3333-4333-8333-333333333333","version_id":"44444444-4444-4444-8444-444444444442"}

Unsaved request: {"markdown":"# Preview\n\nUnsaved content.\n"}. With deck_id and no version_id, the current main revision supplies context. Supplying both Markdown and deck context previews the supplied text with relevant inherited image pins; it does not save a revision. Omitting both source and context previews an empty document.

{
  "html":"<!doctype html><html>...rendered document...</html>",
  "slide_count":2,
  "width":1280,
  "height":720,
  "errors":[],
  "renderer_version":"web-slides-v1/marp-4.4.0/mermaid-12.1.0"
}

The HTML is deliberately abbreviated here. A rendering error entry can contain slide and message. Do not treat HTTP 200 alone as a clean preview: inspect the errors array. Profile errors return 422, often with a Slide N: message. Only one preview runs per API process at a time; contention returns 429 with Retry-After:2. Preview is not a job and has no polling endpoint or idempotency key.

Exports and authenticated downloads

Submit an exact revision

POST /api/v1/decks/{deck_id}/exports accepts:

Field Required Meaning
format Yes "pdf", "pptx", "png", or "png_zip"
version_id No Owned revision of this deck; omitted/null resolves current main at submission
font_id No Installed catalog font ID override
slide_number Only for PNG Strict integer, one-based; required for png, omit entirely for every other format
POST /api/v1/decks/33333333-3333-4333-8333-333333333333/exports
Authorization: Bearer wst_REPLACE_WITH_YOUR_SERVICE_TOKEN
Content-Type: application/json
Idempotency-Key: review-pdf-revision-2

{"version_id":"44444444-4444-4444-8444-444444444442","format":"pdf"}

202 response:

{
  "id":"99999999-9999-4999-8999-999999999999", "kind":"export", "status":"queued",
  "error":null, "attempts":0, "timeout_seconds":300,
  "created_at":"2026-01-01T00:04:00Z", "started_at":null, "finished_at":null, "result":null
}

An existing cached job may instead be returned as queued, running, or succeeded, still with HTTP 202. The job snapshots the resolved revision UUID, format, font option, renderer version, recorded font manifest, and the selected slide number for PNG. Subsequent edits to the deck do not change the queued export's revision. An unavailable renderer version is rejected with 409 at submission; required font snapshots are checked during execution.

Download one slide as PNG

Use format:"png" with the slide's one-based position in the selected revision:

{
  "version_id":"44444444-4444-4444-8444-444444444442",
  "format":"png",
  "slide_number":1
}

Slide 1 is the first slide, not slide 0. A missing number, zero, negative number, noninteger, or number beyond that revision's slide count returns 422 before enqueueing. Send a JSON integer, not "1", 1.0, or true. For pdf, pptx, and png_zip, omit slide_number entirely; even explicitly supplying null is rejected. Changing the slide number changes the export snapshot and idempotency payload. Use a separate key per revision, format, and selected slide.

JOB=$(jq -nc --arg v "$VERSION_ID" '{version_id:$v,format:"png",slide_number:1}' \
  | ws "$WS_BASE/api/v1/decks/$DECK_ID/exports" \
      -H "Idempotency-Key: slide-$VERSION_ID-001-png" --json @-)
JOB_ID=$(jq -r '.id' <<<"$JOB")
# Poll GET /api/v1/exports/$JOB_ID until status is succeeded, as shown below.
# Only then download the completed image:
ws "$WS_BASE/api/v1/exports/$JOB_ID/download" --output slide-001.png

The asynchronous job, polling URL, ownership checks, and retry rules are the same as PDF/PPTX. Successful download returns Content-Type:image/png, PNG bytes, and the SHA-256 header. For the standard 16:9 canvas, the image is 1280 × 720 pixels. The attachment filename is webslides-<revision UUID>-slide-001.png for slide 1. A slide PNG is an export artifact, not a newly created image-library asset; upload it separately if you want to reference it in another deck.

Download all slides as a PNG ZIP

{"version_id":"44444444-4444-4444-8444-444444444442","format":"png_zip"}

This enqueues one export job for all slides, not one job per slide. After polling to success, download through the same authenticated export-download endpoint. The MIME type is application/zip, and the attachment is webslides-<revision UUID>.zip. Archive entries are ordered and named slide-001.png, slide-002.png, and so on. Their images use the same rendered slide appearance and dimensions as individual PNG exports. ZIP and PPTX both start with ZIP signatures; distinguish them by the requested format and archive contents, not the signature alone. Verify the archive's SHA-256 against job.result.sha256 before extracting, and inspect entries without treating them as executable files. The ZIP's result.size and hash describe the complete archive, not an individual image.

Poll until a terminal status

GET /api/v1/exports/{job_id} returns the job with 200. Poll queued and running, stop on succeeded or failed, and give the client its own deadline. Two-second polling is reasonable for ordinary use; honor 429 and Retry-After if encountered. The reference acceptance CLI uses a 180-second client polling deadline; that is not the server's default 300-second job execution limit.

Successful response:

{
  "id":"99999999-9999-4999-8999-999999999999", "kind":"export", "status":"succeeded",
  "error":null, "attempts":1, "timeout_seconds":300,
  "created_at":"2026-01-01T00:04:00Z", "started_at":"2026-01-01T00:04:02Z",
  "finished_at":"2026-01-01T00:04:10Z",
  "result": {
    "sha256":"0000000000000000000000000000000000000000000000000000000000000000",
    "size":12345, "mime_type":"application/pdf"
  },
  "download_url":"/api/v1/exports/99999999-9999-4999-8999-999999999999/download"
}

The hash and size are illustrative. A failed job has status:"failed", an error string, and no usable download. There are no webhooks, cancellation endpoints, or job-deletion endpoints in this API.

Download and verify

ws "$WS_BASE/api/v1/exports/$JOB_ID/download" \
  --dump-header export.headers --output slides.pdf

Use the authenticated helper; do not paste the relative URL into an unauthenticated downloader. The download endpoint checks owner and successful status again; premature downloads return 409. The response includes Content-Disposition:attachment, a revision-based filename, and X-Content-SHA256. PDF MIME type is application/pdf. PPTX MIME type is application/vnd.openxmlformats-officedocument.presentationml.presentation. Individual-slide PNG uses image/png; all-slide PNG ZIP uses application/zip. Compare SHA-256 of the downloaded bytes with result.sha256 and the response header; check the recorded byte size as well. PDF begins with %PDF-; PPTX is a ZIP containing [Content_Types].xml, ppt/presentation.xml, slide XML, and slide images under ppt/media/. Export files are limited to 80 MiB. Keep authentication on downloads and do not forward it to another origin or follow unexpected redirects.

Exports are private by default. Only the owner may explicitly publish a completed PDF or PPTX. Publishing exposes the entire exported file, including embedded slide images and any links or text in that file. It does not publish source Markdown, individual asset URLs, project metadata, or other export formats.

Anyone with the public URL can download and redistribute the file without an account. Obtain the user's permission before publishing private content, and check that embedded material may be shared. Revocation stops future downloads from this service; it cannot recall already downloaded copies. Do not put API tokens in these URLs.

After polling a PDF/PPTX export until succeeded:

ws "$WS_BASE/api/v1/exports/$JOB_ID/public-links" -X POST \
  --data '{"acknowledge_public":true}'

The JSON boolean acknowledge_public is required and must be exactly true; omitting it or sending a string, number, or false returns 422. The 201 response has:

Field Meaning
id Management UUID; use this to get or revoke the link
export_id Successful export job UUID
version_id Immutable document revision used for this export
format pdf or pptx
sha256, size Exact published file hash and byte count
download_url Absolute public download URL; null after revocation
created_at, revoked_at Creation timestamp and nullable revocation timestamp
warning Public-sharing and downloaded-copy warning

Repeating the request while an active link exists returns the same link, including under concurrent requests. This does not require an Idempotency-Key. A new request after revocation creates a different URL and never reactivates the old URL. There is no automatic expiration: revoke links that should no longer be publicly accessible.

The link pins the exact result hash, file format and revision at publication time. Subsequent deck edits, restores, branches, new exports or changes to default fonts do not change its bytes. Archiving a deck or revoking an API token does not revoke its already published files: explicitly revoke the public links too.

List, inspect and revoke

ws "$WS_BASE/api/v1/public-links?export_id=$JOB_ID&limit=50&offset=0"
ws "$WS_BASE/api/v1/public-links/$LINK_ID"
ws "$WS_BASE/api/v1/public-links/$LINK_ID" -X DELETE

List returns a bare JSON array including active and revoked links, newest first. The optional export_id filter must identify an export owned by the caller. limit is 1–200 (default 50); offset is 0–100000. DELETE returns 204, including repeated revocations by the owner. There is no update, un-revoke, or public list endpoint. Creation and revocation are recorded in the owner's audit trail without the public URL.

Anonymous download

download_url has the shape https://webslides.parklab.work/s/<random-256-bit-token>/download. GET downloads it; HEAD returns the same file metadata without a body. No cookie or Authorization header is needed. Verify X-Content-SHA256 and Content-Length against the creation response. Filenames are webslides-<version_id>.pdf or .pptx, not user titles. Responses use the matching PDF/PPTX Content-Type, Content-Disposition:attachment, X-Content-Type-Options:nosniff, Cache-Control:no-store, Referrer-Policy:no-referrer and X-Robots-Tag:noindex, nofollow, nosnippet. /robots.txt disallows /s/; public links are never added to the sitemap. These directives discourage indexing but do not make a shared URL confidential. Do not put URLs in public logs or analytics.

Unknown, malformed and revoked public URLs all return 404. A download that already started before revocation may finish. Missing or corrupt stored files return 503 without exposing storage paths. The original /api/v1/exports/{job_id}/download still requires the owner's authentication even after publication.

Creation rejects incomplete/failed exports with 409 and PNG/PNG ZIP with 422. Generation jobs, nonexistent jobs and other owners' jobs/links return 404. Management operations require authentication (401 otherwise) and session writes also require the normal CSRF checks. Public downloads do not expose a metadata API.

Jobs, idempotency, and retries

Shared job fields

Field Meaning
id Job UUID
kind export or generation
status queued, running, succeeded, or failed
error Sanitized failure description or null; not an upstream response dump
attempts Number of execution starts; starts at zero while queued
timeout_seconds Per-job execution deadline recorded at creation
created_at, started_at, finished_at Lifecycle timestamps; the latter two may be null
result Kind-specific output object or null
download_url Present for a successful export
asset_id, asset_version_id, usage Also exposed at the top level for a generation result

GET /api/v1/jobs returns up to 100 of your jobs, newest first, across both kinds. There is no generic GET /jobs/{id}; use /exports/{id} or /image-generations/{id}. Use those direct paths when a job falls outside the latest-100 list.

Idempotency is tied to the resolved request

Supply Idempotency-Key on export or image-generation POST requests. It is optional, must be nonblank, and must not exceed 128 characters. Keys are scoped by account and job kind, not by deck or API token. Within that scope, the same key and same normalized payload return the existing job; different payloads return 409. The original job can be returned even if it failed. A replay is not an execution retry.

For exports, the normalized payload contains the resolved revision UUID, format, requested font override, renderer version, and recorded fonts; PNG additionally contains slide_number. If you omit version_id, a later replay after editing main can resolve to a different revision and return 409. For stable retries, capture and send an explicit revision UUID from the beginning. Semantically similar options may still differ: omitted/null font_id and an explicit default font ID are different payload values.

For generation, the normalized payload includes validated request fields, resolved upstream model/provider IDs, the model manifest version, and effective default quality. Reference-image UUID order is preserved in the request payload. A catalog/default change can therefore change the payload associated with an otherwise similar request. Connection and model validation run before the idempotency lookup; a now-inactive model or connection can prevent replay through the POST route. Keep the job UUID and use GET to recover its status independently of those submission-time conditions.

Export submissions also reuse an owned queued, running, or successful job with the same payload, even with no idempotency key. A new key used on such a cache hit is bound to the existing job and cannot later be reused for a different payload. Failed exports are excluded from this automatic cache reuse, unless an explicit key refers to that failed job. Generation has no payload-only deduplication: a fresh key or no key can create another billable request. Do not send an idempotency key expecting deduplication on ordinary project, deck, revision, issue, connection, or upload endpoints.

Retry policy

POST /api/v1/jobs/{job_id}/retry takes no JSON body and returns 202 for an eligible failed export. It preserves the job UUID and payload, changes status back to queued, and clears the error and finish time. The original started_at can remain until execution starts again; status is the authoritative lifecycle field. The endpoint rejects nonfailed jobs, generation jobs, and exports already started twice with 409. Retries also obey the account's pending-job limit and can return 429.

Image-generation jobs are not automatically retried and cannot use this retry endpoint. A timeout or interrupted upstream connection does not prove that the provider did not charge or generate an image. Inspect the existing job and the provider account before deliberately submitting a new request with a new key. Workers mark timed-out or interrupted jobs failed; polling a permanently queued job usually means the worker is unavailable or busy.

OpenRouter connections

Connection operations use your web-slides Bearer token. The provider key is a separate request-body value. There is no public endpoint to retrieve or decrypt a stored provider key.

Method and path Request fields Success
POST /api/v1/connections Required name (1–100), api_key (16–256) 201 connection metadata
GET /api/v1/connections No body 200 array, newest first, excluding deleted connections
PATCH /api/v1/connections/{connection_id} Optional name, api_key; nonnull values replace those fields 200 connection metadata
POST /api/v1/connections/{connection_id}/verify No body 200 connection metadata after revalidation
DELETE /api/v1/connections/{connection_id} No body 200 {"id":"...","deleted":true}

There is no individual GET /connections/{id} route; find the connection in the list. Register a key with this request shape, replacing the placeholder privately:

{"name":"My OpenRouter account","api_key":"REPLACE_WITH_OPENROUTER_KEY"}

Creation and key replacement perform a verification request and store one of three statuses:

Status Meaning
active The provider key check succeeded; required for generation submission and execution
invalid Provider rejected the key
unavailable Verification did not complete successfully; retry verification later
{
  "id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", "provider":"openrouter",
  "name":"My OpenRouter account", "masked_key":"••••1234", "status":"active",
  "verified_at":"2026-01-01T00:05:00Z", "created_at":"2026-01-01T00:05:00Z"
}

An HTTP 201 or 200 does not itself mean the connection is active; inspect status. Replacing only name does not reverify the key. Replacing api_key encrypts and verifies the replacement. Deletion clears the encrypted key and removes the connection from ordinary lookup; later mutation attempts return 404. Queued generation jobs resolve the connection again at execution, so deletion/invalidation can make them fail and key replacement can affect which credential they use. Provider requests use the fixed OpenRouter HTTPS origin and do not follow redirects. A custom provider base URL is not a request option.

Model discovery and image generation

Read the live catalog before choosing a model

GET /api/v1/models returns all registered entries, including inactive entries. Select an entry whose active value is true and whose capabilities satisfy your request. Do not infer activation from the model's name, a documentation example, or its presence in the response. An inactive registered model returns 409 on generation; an unknown model key returns 422.

The registry uses service keys such as quality, balanced, and efficient; send model_key, not an arbitrary upstream model ID. Each entry includes key, model_id, name, description, provider, active, status, catalog_checked_at, validated_at, validation_result, capabilities, default_quality, pricing, and manifest_version. These values describe the deployed registry and can change independently of this guide. Prices are catalog metadata, not a guarantee of the eventual charge. Actual usage is stored only when supplied upstream.

Capabilities object, illustrating the shape rather than promising any model's current configuration:

{
  "input_modalities":["text","image"], "output_modalities":["image"],
  "aspect_ratios":["1:1","16:9"], "resolutions":["1K","2K"],
  "output_formats":["png"], "max_references":14, "seed":true, "quality":[]
}

Use aspect_ratios, resolutions, output_formats, and quality as allowed-value arrays. An empty optional-option array means you should omit that option, not invent a value. If seed is false, omit it. Limit reference images to max_references and the API's absolute maximum of 16. An omitted quality uses default_quality; do not assume the default is the same across models.

Submit a generation job

POST /api/v1/image-generations returns a job with 202. It may incur a provider charge when executed.

Field Required Type, default, and validation
connection_id Yes Owned active connection UUID
model_key Yes Registry key, maximum 30 characters, active entry required
prompt Yes String, 1–6,000 characters
aspect_ratio No Default "16:9"; must be supported by the selected model
resolution No Null/omitted, or a value in the model's resolutions
output_format No Default "png"; must be in the model's output formats
quality No Null/omitted uses model default; explicit value must be supported
seed No Integer 0–2,147,483,647; only for a model that supports it
asset_id No Owned existing asset UUID; appends a version instead of creating a new asset
reference_version_ids No Array of owned asset-version UUIDs; default [], maximum 16 and model-specific cap

Example request, valid only when the chosen live model entry supports these options:

POST /api/v1/image-generations
Authorization: Bearer wst_REPLACE_WITH_YOUR_SERVICE_TOKEN
Content-Type: application/json
Idempotency-Key: diagram-variation-001

{
  "connection_id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
  "model_key":"efficient", "prompt":"A clean abstract process illustration, without text",
  "aspect_ratio":"16:9", "resolution":"1K", "output_format":"png",
  "reference_version_ids":["77777777-7777-4777-8777-777777777777"]
}

The service fixes generation to one output image per job and pins the upstream provider without fallback. There is no request field for arbitrary provider options, a custom endpoint, model overrides, or an output count. The stored image is normalized PNG even if the provider's original image used another raster encoding.

Reference images and regeneration

reference_version_ids contains asset-version IDs, not asset IDs or external URLs. Upload reference images first, retain their version IDs, then submit them in the generation request. The worker reads those exact owned versions; later uploads to the same logical asset do not change the reference inputs. The total reference-image size must not exceed 30 MiB; model count limits also apply. Setting asset_id creates a new immutable version on that target asset. Existing deck revisions retain their existing pins. To show the new result in a deck, append a deck revision with the returned asset version explicitly selected.

Poll and inspect the result

GET /api/v1/image-generations/{job_id} returns the same job envelope as exports, with kind:"generation". A successful job's result has asset_id, asset_version_id, and usage; these fields are also repeated at the top level.

{
  "id":"99999999-9999-4999-8999-999999999999", "kind":"generation", "status":"succeeded",
  "error":null, "attempts":1, "timeout_seconds":300,
  "created_at":"2026-01-01T00:06:00Z", "started_at":"2026-01-01T00:06:02Z",
  "finished_at":"2026-01-01T00:06:30Z",
  "result": {
    "asset_id":"66666666-6666-4666-8666-666666666666",
    "asset_version_id":"77777777-7777-4777-8777-777777777777", "usage":null
  },
  "asset_id":"66666666-6666-4666-8666-666666666666",
  "asset_version_id":"77777777-7777-4777-8777-777777777777", "usage":null
}

Fetch the resulting asset version for its authenticated download_url, dimensions, MIME type, byte size, and SHA-256. Generation metadata includes source:"generation", the original prompt, resolved model/provider IDs, reference-version IDs, and request parameters. Recorded parameters include aspect_ratio, resolution, output_format, effective quality, seed, and manifest_version. Allowed usage keys are prompt_tokens, completion_tokens, total_tokens, and cost, restricted to finite nonnegative numeric values. Usage can be null or an empty object. Missing cost is unknown, not zero.

Provider key rejection, insufficient provider balance, provider rate limits, malformed image responses, storage exhaustion, and deadlines can make a job fail. Failure messages are sanitized and do not contain raw provider responses or keys. An active connection check does not guarantee balance, model availability, or a successful generation. An active, empirically validated catalog model can still be blocked by your provider account's privacy or endpoint restrictions. For example, OpenRouter may return an upstream 404 when no endpoint satisfies an account's Zero Data Retention (ZDR) policy and the pinned provider selection. The worker translates that condition into a sanitized conflict-style failure message in job.error; polling still returns HTTP 200 with status:"failed", not a raw upstream 404. The service does not automatically relax privacy settings or switch to another provider to make the request succeed. Check the current catalog, connection, provider-account restrictions, and sanitized error before deciding whether another permitted request is appropriate.

Project issues

Each project has one issue collection; there is no separate board-creation endpoint. Issues use an integer optimistic-concurrency counter, not deck revision UUIDs.

Method and path Request or result
POST /api/v1/projects/{project_id}/issues Create; 201 issue object
GET /api/v1/projects/{project_id}/issues 200 array, oldest first; include_archived=true includes archived issues
GET /api/v1/issues/{issue_id} 200 issue object, including archived issues
PATCH /api/v1/issues/{issue_id} Update with required expected_revision; 200 issue object
DELETE /api/v1/issues/{issue_id}?expected_revision=1 Archive with query precondition; 200 issue object

Create fields: required nonblank title (1–255 characters); optional body (maximum 100,000, default ""), status (default todo), and priority (default normal). Statuses are todo, in_progress, and done; priorities are low, normal, and high.

{
  "id":"88888888-8888-4888-8888-888888888888",
  "owner_id":"11111111-1111-4111-8111-111111111111",
  "project_id":"22222222-2222-4222-8222-222222222222",
  "title":"Review the slides", "body":"Check the figures and source references.",
  "status":"todo", "priority":"normal", "revision":1, "archived":false,
  "created_at":"2026-01-01T00:07:00Z", "updated_at":"2026-01-01T00:07:00Z"
}

PATCH example: {"expected_revision":1,"status":"in_progress","priority":"high"}. PATCH accepts title, body, status, priority, and archived; explicitly null updated fields are rejected. Successful updates and archives increment revision. A stale counter returns 409 with {"detail":{"code":"issue_conflict","current_revision":2}}. Unarchive with the latest counter and archived:false. There is no issue-move field or separate historical issue-version endpoint; the counter prevents stale writes and audit records track operations.

Audit events

GET /api/v1/audit?limit=100 returns an owner-scoped array, newest first. The default limit is 100; supplied values are clamped to 1–200.

[
  {
    "id":"cccccccc-cccc-4ccc-8ccc-cccccccccccc", "action":"deck.version_created",
    "actor_type":"agent", "actor_id":"bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    "resource_id":"44444444-4444-4444-8444-444444444442",
    "details":{"deck_id":"33333333-3333-4333-8333-333333333333","parent_id":"44444444-4444-4444-8444-444444444441","merge_parent_id":null},
    "created_at":"2026-01-01T00:01:00Z"
  }
]

Common actions include token.created, token.used, token.revoked, project.created, project.updated, project.archived, deck.created, deck.updated, deck.version_created, deck.restored, branch.created, branch.merged, issue.created, issue.updated, and asset.version_created. Connection events use connection.created, connection.updated, connection.verified, and connection.deleted. Jobs record export.queued, generation.queued, kind-specific succeeded/failed events, and export.retry. Worker events use actor_type:"worker" and the job UUID as actor ID. Token-use audit and rate accounting are committed before the resource operation, so a rejected operation can still have a token-use event. The audit feed is a bounded metadata view, not a copy of document text, a credential store, or a guarantee of a complete execution trace for interrupted processes.

Limits and security behavior

Limit Current implementation or default
Authenticated request rate 300 requests per fixed minute per user, shared by tokens and sessions
Request-rate response 429 and Retry-After:60; polling and downloads count too
Active service tokens 30 per account
Pending jobs Default 5 queued/running jobs per user across both kinds; deployment configurable
New generation jobs Default 50 created in the preceding 24 hours; deployment configurable
Pending-job response 429 and Retry-After:30; daily generation limit also returns 429
Worker execution timeout Default 300 seconds, recorded in each job; deployment configurable
Renderer deadlines 30 seconds for document rendering; 90 seconds for the export renderer path
Image size Raster: 12 MiB input and normalized output; 16,777,216 pixels (4096²). Static SVG: 10 MiB
Stored asset budget 500 MiB per account across asset versions, including active generation reservations
Generation reservation 12 MiB for each queued/running generation; checked before submission/execution and released by leaving those states
Worker disk preflight At least 24 MiB free before a paid image request
Referenced image bytes 36 MiB per rendered document; generation reference sets remain limited to 30 MiB
Repeated embedded image data 48 MiB renderer budget
Export result 80 MiB maximum
Markdown and slides 200,000 characters; 100 slides
Collection caps Assets: 500; jobs: 100; audit: up to 200

Generation quota counts created jobs, including failed ones; reusing an existing idempotent job does not create another daily-quota entry. Queued/running image reservations also reduce space available for uploads. Historical image versions consume storage even when no current deck references them. The worker excludes its own reservation when storing the completed image and checks actual normalized output size. These checks avoid starting known-unwritable work; an upstream charge still cannot be made transactionally atomic with local storage.

Account-owned resource lookups are private to the issuing user. A known foreign UUID does not grant access. Exceptions are the authenticated shared-image library and explicitly published PDF/PPTX files. Projects do not grant permissions to other accounts, and tokens have account-level access rather than per-deck scopes. Deleted/revoked credentials and archived content have different semantics: archive preserves access and history; credential revocation prevents future authenticated use. Renderer inputs cannot execute arbitrary JavaScript or fetch external image resources. API binary downloads require authentication on every request; only explicitly created /s/ permalinks allow anonymous downloads. Responses use Cache-Control:no-store; do not build a public asset cache from private download URLs.

Complete curl workflow

This runnable Bash example needs a recent curl, jq, an already issued token in a private file, and a small local chart.png. It creates and retains a project, a deck with a pinned image, and a completed issue; it exports and downloads all four formats. It does not create credentials, change provider connections, or request paid image generation. Set the origin and token-file path for your environment. Do not enable shell tracing while handling credentials.

set -euo pipefail
set +x
WS_BASE='https://webslides.parklab.work'
WS_TOKEN_FILE='/private/path/web-slides-token'
chmod 600 "$WS_TOKEN_FILE"

ws() {
  curl --silent --show-error --fail-with-body --connect-timeout 10 --max-time 60 \
    --header @<(printf 'Authorization: Bearer %s\n' "$(tr -d '\r\n' < "$WS_TOKEN_FILE")") "$@"
}

ws "$WS_BASE/api/v1/me" | jq '{id,actor_type}'
PROJECT=$(ws "$WS_BASE/api/v1/projects" --json '{"name":"API tutorial"}')
PROJECT_ID=$(jq -r '.id' <<<"$PROJECT")
ASSET=$(ws "$WS_BASE/api/v1/assets/upload" -F 'name=Tutorial chart' -F 'file=@chart.png;type=image/png')
ASSET_ID=$(jq -r '.id' <<<"$ASSET")
ASSET_VERSION=$(jq -r '.current_version_id' <<<"$ASSET")
DECK=$(jq -nc --arg p "$PROJECT_ID" --arg a "$ASSET_ID" --arg v "$ASSET_VERSION" \
  '{name:"API tutorial",project_id:$p,markdown:("# API tutorial\n\n![Chart](asset://"+$a+")\n"),asset_versions:{($a):$v}}' \
  | ws "$WS_BASE/api/v1/decks" --json @-)
DECK_ID=$(jq -r '.id' <<<"$DECK")
VERSION_ID=$(jq -r '.current_version_id' <<<"$DECK")
ISSUE=$(ws "$WS_BASE/api/v1/projects/$PROJECT_ID/issues" --json '{"title":"Verify exports"}')
ISSUE_ID=$(jq -r '.id' <<<"$ISSUE")
jq -nc --arg d "$DECK_ID" --arg v "$VERSION_ID" '{deck_id:$d,version_id:$v}' \
  | ws "$WS_BASE/api/v1/preview" --json @- | jq '{slide_count,errors}'

for FORMAT in pdf pptx png png_zip; do
  KEY="tutorial-$VERSION_ID-$FORMAT"
  JOB=$(jq -nc --arg v "$VERSION_ID" --arg f "$FORMAT" \
    '{version_id:$v,format:$f} + (if $f == "png" then {slide_number:1} else {} end)' \
    | ws "$WS_BASE/api/v1/decks/$DECK_ID/exports" -H "Idempotency-Key: $KEY" --json @-)
  JOB_ID=$(jq -r '.id' <<<"$JOB")
  DEADLINE=$((SECONDS + 180))
  while true; do
    STATUS=$(jq -r '.status' <<<"$JOB")
    case "$STATUS" in
      succeeded) break ;;
      failed) printf 'Export failed; inspect job %s\n' "$JOB_ID" >&2; exit 1 ;;
      queued|running) ;;
      *) printf 'Unexpected job status\n' >&2; exit 1 ;;
    esac
    if (( SECONDS >= DEADLINE )); then printf 'Polling deadline exceeded\n' >&2; exit 1; fi
    sleep 2
    REMAINING=$((DEADLINE - SECONDS))
    if (( REMAINING <= 0 )); then printf 'Polling deadline exceeded\n' >&2; exit 1; fi
    JOB=$(ws "$WS_BASE/api/v1/exports/$JOB_ID" --max-time "$REMAINING")
  done
  EXTENSION=$FORMAT
  if [[ "$FORMAT" == png_zip ]]; then EXTENSION=zip; fi
  ws "$WS_BASE/api/v1/exports/$JOB_ID/download" --output "tutorial.$EXTENSION"
  EXPECTED=$(jq -r '.result.sha256' <<<"$JOB")
  ACTUAL=$(shasum -a 256 "tutorial.$EXTENSION" | awk '{print $1}')
  test "$EXPECTED" = "$ACTUAL"
done

ws "$WS_BASE/api/v1/issues/$ISSUE_ID" -X PATCH --json '{"expected_revision":1,"status":"done"}' \
  | jq '{id,status,revision}'
ws "$WS_BASE/api/v1/audit?limit=20" | jq 'map({action,resource_id})'
printf 'Retained project: %s\n' "$PROJECT_ID"

The helper sends authentication through a temporary file descriptor, not a token literal in curl's command-line header argument. It does not use cookie files or follow redirects. Use sha256sum instead of shasum -a 256 if that is the checksum utility installed on your system. For a broader repository-provided acceptance run, use uv run python -m scripts.api_smoke --base-url <origin> --token-file <private-file>. That CLI also tests Korean/Mermaid content, independent branch edits, merging, image downloads, PPTX entries, and response hash headers, and retains its demo project.

Complete Python workflow

Install httpx and Pillow, save the following as api_example.py, and run it with an already issued private token file:

python api_example.py --base-url https://webslides.parklab.work --token-file /private/path/web-slides-token

It creates an in-memory PNG, saves pinned Markdown, edits a branch, merges it, previews, exports, verifies downloads, and completes an issue. It writes tutorial.pdf, tutorial.pptx, tutorial.png, and tutorial.zip in the current directory and retains the created server resources. No provider connection or paid generation request is made.

import argparse
import hashlib
import io
import stat
import time
import uuid
import zipfile
from pathlib import Path

import httpx
from PIL import Image

parser = argparse.ArgumentParser()
parser.add_argument("--base-url", required=True)
parser.add_argument("--token-file", required=True, type=Path)
args = parser.parse_args()
origin = httpx.URL(args.base_url)
assert origin.scheme == "https" or (
    origin.scheme == "http" and origin.host in {"localhost", "127.0.0.1", "::1"}
)
assert not origin.username and not origin.password and not origin.query and not origin.fragment
assert origin.path in ("", "/")
assert stat.S_IMODE(args.token_file.stat().st_mode) & 0o077 == 0
token = args.token_file.read_text().strip()
assert token.startswith("wst_")


def without_cookie(request):
    request.headers.pop("cookie", None)


client = httpx.Client(
    base_url=str(origin),
    headers={"Authorization": "Bearer " + token},
    timeout=60,
    follow_redirects=False,
    trust_env=False,
    event_hooks={"request": [without_cookie]},
)


def api(method, path, **kwargs):
    response = client.request(method, "/api/v1" + path, **kwargs)
    if response.status_code not in (200, 201, 202):
        raise RuntimeError(f"API request failed: HTTP {response.status_code}")
    return response.json()


def wait_export(job):
    deadline = time.monotonic() + 180
    while job["status"] in ("queued", "running"):
        remaining = deadline - time.monotonic()
        if remaining <= 0:
            raise TimeoutError("Export polling deadline exceeded")
        time.sleep(min(2, remaining))
        remaining = deadline - time.monotonic()
        if remaining <= 0:
            raise TimeoutError("Export polling deadline exceeded")
        job = api("GET", "/exports/" + job["id"], timeout=min(30, remaining))
    if job["status"] != "succeeded":
        raise RuntimeError("Export failed; inspect the job using its UUID")
    return job


with client:
    assert api("GET", "/me")["actor_type"] == "agent"
    project = api("POST", "/projects", json={"name": "Python API tutorial"})
    image = io.BytesIO()
    Image.new("RGB", (96, 54), "#3154a5").save(image, format="PNG")
    asset = api(
        "POST",
        "/assets/upload",
        data={"name": "Tutorial image"},
        files={"file": ("chart.png", image.getvalue(), "image/png")},
    )
    pins = {asset["id"]: asset["current_version_id"]}
    markdown = (
        "# Tutorial\n\nOpening.\n\n![Chart](asset://"
        + asset["id"]
        + ")\n\n---\n\n# Review\n\nDraft.\n"
    )
    deck = api(
        "POST",
        "/decks",
        json={
            "name": "Python tutorial",
            "project_id": project["id"],
            "markdown": markdown,
            "asset_versions": pins,
        },
    )
    root = "/decks/" + deck["id"]
    branch = api(
        "POST",
        root + "/branches",
        json={"name": "review", "from_version_id": deck["current_version_id"]},
    )
    source = api(
        "POST",
        root + "/versions",
        json={
            "branch_id": branch["id"],
            "expected_version_id": branch["head_version_id"],
            "markdown": markdown.replace("Draft.", "Reviewed."),
            "asset_versions": pins,
        },
    )
    target = api(
        "POST",
        root + "/versions",
        json={
            "expected_version_id": deck["current_version_id"],
            "markdown": markdown.replace("Opening.", "Updated opening."),
            "asset_versions": pins,
        },
    )
    merged = api(
        "POST",
        root + "/merge",
        json={
            "source_branch_id": branch["id"],
            "expected_version_id": target["id"],
            "message": "Merge reviewed content",
        },
    )
    assert merged["parent_id"] == target["id"] and merged["merge_parent_id"] == source["id"]
    assert merged["asset_versions"] == pins
    preview = api("POST", "/preview", json={"deck_id": deck["id"], "version_id": merged["id"]})
    assert preview["html"] and not preview["errors"]
    issue = api(
        "POST", "/projects/" + project["id"] + "/issues", json={"title": "Verify downloads"}
    )
    for format in ("pdf", "pptx", "png", "png_zip"):
        options = {"version_id": merged["id"], "format": format}
        if format == "png":
            options["slide_number"] = 1
        job = api(
            "POST", root + "/exports", headers={"Idempotency-Key": str(uuid.uuid4())}, json=options
        )
        job = wait_export(job)
        path = "/api/v1/exports/" + str(uuid.UUID(job["id"])) + "/download"
        assert job["download_url"] == path
        response = client.get(path)
        if response.status_code != 200:
            raise RuntimeError("Authenticated download failed")
        data = response.content
        digest = hashlib.sha256(data).hexdigest()
        assert digest == job["result"]["sha256"] == response.headers["X-Content-SHA256"]
        assert len(data) == job["result"]["size"]
        if format == "pdf":
            assert data.startswith(b"%PDF-")
        elif format == "png":
            assert data.startswith(b"\x89PNG\r\n\x1a\n")
            with Image.open(io.BytesIO(data)) as slide:
                assert slide.size == (1280, 720)
        else:
            with zipfile.ZipFile(io.BytesIO(data)) as archive:
                if format == "pptx":
                    assert {
                        "[Content_Types].xml",
                        "ppt/presentation.xml",
                        "ppt/slides/slide1.xml",
                    } <= set(archive.namelist())
                else:
                    assert archive.namelist() == ["slide-001.png", "slide-002.png"]
                    for name in archive.namelist():
                        with Image.open(io.BytesIO(archive.read(name))) as slide:
                            assert slide.format == "PNG" and slide.size == (1280, 720)
                assert archive.testzip() is None
        extension = "zip" if format == "png_zip" else format
        Path("tutorial." + extension).write_bytes(data)
    api(
        "PATCH",
        "/issues/" + issue["id"],
        json={"expected_revision": issue["revision"], "status": "done"},
    )
    for endpoint in ("fonts", "models", "connections", "audit"):
        assert isinstance(api("GET", "/" + endpoint), list)
    print("Retained project:", project["id"])

The program never prints the token, uses no cookie authentication, and verifies downloaded bytes before writing them. For production automation, retain project/deck/job IDs in your own state so recovery can use GET instead of creating another set of resources.

Troubleshooting

Symptom Check
401 on all API calls Use a nonrevoked wst_ token, not an OpenRouter key or Google token
Browser POST fails but GET works Read /me again and send its X-CSRF-Token; check Origin
API download URL returns 401 Authenticate the download itself; /api/v1/ download URLs are not public
404 for a known UUID Confirm owner, resource type, and parent deck/asset association
409 when saving Fetch the latest main or branch head and reconcile edits
409 when updating an issue Use the latest integer revision, not a deck UUID
409 for a reused job key Compare resolved revision, format/options, and generation catalog/defaults
Export POST immediately returns succeeded A matching cached successful export was reused
Generation POST returns inactive-model conflict Refresh /models and select an active compatible entry
Connection creation succeeded but generation fails Inspect connection status, provider balance, and job error
New asset upload does not change an old deck The revision is pinned; explicitly select the new asset version in a new revision
Diff is empty after an image update Markdown diff does not compare asset-version maps
Job remains queued Inspect worker availability and queue load; do not duplicate paid requests
Export fails after a deployment Check renderer and font snapshot availability, then inspect sanitized job error
A diagram saves but does not export Inspect preview errors and remove unsupported Mermaid content
Asset upload fails below 500 MiB of visible images Older versions and pending generation reservations also consume the budget
Job GET returns 200 with an error HTTP transport succeeded; the asynchronous operation failed

Use the response schema and status fields as the integration contract. Archive content when you want to hide it, create new revisions when you want to change it, and keep explicit version IDs when you need reproducible results.

02 / ENDPOINT REFERENCE

Every operation. From the source.

65 operations

Generated from this server's OpenAPI specification for every /api/v1 route. Expand an operation to inspect its parameters, request body, responses, and security declaration.

Read the guide alongside the schema.

OpenAPI describes the declared interface. Some endpoints do not declare a detailed response model; an empty schema does not mean an empty response. The guide explains behavior, authentication, concurrency, and examples.

Me

1 operations
GET/api/v1/meMe

Operation ID me_api_v1_me_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "me_api_v1_me_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Me"
}

Projects

7 operations
GET/api/v1/projectsList Projects

List Projects

Operation ID list_projects_api_v1_projects_get

Parameters
NameLocationTypeRequiredDescription
include_archivedquerybooleanNo—
Complete parameter definitions
[
  {
    "in": "query",
    "name": "include_archived",
    "required": false,
    "schema": {
      "default": false,
      "title": "Include Archived",
      "type": "boolean"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_projects_api_v1_projects_get",
  "parameters": [
    {
      "in": "query",
      "name": "include_archived",
      "required": false,
      "schema": {
        "default": false,
        "title": "Include Archived",
        "type": "boolean"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Projects",
  "tags": [
    "content"
  ]
}
POST/api/v1/projectsCreate Project

Create Project

Operation ID create_project_api_v1_projects_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/ProjectCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_project_api_v1_projects_post",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ProjectCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Project",
  "tags": [
    "content"
  ]
}
GET/api/v1/projects/{project_id}Get Project

Get Project

Operation ID get_project_api_v1_projects__project_id__get

Parameters
NameLocationTypeRequiredDescription
project_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "project_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Project Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_project_api_v1_projects__project_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Project Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Project",
  "tags": [
    "content"
  ]
}
PATCH/api/v1/projects/{project_id}Update Project

Update Project

Operation ID update_project_api_v1_projects__project_id__patch

Parameters
NameLocationTypeRequiredDescription
project_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "project_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Project Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/ProjectUpdate"
      }
    }
  },
  "required": true
}
Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "update_project_api_v1_projects__project_id__patch",
  "parameters": [
    {
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Project Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ProjectUpdate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Update Project",
  "tags": [
    "content"
  ]
}
DELETE/api/v1/projects/{project_id}Archive Project

Archive Project

Operation ID archive_project_api_v1_projects__project_id__delete

Parameters
NameLocationTypeRequiredDescription
project_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "project_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Project Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "archive_project_api_v1_projects__project_id__delete",
  "parameters": [
    {
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Project Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Archive Project",
  "tags": [
    "content"
  ]
}
GET/api/v1/projects/{project_id}/issuesList Issues

List Issues

Operation ID list_issues_api_v1_projects__project_id__issues_get

Parameters
NameLocationTypeRequiredDescription
project_idpathstring (uuid)Yes—
include_archivedquerybooleanNo—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "project_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Project Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "include_archived",
    "required": false,
    "schema": {
      "default": false,
      "title": "Include Archived",
      "type": "boolean"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_issues_api_v1_projects__project_id__issues_get",
  "parameters": [
    {
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Project Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "include_archived",
      "required": false,
      "schema": {
        "default": false,
        "title": "Include Archived",
        "type": "boolean"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Issues",
  "tags": [
    "content"
  ]
}
POST/api/v1/projects/{project_id}/issuesCreate Issue

Create Issue

Operation ID create_issue_api_v1_projects__project_id__issues_post

Parameters
NameLocationTypeRequiredDescription
project_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "project_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Project Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/IssueCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_issue_api_v1_projects__project_id__issues_post",
  "parameters": [
    {
      "in": "path",
      "name": "project_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Project Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/IssueCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Issue",
  "tags": [
    "content"
  ]
}

Decks

14 operations
GET/api/v1/decksList Decks

List Decks

Operation ID list_decks_api_v1_decks_get

Parameters
NameLocationTypeRequiredDescription
project_idquerystring (uuid) | nullNo—
include_archivedquerybooleanNo—
Complete parameter definitions
[
  {
    "in": "query",
    "name": "project_id",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Project Id"
    }
  },
  {
    "in": "query",
    "name": "include_archived",
    "required": false,
    "schema": {
      "default": false,
      "title": "Include Archived",
      "type": "boolean"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_decks_api_v1_decks_get",
  "parameters": [
    {
      "in": "query",
      "name": "project_id",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "format": "uuid",
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Project Id"
      }
    },
    {
      "in": "query",
      "name": "include_archived",
      "required": false,
      "schema": {
        "default": false,
        "title": "Include Archived",
        "type": "boolean"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Decks",
  "tags": [
    "content"
  ]
}
POST/api/v1/decksCreate Deck

Create Deck

Operation ID create_deck_api_v1_decks_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/DeckCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_deck_api_v1_decks_post",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeckCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Deck",
  "tags": [
    "content"
  ]
}
GET/api/v1/decks/{deck_id}Get Deck

Operation ID get_deck_api_v1_decks__deck_id__get

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_deck_api_v1_decks__deck_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Deck",
  "tags": [
    "content"
  ]
}
PATCH/api/v1/decks/{deck_id}Update Deck

Update Deck

Operation ID update_deck_api_v1_decks__deck_id__patch

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/DeckUpdate"
      }
    }
  },
  "required": true
}
Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "update_deck_api_v1_decks__deck_id__patch",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/DeckUpdate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Update Deck",
  "tags": [
    "content"
  ]
}
DELETE/api/v1/decks/{deck_id}Archive Deck

Archive Deck

Operation ID archive_deck_api_v1_decks__deck_id__delete

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
expected_version_idquerystring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "expected_version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Expected Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "archive_deck_api_v1_decks__deck_id__delete",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "expected_version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Expected Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Archive Deck",
  "tags": [
    "content"
  ]
}
GET/api/v1/decks/{deck_id}/branchesList Branches

List Branches

Operation ID list_branches_api_v1_decks__deck_id__branches_get

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_branches_api_v1_decks__deck_id__branches_get",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Branches",
  "tags": [
    "content"
  ]
}
POST/api/v1/decks/{deck_id}/branchesCreate Branch

Create Branch

Operation ID create_branch_api_v1_decks__deck_id__branches_post

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/BranchCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_branch_api_v1_decks__deck_id__branches_post",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/BranchCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Branch",
  "tags": [
    "content"
  ]
}
GET/api/v1/decks/{deck_id}/diffGet Diff

Operation ID get_diff_api_v1_decks__deck_id__diff_get

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
from_version_idquerystring (uuid)Yes—
to_version_idquerystring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "from_version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "From Version Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "to_version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "To Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_diff_api_v1_decks__deck_id__diff_get",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "from_version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "From Version Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "to_version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "To Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Diff",
  "tags": [
    "content"
  ]
}
POST/api/v1/decks/{deck_id}/exportsExport Deck

Export Deck

Operation ID export_deck_api_v1_decks__deck_id__exports_post

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
idempotency-keyheaderstring | nullNo—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  },
  {
    "in": "header",
    "name": "idempotency-key",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Idempotency-Key"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/ExportCreate"
      }
    }
  },
  "required": true
}
Responses
202Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "export_deck_api_v1_decks__deck_id__exports_post",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    },
    {
      "in": "header",
      "name": "idempotency-key",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Idempotency-Key"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ExportCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "202": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Export Deck",
  "tags": [
    "Rendering and generation jobs"
  ]
}
POST/api/v1/decks/{deck_id}/mergeMerge Branch

Merge Branch

Operation ID merge_branch_api_v1_decks__deck_id__merge_post

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/Merge"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "merge_branch_api_v1_decks__deck_id__merge_post",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/Merge"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Merge Branch",
  "tags": [
    "content"
  ]
}
POST/api/v1/decks/{deck_id}/restoreRestore Version

Restore Version

Operation ID restore_version_api_v1_decks__deck_id__restore_post

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/Restore"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "restore_version_api_v1_decks__deck_id__restore_post",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/Restore"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Restore Version",
  "tags": [
    "content"
  ]
}
GET/api/v1/decks/{deck_id}/versionsList Versions

List Versions

Operation ID list_versions_api_v1_decks__deck_id__versions_get

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_versions_api_v1_decks__deck_id__versions_get",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Versions",
  "tags": [
    "content"
  ]
}
POST/api/v1/decks/{deck_id}/versionsCreate Version

Create Version

Operation ID create_version_api_v1_decks__deck_id__versions_post

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/VersionCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_version_api_v1_decks__deck_id__versions_post",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/VersionCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Version",
  "tags": [
    "content"
  ]
}
GET/api/v1/decks/{deck_id}/versions/{version_id}Get Version

Get Version

Operation ID get_version_api_v1_decks__deck_id__versions__version_id__get

Parameters
NameLocationTypeRequiredDescription
deck_idpathstring (uuid)Yes—
version_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "deck_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Deck Id",
      "type": "string"
    }
  },
  {
    "in": "path",
    "name": "version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_version_api_v1_decks__deck_id__versions__version_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "deck_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Deck Id",
        "type": "string"
      }
    },
    {
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Version",
  "tags": [
    "content"
  ]
}

Issues

3 operations
GET/api/v1/issues/{issue_id}Get Issue

Get Issue

Operation ID get_issue_api_v1_issues__issue_id__get

Parameters
NameLocationTypeRequiredDescription
issue_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "issue_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Issue Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_issue_api_v1_issues__issue_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "issue_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Issue Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Issue",
  "tags": [
    "content"
  ]
}
PATCH/api/v1/issues/{issue_id}Update Issue

Update Issue

Operation ID update_issue_api_v1_issues__issue_id__patch

Parameters
NameLocationTypeRequiredDescription
issue_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "issue_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Issue Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/IssueUpdate"
      }
    }
  },
  "required": true
}
Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "update_issue_api_v1_issues__issue_id__patch",
  "parameters": [
    {
      "in": "path",
      "name": "issue_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Issue Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/IssueUpdate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Update Issue",
  "tags": [
    "content"
  ]
}
DELETE/api/v1/issues/{issue_id}Archive Issue

Archive Issue

Operation ID archive_issue_api_v1_issues__issue_id__delete

Parameters
NameLocationTypeRequiredDescription
issue_idpathstring (uuid)Yes—
expected_revisionqueryintegerYes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "issue_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Issue Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "expected_revision",
    "required": true,
    "schema": {
      "minimum": 1,
      "title": "Expected Revision",
      "type": "integer"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "archive_issue_api_v1_issues__issue_id__delete",
  "parameters": [
    {
      "in": "path",
      "name": "issue_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Issue Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "expected_revision",
      "required": true,
      "schema": {
        "minimum": 1,
        "title": "Expected Revision",
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Archive Issue",
  "tags": [
    "content"
  ]
}

Preview

1 operations
POST/api/v1/previewPreview

Operation ID preview_api_v1_preview_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/PreviewCreate"
      }
    }
  },
  "required": true
}
Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "preview_api_v1_preview_post",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PreviewCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Preview",
  "tags": [
    "Preview"
  ]
}

Assets

5 operations
GET/api/v1/assetsList Assets

List Assets

Operation ID list_assets_api_v1_assets_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_assets_api_v1_assets_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Assets",
  "tags": [
    "Assets"
  ]
}
POST/api/v1/assets/uploadUpload Asset

Upload Asset

Operation ID upload_asset_api_v1_assets_upload_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "multipart/form-data": {
      "schema": {
        "$ref": "#/components/schemas/Body_upload_asset_api_v1_assets_upload_post"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "upload_asset_api_v1_assets_upload_post",
  "requestBody": {
    "content": {
      "multipart/form-data": {
        "schema": {
          "$ref": "#/components/schemas/Body_upload_asset_api_v1_assets_upload_post"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Upload Asset",
  "tags": [
    "Assets"
  ]
}
GET/api/v1/assets/{asset_id}Get Asset

Get Asset

Operation ID get_asset_api_v1_assets__asset_id__get

Parameters
NameLocationTypeRequiredDescription
asset_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "asset_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Asset Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_asset_api_v1_assets__asset_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "asset_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Asset Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Asset",
  "tags": [
    "Assets"
  ]
}
GET/api/v1/assets/{asset_id}/versions/{version_id}Get Asset Version

Get Asset Version

Operation ID get_asset_version_api_v1_assets__asset_id__versions__version_id__get

Parameters
NameLocationTypeRequiredDescription
asset_idpathstring (uuid)Yes—
version_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "asset_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Asset Id",
      "type": "string"
    }
  },
  {
    "in": "path",
    "name": "version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_asset_version_api_v1_assets__asset_id__versions__version_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "asset_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Asset Id",
        "type": "string"
      }
    },
    {
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Asset Version",
  "tags": [
    "Assets"
  ]
}
GET/api/v1/assets/{asset_id}/versions/{version_id}/downloadDownload Asset

Download Asset

Operation ID download_asset_api_v1_assets__asset_id__versions__version_id__download_get

Parameters
NameLocationTypeRequiredDescription
asset_idpathstring (uuid)Yes—
version_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "asset_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Asset Id",
      "type": "string"
    }
  },
  {
    "in": "path",
    "name": "version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "download_asset_api_v1_assets__asset_id__versions__version_id__download_get",
  "parameters": [
    {
      "in": "path",
      "name": "asset_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Asset Id",
        "type": "string"
      }
    },
    {
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Download Asset",
  "tags": [
    "Assets"
  ]
}

Image Generations

2 operations
POST/api/v1/image-generationsGenerate Image

Generate Image

Operation ID generate_image_api_v1_image_generations_post

Parameters
NameLocationTypeRequiredDescription
idempotency-keyheaderstring | nullNo—
Complete parameter definitions
[
  {
    "in": "header",
    "name": "idempotency-key",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Idempotency-Key"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/GenerationCreate"
      }
    }
  },
  "required": true
}
Responses
202Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "generate_image_api_v1_image_generations_post",
  "parameters": [
    {
      "in": "header",
      "name": "idempotency-key",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Idempotency-Key"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/GenerationCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "202": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Generate Image",
  "tags": [
    "Rendering and generation jobs"
  ]
}
GET/api/v1/image-generations/{job_id}Get Generation

Get Generation

Operation ID get_generation_api_v1_image_generations__job_id__get

Parameters
NameLocationTypeRequiredDescription
job_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "job_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Job Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_generation_api_v1_image_generations__job_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Job Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Generation",
  "tags": [
    "Rendering and generation jobs"
  ]
}

Models

1 operations
GET/api/v1/modelsModels

Operation ID models_api_v1_models_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "models_api_v1_models_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Models",
  "tags": [
    "Rendering and generation jobs"
  ]
}

Connections

5 operations
GET/api/v1/connectionsList Connections

List Connections

Operation ID list_connections_api_v1_connections_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_connections_api_v1_connections_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Connections",
  "tags": [
    "OpenRouter connections"
  ]
}
POST/api/v1/connectionsCreate Connection

Create Connection

Operation ID create_connection_api_v1_connections_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/ConnectionCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_connection_api_v1_connections_post",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ConnectionCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Connection",
  "tags": [
    "OpenRouter connections"
  ]
}
PATCH/api/v1/connections/{connection_id}Update Connection

Update Connection

Operation ID update_connection_api_v1_connections__connection_id__patch

Parameters
NameLocationTypeRequiredDescription
connection_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "connection_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Connection Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/ConnectionUpdate"
      }
    }
  },
  "required": true
}
Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "update_connection_api_v1_connections__connection_id__patch",
  "parameters": [
    {
      "in": "path",
      "name": "connection_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Connection Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ConnectionUpdate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Update Connection",
  "tags": [
    "OpenRouter connections"
  ]
}
DELETE/api/v1/connections/{connection_id}Delete Connection

Delete Connection

Operation ID delete_connection_api_v1_connections__connection_id__delete

Parameters
NameLocationTypeRequiredDescription
connection_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "connection_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Connection Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "delete_connection_api_v1_connections__connection_id__delete",
  "parameters": [
    {
      "in": "path",
      "name": "connection_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Connection Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Delete Connection",
  "tags": [
    "OpenRouter connections"
  ]
}
POST/api/v1/connections/{connection_id}/verifyVerify Connection

Verify Connection

Operation ID verify_connection_api_v1_connections__connection_id__verify_post

Parameters
NameLocationTypeRequiredDescription
connection_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "connection_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Connection Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "verify_connection_api_v1_connections__connection_id__verify_post",
  "parameters": [
    {
      "in": "path",
      "name": "connection_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Connection Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Verify Connection",
  "tags": [
    "OpenRouter connections"
  ]
}

Fonts

2 operations
GET/api/v1/fontsFonts

Operation ID fonts_api_v1_fonts_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "fonts_api_v1_fonts_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Fonts",
  "tags": [
    "Rendering and generation jobs"
  ]
}
GET/api/v1/fonts/{font_id}/fileDownload Font

Download Font

Operation ID download_font_api_v1_fonts__font_id__file_get

Parameters
NameLocationTypeRequiredDescription
font_idpathstringYes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "font_id",
    "required": true,
    "schema": {
      "title": "Font Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "download_font_api_v1_fonts__font_id__file_get",
  "parameters": [
    {
      "in": "path",
      "name": "font_id",
      "required": true,
      "schema": {
        "title": "Font Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Download Font",
  "tags": [
    "Rendering and generation jobs"
  ]
}

Exports

3 operations
GET/api/v1/exports/{job_id}Get Export

Get Export

Operation ID get_export_api_v1_exports__job_id__get

Parameters
NameLocationTypeRequiredDescription
job_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "job_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Job Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "get_export_api_v1_exports__job_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Job Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Get Export",
  "tags": [
    "Rendering and generation jobs"
  ]
}
GET/api/v1/exports/{job_id}/downloadDownload Export

Download Export

Operation ID download_export_api_v1_exports__job_id__download_get

Parameters
NameLocationTypeRequiredDescription
job_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "job_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Job Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "download_export_api_v1_exports__job_id__download_get",
  "parameters": [
    {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Job Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Download Export",
  "tags": [
    "Rendering and generation jobs"
  ]
}
POST/api/v1/exports/{job_id}/public-linksCreate Public Link

Create Public Link

Operation ID create_public_link_api_v1_exports__job_id__public_links_post

Parameters
NameLocationTypeRequiredDescription
job_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "job_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Job Id",
      "type": "string"
    }
  }
]
Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/PublicLinkCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_public_link_api_v1_exports__job_id__public_links_post",
  "parameters": [
    {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Job Id",
        "type": "string"
      }
    }
  ],
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/PublicLinkCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Public Link",
  "tags": [
    "Public export links"
  ]
}

Jobs

2 operations
GET/api/v1/jobsList Jobs

List Jobs

Operation ID list_jobs_api_v1_jobs_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_jobs_api_v1_jobs_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Jobs",
  "tags": [
    "Rendering and generation jobs"
  ]
}
POST/api/v1/jobs/{job_id}/retryRetry Job

Retry Job

Operation ID retry_job_api_v1_jobs__job_id__retry_post

Parameters
NameLocationTypeRequiredDescription
job_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "job_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Job Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
202Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "retry_job_api_v1_jobs__job_id__retry_post",
  "parameters": [
    {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Job Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "202": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Retry Job",
  "tags": [
    "Rendering and generation jobs"
  ]
}

Tokens

3 operations
GET/api/v1/tokensList Tokens

List Tokens

Operation ID list_tokens_api_v1_tokens_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_tokens_api_v1_tokens_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Tokens",
  "tags": [
    "Credentials"
  ]
}
POST/api/v1/tokensCreate Token

Create Token

Operation ID create_token_api_v1_tokens_post

Parameters

No path, query, header, or cookie parameters are declared.

Request body

Required body. Media types, schemas, and declared examples:

{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/TokenCreate"
      }
    }
  },
  "required": true
}
Responses
201Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "create_token_api_v1_tokens_post",
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/TokenCreate"
        }
      }
    },
    "required": true
  },
  "responses": {
    "201": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Create Token",
  "tags": [
    "Credentials"
  ]
}
DELETE/api/v1/tokens/{token_id}Revoke Token

Revoke Token

Operation ID revoke_token_api_v1_tokens__token_id__delete

Parameters
NameLocationTypeRequiredDescription
token_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "token_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Token Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "revoke_token_api_v1_tokens__token_id__delete",
  "parameters": [
    {
      "in": "path",
      "name": "token_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Token Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Revoke Token",
  "tags": [
    "Credentials"
  ]
}

Audit

1 operations
GET/api/v1/auditList Audit

List Audit

Operation ID list_audit_api_v1_audit_get

Parameters
NameLocationTypeRequiredDescription
limitqueryintegerNo—
Complete parameter definitions
[
  {
    "in": "query",
    "name": "limit",
    "required": false,
    "schema": {
      "default": 100,
      "title": "Limit",
      "type": "integer"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_audit_api_v1_audit_get",
  "parameters": [
    {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
        "default": 100,
        "title": "Limit",
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Audit",
  "tags": [
    "Credentials"
  ]
}

Version

1 operations
GET/api/v1/versionVersion

Operation ID version_api_v1_version_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[]
Complete OpenAPI operation
{
  "operationId": "version_api_v1_version_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "summary": "Version"
}

Diagrams

1 operations
GET/api/v1/diagrams/catalogDiagrams Catalog

Diagrams Catalog

Supported architecture nodes, provenance, bounds, and the JSON fence schema.

Operation ID diagrams_catalog_api_v1_diagrams_catalog_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "description": "Supported architecture nodes, provenance, bounds, and the JSON fence schema.",
  "operationId": "diagrams_catalog_api_v1_diagrams_catalog_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Diagrams Catalog",
  "tags": [
    "Rendering and generation jobs"
  ]
}

Library

7 operations
GET/api/v1/library/categoriesCategories

Categories

Operation ID categories_api_v1_library_categories_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "categories_api_v1_library_categories_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Categories",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/imagesList Images

List Images

Operation ID list_images_api_v1_library_images_get

Parameters
NameLocationTypeRequiredDescription
qquerystringNo—
categoryquerystring | nullNo—
tagquerystring | nullNo—
usablequeryboolean | nullNo—
limitqueryintegerNo—
offsetqueryintegerNo—
Complete parameter definitions
[
  {
    "in": "query",
    "name": "q",
    "required": false,
    "schema": {
      "default": "",
      "maxLength": 200,
      "title": "Q",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "category",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 80,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Category"
    }
  },
  {
    "in": "query",
    "name": "tag",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "maxLength": 80,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Tag"
    }
  },
  {
    "in": "query",
    "name": "usable",
    "required": false,
    "schema": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Usable"
    }
  },
  {
    "in": "query",
    "name": "limit",
    "required": false,
    "schema": {
      "default": 50,
      "maximum": 200,
      "minimum": 1,
      "title": "Limit",
      "type": "integer"
    }
  },
  {
    "in": "query",
    "name": "offset",
    "required": false,
    "schema": {
      "default": 0,
      "maximum": 100000,
      "minimum": 0,
      "title": "Offset",
      "type": "integer"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "list_images_api_v1_library_images_get",
  "parameters": [
    {
      "in": "query",
      "name": "q",
      "required": false,
      "schema": {
        "default": "",
        "maxLength": 200,
        "title": "Q",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "category",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "maxLength": 80,
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Category"
      }
    },
    {
      "in": "query",
      "name": "tag",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "maxLength": 80,
            "type": "string"
          },
          {
            "type": "null"
          }
        ],
        "title": "Tag"
      }
    },
    {
      "in": "query",
      "name": "usable",
      "required": false,
      "schema": {
        "anyOf": [
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ],
        "title": "Usable"
      }
    },
    {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
        "default": 50,
        "maximum": 200,
        "minimum": 1,
        "title": "Limit",
        "type": "integer"
      }
    },
    {
      "in": "query",
      "name": "offset",
      "required": false,
      "schema": {
        "default": 0,
        "maximum": 100000,
        "minimum": 0,
        "title": "Offset",
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "List Images",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/images/{image_id}Image Details

Image Details

Operation ID image_details_api_v1_library_images__image_id__get

Parameters
NameLocationTypeRequiredDescription
image_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "image_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Image Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "image_details_api_v1_library_images__image_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "image_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Image Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Image Details",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/images/{image_id}/versionsVersions

Operation ID versions_api_v1_library_images__image_id__versions_get

Parameters
NameLocationTypeRequiredDescription
image_idpathstring (uuid)Yes—
limitqueryintegerNo—
offsetqueryintegerNo—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "image_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Image Id",
      "type": "string"
    }
  },
  {
    "in": "query",
    "name": "limit",
    "required": false,
    "schema": {
      "default": 50,
      "maximum": 200,
      "minimum": 1,
      "title": "Limit",
      "type": "integer"
    }
  },
  {
    "in": "query",
    "name": "offset",
    "required": false,
    "schema": {
      "default": 0,
      "maximum": 100000,
      "minimum": 0,
      "title": "Offset",
      "type": "integer"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "versions_api_v1_library_images__image_id__versions_get",
  "parameters": [
    {
      "in": "path",
      "name": "image_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Image Id",
        "type": "string"
      }
    },
    {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
        "default": 50,
        "maximum": 200,
        "minimum": 1,
        "title": "Limit",
        "type": "integer"
      }
    },
    {
      "in": "query",
      "name": "offset",
      "required": false,
      "schema": {
        "default": 0,
        "maximum": 100000,
        "minimum": 0,
        "title": "Offset",
        "type": "integer"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Versions",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/images/{image_id}/versions/{version_id}Version Details

Version Details

Operation ID version_details_api_v1_library_images__image_id__versions__version_id__get

Parameters
NameLocationTypeRequiredDescription
image_idpathstring (uuid)Yes—
version_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "image_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Image Id",
      "type": "string"
    }
  },
  {
    "in": "path",
    "name": "version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "version_details_api_v1_library_images__image_id__versions__version_id__get",
  "parameters": [
    {
      "in": "path",
      "name": "image_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Image Id",
        "type": "string"
      }
    },
    {
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Version Details",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/images/{image_id}/versions/{version_id}/downloadDownload

Operation ID download_api_v1_library_images__image_id__versions__version_id__download_get

Parameters
NameLocationTypeRequiredDescription
image_idpathstring (uuid)Yes—
version_idpathstring (uuid)Yes—
Complete parameter definitions
[
  {
    "in": "path",
    "name": "image_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Image Id",
      "type": "string"
    }
  },
  {
    "in": "path",
    "name": "version_id",
    "required": true,
    "schema": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  }
]
Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
422Validation Error
{
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/HTTPValidationError"
      }
    }
  },
  "description": "Validation Error"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "download_api_v1_library_images__image_id__versions__version_id__download_get",
  "parameters": [
    {
      "in": "path",
      "name": "image_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Image Id",
        "type": "string"
      }
    },
    {
      "in": "path",
      "name": "version_id",
      "required": true,
      "schema": {
        "format": "uuid",
        "title": "Version Id",
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    },
    "422": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/HTTPValidationError"
          }
        }
      },
      "description": "Validation Error"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Download",
  "tags": [
    "Public image library"
  ]
}
GET/api/v1/library/tagsTags

Operation ID tags_api_v1_library_tags_get

Parameters

No path, query, header, or cookie parameters are declared.

Request body

No request body is declared.

Responses
200Successful Response
{
  "content": {
    "application/json": {
      "schema": {}
    }
  },
  "description": "Successful Response"
}
OpenAPI security declaration

See the guide for browser session authentication, CSRF protection, and token permissions. An empty declaration only indicates that OpenAPI defines no security scheme here.

[
  {
    "HTTPBearer": []
  }
]
Complete OpenAPI operation
{
  "operationId": "tags_api_v1_library_tags_get",
  "responses": {
    "200": {
      "content": {
        "application/json": {
          "schema": {}
        }
      },
      "description": "Successful Response"
    }
  },
  "security": [
    {
      "HTTPBearer": []
    }
  ],
  "summary": "Tags",
  "tags": [
    "Public image library"
  ]
}

03 / DATA MODELS

Schema definitions.

21 models

Exact component schemas, including required properties, constraints, enums, nullable values, and references. Names are case-sensitive.

Body_logout_auth_logout_post
{
  "properties": {
    "csrf": {
      "title": "Csrf",
      "type": "string"
    }
  },
  "required": [
    "csrf"
  ],
  "title": "Body_logout_auth_logout_post",
  "type": "object"
}
Body_upload_asset_api_v1_assets_upload_post
{
  "properties": {
    "asset_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Id"
    },
    "file": {
      "contentMediaType": "application/octet-stream",
      "title": "File",
      "type": "string"
    },
    "name": {
      "default": "Image",
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "file"
  ],
  "title": "Body_upload_asset_api_v1_assets_upload_post",
  "type": "object"
}
BranchCreate
{
  "additionalProperties": false,
  "properties": {
    "from_version_id": {
      "format": "uuid",
      "title": "From Version Id",
      "type": "string"
    },
    "name": {
      "maxLength": 255,
      "minLength": 1,
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "name",
    "from_version_id"
  ],
  "title": "BranchCreate",
  "type": "object"
}
ConnectionCreate
{
  "properties": {
    "api_key": {
      "format": "password",
      "maxLength": 256,
      "minLength": 16,
      "title": "Api Key",
      "type": "string",
      "writeOnly": true
    },
    "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "name",
    "api_key"
  ],
  "title": "ConnectionCreate",
  "type": "object"
}
ConnectionUpdate
{
  "properties": {
    "api_key": {
      "anyOf": [
        {
          "format": "password",
          "maxLength": 256,
          "minLength": 16,
          "type": "string",
          "writeOnly": true
        },
        {
          "type": "null"
        }
      ],
      "title": "Api Key"
    },
    "name": {
      "anyOf": [
        {
          "maxLength": 100,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Name"
    }
  },
  "title": "ConnectionUpdate",
  "type": "object"
}
DeckCreate
{
  "additionalProperties": false,
  "properties": {
    "asset_versions": {
      "anyOf": [
        {
          "additionalProperties": {
            "format": "uuid",
            "type": "string"
          },
          "propertyNames": {
            "format": "uuid"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Versions"
    },
    "description": {
      "default": "",
      "maxLength": 20000,
      "title": "Description",
      "type": "string"
    },
    "markdown": {
      "default": "",
      "maxLength": 200000,
      "title": "Markdown",
      "type": "string"
    },
    "message": {
      "default": "Initial version",
      "maxLength": 10000,
      "title": "Message",
      "type": "string"
    },
    "name": {
      "maxLength": 255,
      "minLength": 1,
      "title": "Name",
      "type": "string"
    },
    "project_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Project Id"
    }
  },
  "required": [
    "name"
  ],
  "title": "DeckCreate",
  "type": "object"
}
DeckUpdate
{
  "additionalProperties": false,
  "properties": {
    "archived": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Archived"
    },
    "asset_versions": {
      "anyOf": [
        {
          "additionalProperties": {
            "format": "uuid",
            "type": "string"
          },
          "propertyNames": {
            "format": "uuid"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Versions"
    },
    "description": {
      "anyOf": [
        {
          "maxLength": 20000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Description"
    },
    "expected_version_id": {
      "format": "uuid",
      "title": "Expected Version Id",
      "type": "string"
    },
    "markdown": {
      "anyOf": [
        {
          "maxLength": 200000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Markdown"
    },
    "message": {
      "default": "Update document",
      "maxLength": 10000,
      "title": "Message",
      "type": "string"
    },
    "name": {
      "anyOf": [
        {
          "maxLength": 255,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Name"
    },
    "project_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Project Id"
    }
  },
  "required": [
    "expected_version_id"
  ],
  "title": "DeckUpdate",
  "type": "object"
}
ExportCreate
{
  "properties": {
    "font_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Font Id"
    },
    "format": {
      "enum": [
        "pdf",
        "pptx",
        "png",
        "png_zip"
      ],
      "title": "Format",
      "type": "string"
    },
    "slide_number": {
      "anyOf": [
        {
          "minimum": 1.0,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "title": "Slide Number"
    },
    "version_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Version Id"
    }
  },
  "required": [
    "format"
  ],
  "title": "ExportCreate",
  "type": "object"
}
GenerationCreate
{
  "properties": {
    "aspect_ratio": {
      "default": "16:9",
      "title": "Aspect Ratio",
      "type": "string"
    },
    "asset_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Id"
    },
    "connection_id": {
      "format": "uuid",
      "title": "Connection Id",
      "type": "string"
    },
    "model_key": {
      "maxLength": 30,
      "title": "Model Key",
      "type": "string"
    },
    "output_format": {
      "default": "png",
      "title": "Output Format",
      "type": "string"
    },
    "prompt": {
      "maxLength": 6000,
      "minLength": 1,
      "title": "Prompt",
      "type": "string"
    },
    "quality": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Quality"
    },
    "reference_version_ids": {
      "items": {
        "format": "uuid",
        "type": "string"
      },
      "maxItems": 16,
      "title": "Reference Version Ids",
      "type": "array"
    },
    "resolution": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Resolution"
    },
    "seed": {
      "anyOf": [
        {
          "maximum": 2147483647.0,
          "minimum": 0.0,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "title": "Seed"
    }
  },
  "required": [
    "connection_id",
    "model_key",
    "prompt"
  ],
  "title": "GenerationCreate",
  "type": "object"
}
HTTPValidationError
{
  "properties": {
    "detail": {
      "items": {
        "$ref": "#/components/schemas/ValidationError"
      },
      "title": "Detail",
      "type": "array"
    }
  },
  "title": "HTTPValidationError",
  "type": "object"
}
IssueCreate
{
  "additionalProperties": false,
  "properties": {
    "body": {
      "default": "",
      "maxLength": 100000,
      "title": "Body",
      "type": "string"
    },
    "priority": {
      "default": "normal",
      "enum": [
        "low",
        "normal",
        "high"
      ],
      "title": "Priority",
      "type": "string"
    },
    "status": {
      "default": "todo",
      "enum": [
        "todo",
        "in_progress",
        "done"
      ],
      "title": "Status",
      "type": "string"
    },
    "title": {
      "maxLength": 255,
      "minLength": 1,
      "title": "Title",
      "type": "string"
    }
  },
  "required": [
    "title"
  ],
  "title": "IssueCreate",
  "type": "object"
}
IssueUpdate
{
  "additionalProperties": false,
  "properties": {
    "archived": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Archived"
    },
    "body": {
      "anyOf": [
        {
          "maxLength": 100000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Body"
    },
    "expected_revision": {
      "minimum": 1.0,
      "title": "Expected Revision",
      "type": "integer"
    },
    "priority": {
      "anyOf": [
        {
          "enum": [
            "low",
            "normal",
            "high"
          ],
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Priority"
    },
    "status": {
      "anyOf": [
        {
          "enum": [
            "todo",
            "in_progress",
            "done"
          ],
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Status"
    },
    "title": {
      "anyOf": [
        {
          "maxLength": 255,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Title"
    }
  },
  "required": [
    "expected_revision"
  ],
  "title": "IssueUpdate",
  "type": "object"
}
Merge
{
  "additionalProperties": false,
  "properties": {
    "asset_versions": {
      "anyOf": [
        {
          "additionalProperties": {
            "format": "uuid",
            "type": "string"
          },
          "propertyNames": {
            "format": "uuid"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Versions"
    },
    "expected_version_id": {
      "format": "uuid",
      "title": "Expected Version Id",
      "type": "string"
    },
    "markdown": {
      "anyOf": [
        {
          "maxLength": 200000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Markdown"
    },
    "message": {
      "default": "Merge branch",
      "maxLength": 10000,
      "title": "Message",
      "type": "string"
    },
    "source_branch_id": {
      "format": "uuid",
      "title": "Source Branch Id",
      "type": "string"
    },
    "target_branch_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Target Branch Id"
    }
  },
  "required": [
    "source_branch_id",
    "expected_version_id"
  ],
  "title": "Merge",
  "type": "object"
}
PreviewCreate
{
  "properties": {
    "asset_versions": {
      "anyOf": [
        {
          "additionalProperties": {
            "type": "string"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Versions"
    },
    "deck_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Deck Id"
    },
    "font_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Font Id"
    },
    "markdown": {
      "anyOf": [
        {
          "maxLength": 200000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Markdown"
    },
    "version_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Version Id"
    }
  },
  "title": "PreviewCreate",
  "type": "object"
}
ProjectCreate
{
  "additionalProperties": false,
  "properties": {
    "description": {
      "default": "",
      "maxLength": 20000,
      "title": "Description",
      "type": "string"
    },
    "name": {
      "maxLength": 255,
      "minLength": 1,
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "name"
  ],
  "title": "ProjectCreate",
  "type": "object"
}
ProjectUpdate
{
  "additionalProperties": false,
  "properties": {
    "archived": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "title": "Archived"
    },
    "description": {
      "anyOf": [
        {
          "maxLength": 20000,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Description"
    },
    "name": {
      "anyOf": [
        {
          "maxLength": 255,
          "minLength": 1,
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Name"
    }
  },
  "title": "ProjectUpdate",
  "type": "object"
}
PublicLinkCreate
{
  "additionalProperties": false,
  "properties": {
    "acknowledge_public": {
      "description": "Must be true: anyone with the URL can download this export.",
      "title": "Acknowledge Public",
      "type": "boolean"
    }
  },
  "required": [
    "acknowledge_public"
  ],
  "title": "PublicLinkCreate",
  "type": "object"
}
Restore
{
  "additionalProperties": false,
  "properties": {
    "expected_version_id": {
      "format": "uuid",
      "title": "Expected Version Id",
      "type": "string"
    },
    "message": {
      "default": "Restore version",
      "maxLength": 10000,
      "title": "Message",
      "type": "string"
    },
    "version_id": {
      "format": "uuid",
      "title": "Version Id",
      "type": "string"
    }
  },
  "required": [
    "expected_version_id",
    "version_id"
  ],
  "title": "Restore",
  "type": "object"
}
TokenCreate
{
  "properties": {
    "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
    }
  },
  "required": [
    "name"
  ],
  "title": "TokenCreate",
  "type": "object"
}
ValidationError
{
  "properties": {
    "ctx": {
      "title": "Context",
      "type": "object"
    },
    "input": {
      "title": "Input"
    },
    "loc": {
      "items": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "integer"
          }
        ]
      },
      "title": "Location",
      "type": "array"
    },
    "msg": {
      "title": "Message",
      "type": "string"
    },
    "type": {
      "title": "Error Type",
      "type": "string"
    }
  },
  "required": [
    "loc",
    "msg",
    "type"
  ],
  "title": "ValidationError",
  "type": "object"
}
VersionCreate
{
  "additionalProperties": false,
  "properties": {
    "asset_versions": {
      "anyOf": [
        {
          "additionalProperties": {
            "format": "uuid",
            "type": "string"
          },
          "propertyNames": {
            "format": "uuid"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "title": "Asset Versions"
    },
    "branch_id": {
      "anyOf": [
        {
          "format": "uuid",
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Branch Id"
    },
    "expected_version_id": {
      "format": "uuid",
      "title": "Expected Version Id",
      "type": "string"
    },
    "markdown": {
      "maxLength": 200000,
      "title": "Markdown",
      "type": "string"
    },
    "message": {
      "default": "",
      "maxLength": 10000,
      "title": "Message",
      "type": "string"
    }
  },
  "required": [
    "expected_version_id",
    "markdown"
  ],
  "title": "VersionCreate",
  "type": "object"
}