12ui API

v1 · 12ui.com/api/v1

Everything below is a hosted API on one base URL: https://12ui.com, with every endpoint under /api/v1. The API does one thing: images in, structured design documents and exports out. You submit a PNG, JPEG, or WebP screenshot and receive a versioned LayerDoc - a structured, editable design document - or any of its export formats, from responsive HTML to PSD. Around that core sit corpus search (ranked design-reference retrieval) and draft generation (concept-to-candidate image runs). Media types carry explicit versions, such as application/vnd.12ui.layerdoc+json;version=2.

Authentication

Requests are authorised with Bearer API keys. Get a key through the skill installer (npx -y @12ui/design skill install) or 12ui auth login; keys are managed at login.justevery.com. Keys carry two scopes: design.convert (convert and edit endpoints) and design.corpus.retrieve (corpus and create endpoints). The anonymous in-browser preview runs at the lower public quota tier; API-key callers run at the account tier and never see a Turnstile challenge.

curl https://12ui.com/api/v1/convert/quota \
  -H "Authorization: Bearer $TWELVE_UI_API_KEY"

Conventions

  • Idempotency-Key is required on every paid POST (convert, edit, package, corpus inspire, create, document-revision, reference-assets). Replaying the same key returns the original result and is never double-billed. Reusing a key with a different request body returns 409 idempotency_conflict.
  • Prefer: wait=<0..20> on convert and edit POST and GET holds the request open for up to 20 seconds before falling back to polling state.
  • Asynchronous operations return a Location header pointing at the operation resource. Poll it until the operation completes.
  • Output format is chosen by content negotiation: set Accept to a versioned media type.
  • Conditional reads: send If-None-Match with a stored ETag to receive 304 when nothing changed.
  • Convert-family errors are application/problem+json with a machine-readable code and a requestId. Corpus and create errors are application/json with {error, message}.
  • Rate limits are per-UTC-day buckets, reported in X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Bucket, and X-RateLimit-Reset. Exceeding a bucket returns 429 with Retry-After.

Convert

The conversion pipeline. All endpoints in this section require the design.convert scope.

POST /api/v1/convert

Convert one PNG, JPEG, or WebP - or an existing LayerDoc - into a versioned LayerDoc or any export format. Send multipart/form-data with file (or layerdoc, or source_conversion_id), output, model (fast | standard | pro), width, profile, and responsive_quality. Returns a ConversionOperation (202, or 200 when finished within the wait window).

curl -X POST https://12ui.com/api/v1/convert \
  -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
  -H "Idempotency-Key: demo-hero-1" \
  -F "file=@screenshot.png" \
  -F "output=layerdoc" \
  -F "model=standard"

GET /api/v1/convert/{id}

Poll conversion status, or fetch the finished artifact via Accept negotiation: LayerDoc JSON, responsive HTML, fixed HTML, SVG, PNG, JPEG, WebP, PDF, PSD, PPTX, Sketch, responsive bundle zip, web-project zip, or app-project zip. Returns 410 once the artifact has been removed by automated cleanup.

curl https://12ui.com/api/v1/convert/cnv_123 \
  -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
  -H "Accept: application/vnd.12ui.layerdoc+json;version=2"

GET /api/v1/convert/quota

Authoritative daily quota snapshot: {tier, resets_at, buckets}.

GET /api/v1/convert/history

List the account's conversions. DELETE /api/v1/convert/history/{id} hides a single entry. Account only.

POST /api/v1/convert/package

Multi-page package: a manifest plus screenshots, converted page by page and composed into a unified static site zip. GET /api/v1/convert/package/{id} reports status, GET /api/v1/convert/package/{id}/result downloads the zip, and GET /api/v1/convert/package/{id}/pages/{pageId} 307-redirects to the underlying page conversion. Account only.

GET /api/v1/convert/{id}/responsive-export

Recover the latest retained responsive HTML derived from a source conversion, with ?quality=standard|pro. Account only.

GET/POST /api/v1/convert/{id}/document-revision

Read and persist immutable LayerDoc revisions - the editing trail for a conversion.

POST /api/v1/convert/{id}/reference-assets

