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

Corpus search and reference reads are free and accept anonymous requests without an API key, browser session, or Turnstile challenge. Hedge mode requires account authentication; Direct, Balanced, Adventurer, image-conditioned search, and logo search support anonymous access. An optional Bearer key with design.corpus.retrieve uses the larger account search allowance. Invalid supplied credentials return an authentication error rather than switching to anonymous access.

Authenticated creation and conversion requests use 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 (account corpus access and create endpoints). The anonymous in-browser creation and conversion previews use their existing public quota tier.

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, create, document-revision, reference-assets). Replaying the same key returns the original result and is never double-billed. Keep the same key when retrying free corpus searches to reuse the original retrieval; a search made without an account replays for 90 days, after which its key returns 409 idempotency_key_retired and the search must be sent again with a new key. 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}.
  • Daily quota buckets reset at midnight UTC; corpus also has per-minute query and read limits. Exceeding a limit returns 429 with Retry-After. Daily quota responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Bucket, and X-RateLimit-Reset.

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

Free design-reference retrieval, available anonymously or with a Bearer API key carrying design.corpus.retrieve. Search and reference reads never debit a wallet. Anonymous callers get 1,000 queries per UTC day; authenticated callers get 2,000. Limits of 30 queries and 120 reads per minute apply per network address. Anonymous searches return at most 24 references.

POST /api/v1/corpus/inspire

Ranked design-reference retrieval. JSON body: {q, mode: direct|balanced|adventurer|hedge, k, seed?, referenceImage?}, with k from 1 to 24 anonymously or 1 to 480 with account authentication. Returns a reference set with scored items and rendition URLs. A referenceImage is available to anonymous and authenticated callers; use direct, balanced, or adventurer with it. hedge requires account authentication, remains free, and carries per-reference retrieval evidence for trusted consumers; anonymous Hedge requests receive 403 mode_requires_account. seed remains account-tier only.

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

POST /api/v1/corpus/logos/search

Find reference logo symbols from an explicit logo or brand-mark query. This search is free for anonymous and authenticated callers, uses the daily and per-minute search limits above, and returns at most 24 references anonymously or 60 with account authentication.

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.

Free anonymous and authenticated reads: 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

Daily 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: 1,000 / 2,000, with no wallet overflow. Searches include logo and image-conditioned queries and share a 30-query-per-minute limit per network address. Anonymous searches return at most 24 references. Corpus reads have a separate 120-read-per-minute limit per network address.
  • 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.