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-Keyis 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 409idempotency_key_retiredand the search must be sent again with a new key. Reusing a key with a different request body returns 409idempotency_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
Locationheader pointing at the operation resource. Poll it until the operation completes. - Output format is chosen by content negotiation: set
Acceptto a versioned media type. - Conditional reads: send
If-None-Matchwith a storedETagto receive 304 when nothing changed. - Convert-family errors are
application/problem+jsonwith a machine-readablecodeand arequestId. Corpus and create errors areapplication/jsonwith{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 includeX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Bucket, andX-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.