Upload immutable reference images used to guide later edits, at most 20 MiB and 8 MP each. Account only.

POST /api/v1/convert/{id}/image-edit

One generative image edit against a conversion. Operations: remove-background, prompt, generate-region.

POST /api/v1/edit

Natural-language LayerDoc edit: input LayerDoc plus a prompt of at most 8192 characters; always returns a LayerDoc. Poll with GET /api/v1/edit/{id}.

Corpus

Design-reference retrieval. All endpoints in this section require the design.corpus.retrieve scope.

POST /api/v1/corpus/inspire

Ranked design-reference retrieval. JSON body: {q, mode: direct|balanced|adventurer|hedge, k, seed?, referenceImage?}. Returns a reference set with scored items and rendition URLs. hedge carries per-reference retrieval evidence for trusted consumers; seed and referenceImage are account-tier only.

curl -X POST https://12ui.com/api/v1/corpus/inspire \
  -H "Authorization: Bearer $TWELVE_UI_API_KEY" \
  -H "Idempotency-Key: search-cafe-1" \
  -H "Content-Type: application/json" \
  -d '{"q":"warm cafe brand homepage","mode":"balanced","k":4}'

GET /api/v1/corpus/featured

The daily featured edition. No query cost.

GET /api/v1/corpus/designs/{designId}

Resolve a shared design id.

GET /api/v1/corpus/references/{referenceId}/image

Immutable WebP rendition of a reference, with ?size=thumb|thumb-hd|ref|ref-hd. Publicly cacheable.

Account-only companions: GET /api/v1/corpus/references/{referenceId} (full metadata), GET /api/v1/corpus/references/{referenceId}/profile (the 39-dimension score profile), and GET /api/v1/corpus/status (active release info).

Create

Draft generation runs. All endpoints in this section require the design.corpus.retrieve scope.

POST /api/v1/create

Claim a draft run: {concept ≤1200 chars, aspect, mode, retain?, candidates} with 1–96 unique slots from a–cr, where each candidate may carry a referenceId or an uploaded referenceImage. retain accepts a string, array, or semantic include/exclude object; a referenced new page defaults to style without layout, content, or assets, while layout is the explicit preserve-structure opt-in. Alternatively claim a build run - {source: "build", winner: {createRunId, slot}} - planning 2–8 screens across slots a–h. Returns 201 (or 200 on idempotent replay) with the run envelope. Runs stay readable for 7 days.

GET /api/v1/create/{runId}

Durable run state.

POST /api/v1/create/{runId}/candidates/{slot}

Dispatch exactly one image generation for that slot. Returns 409 while a generation for the slot is in flight.

GET /api/v1/create/{runId}/candidates/{slot}/image

The finished PNG for a candidate slot. The ETag is the image's sha256.

Status

  • GET /api/status - API/raster health: {status, service, buildRevision, rasterBuildRevision, compatible, ...}. No auth.
  • GET /api/runtime-env - browser bootstrap configuration. No auth.

Quotas

All buckets reset per UTC day; limits are public tier / account tier.

  • Conversions: fast 5 / 50, standard 2 / 20, pro 0 / 2.
  • Exports: 20 / 200.
  • LayerDoc edits: 2 / 20.
  • Image actions: 5 / 30, shared by Design-edit raster operations, direct image edits, and background removals.
  • Corpus queries: 100 / 2000.
  • Draft and Branch images: 12 / 20, shared.
  • At most 10 conversions may be active per account at once.
  • Conversion artifacts are removed by automated cleanup once they are no longer needed; later fetches return 410.

Errors

Convert-family endpoints return application/problem+json - type, title, status, detail, plus a machine-readable code, a requestId for support, and a retryable flag. Corpus and create endpoints return application/json with {error, message}. Common statuses: 400 (malformed request), 401 (missing or invalid key), 403 (scope or tier), 404 (unknown resource), 409 (idempotency_conflict, or a create slot already in flight), 410 (artifact expired), and 429 (bucket exhausted - honour Retry-After). Include the requestId when writing to support@12ui.com.

Most integrations never call these endpoints by hand: the skill wraps the full API for agents and the CLI, and the in-browser studio at /convert drives the same pipeline with no setup.