{"openapi":"3.1.0","info":{"title":"Formatry API","version":"2026-06-18","summary":"Metered creative-pack generation API for scoped keys, balance checks, uploads, requests, and ready files."},"servers":[{"url":"/","description":"Current Formatry origin"}],"tags":[{"name":"Codex"},{"name":"Balance"},{"name":"Usage"},{"name":"API Keys"},{"name":"Assets"},{"name":"Previews"},{"name":"Jobs"},{"name":"Artifacts"}],"x-formatry-cc-consumer-contract":{"authentication":{"acceptedHeaders":["Authorization: Bearer <api-key>","X-API-Key: <api-key>"],"secretHandling":"API key secrets are shown only when created, stored hashed, and can be revoked.","scopes":{"balance:read":["GET /api/v1/balance","GET /api/v1/usage"],"assets:read":["GET /api/v1/assets","GET /api/v1/assets/{assetId}"],"assets:write":["DELETE /api/v1/assets/{assetId}","POST /api/v1/assets/uploads","PUT /api/v1/assets/uploads/{uploadId}/object","POST /api/v1/assets/uploads/{uploadId}/complete","PUT /api/v1/assets/upload-object"],"jobs:write":["POST /api/v1/jobs","POST /api/v1/jobs/{jobId}/cancel"],"jobs:read":["GET /api/v1/jobs","GET /api/v1/jobs/{jobId}"],"artifacts:read":["GET /api/v1/artifacts/{artifactId}","GET /api/v1/artifacts/{artifactId}/download","GET /api/v1/artifacts/{artifactId}/files/{fileId}/download"],"deliveries:write":["POST /api/account/artifacts/{artifactId}/destinations via account session"],"previews:read":["GET /api/v1/previews/quota"],"previews:write":["POST /api/v1/previews"],"api-keys:read":["GET /api/v1/api-keys"],"api-keys:write":["POST /api/v1/api-keys","DELETE /api/v1/api-keys/{apiKeyId}"]}},"codexTrial":{"claimEndpoint":"POST /api/v1/codex/trial-key","authMode":"public-codex-trial","creditGrant":"5 credits per hour for each hashed IP, user agent, and client marker identity.","privacy":"The trial limiter stores HMAC hashes only. Raw IP addresses, user agents, client markers, API keys, and signed URLs must not be logged or exposed in evidence.","followOnFlow":"Use the returned scoped API key only for balance, asset upload, job creation, job polling, and artifact download routes. Treat the returned secret as one-time session material."},"balance":{"checkEndpoint":"GET /api/v1/balance","debitPoint":"POST /api/v1/jobs","unit":"credit","insufficientFundsStatus":402,"retrySafety":"Accepted and replayed job requests reserve balance once for the same Idempotency-Key and body."},"liveHandoff":{"contractVsProof":"The OpenAPI schema describes the customer contract. A live paid loop is proven only against a configured Formatry origin with a scoped key, paid balance or quota, enabled uploads, generation processing, and artifact delivery.","readySignals":["GET /api/v1/balance returns usable credits, subscription quota, or unlimited access for the workspace.","Upload intent and completion return a ready workspace asset before the job is created.","POST /api/v1/jobs returns a queued or existing job with the expected cost and one balance reservation.","GET /api/v1/jobs/{jobId} reaches succeeded before an artifactId is used.","GET /api/v1/artifacts/{artifactId} returns a ready manifest before the download endpoint is called."],"blockedSignals":{"401":"Missing or invalid key.","402":"Paid access is not sufficient for the requested output sizes.","403":"Key is valid but does not include the required scope.","409":"Retry data, asset readiness, or job state conflicts with the requested action.","422":"The named asset, slot, size, combination, or output format is unsupported.","429":"The route or protected-preview allowance is exhausted until the returned retry or reset time.","501":"The endpoint exists, but this origin is not configured for the required paid-loop service."},"evidencePolicy":"Live evidence should store route status, balance numbers, job and artifact ids, manifest file metadata, and checksum match results. Do not store API keys, upload URLs, download URLs, cookies, or payment details."},"flow":["Check connection, balance, and protected-preview quota.","Create an upload intent.","Upload file bytes to the returned URL with the returned headers and the same API key.","Complete the upload.","Create one bounded protected preview when visual confirmation is useful.","Create a paid pack request with ready asset ids.","Poll or cancel the job. Continue only after status is succeeded and artifactId is available.","Read the artifact manifest and require status ready with at least one file.","Download a verified manifest file through the scoped file route, or request short-lived metadata for a client-managed transfer."],"jobs":{"states":["queued","running","succeeded","failed","canceled"],"artifactRule":"Use artifactId only after the job is succeeded. Null artifactId means the request has no downloadable artifact yet.","cancelRule":"Queued jobs can be canceled to release the reservation. Jobs already in progress cannot be canceled."},"artifacts":{"manifestEndpoint":"GET /api/v1/artifacts/{artifactId}","downloadEndpoint":"GET /api/v1/artifacts/{artifactId}/download","fileDownloadEndpoint":"GET /api/v1/artifacts/{artifactId}/files/{fileId}/download","readinessRule":"Read the manifest first. Request download information only when the artifact status is ready and the manifest lists the expected files."},"assets":{"maxUploadByteLength":26214400,"maxUploadMegabytes":25,"maxImageEdgePixels":8192,"maxImagePixels":48000000,"minimumRasterShortEdgeBySlot":{"logo":128,"background":512,"media":360,"product":256,"person":256,"device":360},"supportedAssetInputs":{"logo":{"accepts":["image/svg+xml","image/png","image/jpeg","image/webp"],"bestFor":"Use SVG for marks and compact brand logos. Raster logos are accepted by the upload validator but SVG is the preferred integration input."},"background":{"accepts":["image/png","image/jpeg","image/webp"],"bestFor":"Use full-canvas environment, texture, or campaign background imagery."},"media":{"accepts":["image/png","image/jpeg","image/webp"],"bestFor":"Use the primary campaign visual, app screen, editorial image, or product-in-context image."},"secondaryMedia":{"accepts":["image/png","image/jpeg","image/webp"],"bestFor":"Use only with media when the creative needs a second screen or supporting visual.","requires":["media"]},"product":{"accepts":["image/png","image/jpeg","image/webp"],"bestFor":"Use one contained product shot. Do not mix product with media, secondaryMedia, device, or person in one job.","cannotMixWith":["media","secondaryMedia","device","person"]},"person":{"accepts":["image/png","image/webp"],"bestFor":"Use one person or presenter cutout. PNG or WebP with transparency is preferred.","cannotMixWith":["media","secondaryMedia","device","product"]},"device":{"accepts":["image/png","image/jpeg","image/webp"],"bestFor":"Use one complete device visual. Do not mix device with media or secondaryMedia.","cannotMixWith":["media","secondaryMedia"]},"font":{"accepts":["font/otf","font/ttf"],"bestFor":"Use one TTF or OTF brand font. Font uploads must not include width or height metadata."}},"agentSelectionRule":"For an unknown campaign image, choose media. Choose product only for a single contained product shot, person only for a person cutout, device only for a complete device visual, background only for full-canvas scenery, logo only for a brand mark, and font only for TTF/OTF typography.","unsupportedCombinations":["secondaryMedia requires media in the same job.","product or person cannot be mixed with media, secondaryMedia, or device.","device cannot be mixed with media or secondaryMedia."]},"idempotency":{"header":"Idempotency-Key","requiredFor":["POST /api/v1/assets/uploads","POST /api/v1/assets/uploads/{uploadId}/complete","POST /api/v1/jobs"],"replayStatus":200,"conflictStatus":409},"errors":{"envelope":"{ ok: false, error: { code, message, httpStatus, requestId, details? }, meta }","failClosed":"Invalid requests, missing scopes, insufficient paid access, conflicting retries, unready assets, and unconfigured providers return explicit error envelopes instead of creating jobs, exposing files, or falling back to demo data.","commonStatuses":[400,401,402,403,409,429,501]},"rateLimits":{"successfulResponseHeaders":["X-Request-ID","X-RateLimit-Limit","X-RateLimit-Remaining","X-RateLimit-Reset"],"exhaustedResponseHeaders":["Retry-After","X-Request-ID","X-RateLimit-Limit","X-RateLimit-Remaining","X-RateLimit-Reset"],"recovery":"Treat X-RateLimit-Reset as the authoritative retry deadline; use Retry-After on 429 for an immediate delay."}},"paths":{"/api/v1/codex/trial-key":{"post":{"tags":["Codex"],"summary":"Claim a temporary Codex plugin trial key.","description":"Creates a one-hour trial workspace, grants five credits, and returns a scoped API key for the same paid-loop API. The limiter uses a server-side HMAC of IP, user agent, and client marker; raw identifiers are not stored.","x-formatry-cc-auth-mode":"public-codex-trial","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodexTrialKeyRequest"}}}},"responses":{"201":{"description":"Temporary Codex trial key. The secret is returned once and must be handled like any API key.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/CodexTrialKeyResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/balance":{"get":{"tags":["Balance"],"summary":"Read the workspace credit balance for the API key.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"balance:read","responses":{"200":{"description":"Workspace balance.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/BalanceResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/usage":{"get":{"tags":["Usage"],"summary":"List recent workspace usage ledger events.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"balance:read","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/BeforeLedgerCursor"}],"responses":{"200":{"description":"Workspace usage ledger page.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/UsageLedgerResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/api-keys":{"get":{"tags":["API Keys"],"summary":"List workspace API keys without exposing secrets.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"api-keys:read","responses":{"200":{"description":"Workspace API keys.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/ApiKeyListResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}},"post":{"tags":["API Keys"],"summary":"Create a workspace API key and return its secret once.","description":"Requires api-keys:write and paid workspace access or an explicit positive balance. A caller can only grant scopes already present on the authenticating key. The plaintext secret is returned only in this creation response and is never stored.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"api-keys:write","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreateRequest"}}}},"responses":{"201":{"description":"Created API key with one-time secret.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/ApiKeyCreateResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/api-keys/{apiKeyId}":{"delete":{"tags":["API Keys"],"summary":"Revoke one workspace API key.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"api-keys:write","parameters":[{"$ref":"#/components/parameters/ApiKeyId"}],"responses":{"200":{"description":"Revoked API key.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/ApiKeyRevokeResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/ApiKeyNotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/assets":{"get":{"tags":["Assets"],"summary":"List workspace assets visible to new generation jobs.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:read","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/BeforeDateCursor"},{"$ref":"#/components/parameters/AssetSlotId"},{"$ref":"#/components/parameters/AssetStatus"}],"responses":{"200":{"description":"Workspace asset page.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/AssetListResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/assets/{assetId}":{"get":{"tags":["Assets"],"summary":"Read one workspace asset by id.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:read","parameters":[{"$ref":"#/components/parameters/AssetId"}],"responses":{"200":{"description":"Workspace asset.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/AssetSummary"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/AssetNotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}},"delete":{"tags":["Assets"],"summary":"Soft-delete one workspace asset.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:write","parameters":[{"$ref":"#/components/parameters/AssetId"}],"responses":{"200":{"description":"Soft-deleted asset.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/AssetDeleteResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/AssetNotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/assets/uploads":{"post":{"tags":["Assets"],"summary":"Create an upload intent for a workspace asset.","description":"Returns a short-lived URL and required headers for uploading the file bytes. Complete the upload with the returned uploadId and assetId before using the asset in a paid pack request.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetUploadCreateRequest"}}}},"responses":{"201":{"description":"Presigned upload intent.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/AssetUploadIntent"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/assets/uploads/{uploadId}/complete":{"post":{"tags":["Assets"],"summary":"Verify a previously uploaded object and mark the asset ready.","description":"Requires Idempotency-Key. Repeating the same completed upload request with the same key replays the ready asset response; a different completion body or key returns an idempotency conflict.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:write","parameters":[{"$ref":"#/components/parameters/UploadId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetUploadCompleteRequest"}}}},"responses":{"200":{"description":"Verified asset.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/AssetUploadCompleteResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/AssetNotFound"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"422":{"$ref":"#/components/responses/UnprocessableRequest"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"},"502":{"$ref":"#/components/responses/AssetUploadNotConfigured"}}}},"/api/v1/assets/uploads/{uploadId}/object":{"put":{"tags":["Assets"],"summary":"Upload bytes for a pending workspace asset.","description":"Use the url, method, and headers returned by POST /api/v1/assets/uploads. Send the same API key on this request. The byte length and Content-Type must match the upload intent before the asset can be completed.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:write","parameters":[{"$ref":"#/components/parameters/UploadId"}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string","format":"binary"}},"font/ttf":{"schema":{"type":"string","format":"binary"}},"font/otf":{"schema":{"type":"string","format":"binary"}}}},"responses":{"204":{"description":"Object bytes accepted for the pending upload. Complete the upload before using the asset in a job.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/AssetNotFound"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableRequest"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/assets/upload-object":{"put":{"tags":["Assets"],"summary":"Upload bytes through the proxy URL returned by an upload intent.","description":"Use the upload URL returned by POST /api/v1/assets/uploads when direct object upload is not available. Send the same API key, uploadId query parameter or x-formatry-cc-upload-id header, byte length, and Content-Type declared by the upload intent.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"assets:write","parameters":[{"$ref":"#/components/parameters/UploadIdQuery"},{"$ref":"#/components/parameters/UploadIdHeader"}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}},"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string","format":"binary"}},"font/ttf":{"schema":{"type":"string","format":"binary"}},"font/otf":{"schema":{"type":"string","format":"binary"}}}},"responses":{"204":{"description":"Object bytes accepted for the pending upload. Complete the upload before using the asset in a job.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/AssetNotFound"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/UnprocessableRequest"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/previews/quota":{"get":{"tags":["Previews"],"summary":"Read the effective protected-preview allowance and policy.","description":"Returns workspace-shared product allowance, used and remaining counters, per-client burst allowance, exact reset timestamps, and delivered-image protection policy without reserving quota or rendering. An exhausted product or burst allowance includes Retry-After.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"previews:read","responses":{"200":{"description":"Current preview policy and allowance.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-Preview-Protection":{"schema":{"enum":["watermarked-lowres","watermarked","none"]}},"X-Preview-Quota-Limit":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Used":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Remaining":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Reset":{"schema":{"type":"string","format":"date-time"}},"Retry-After":{"description":"Present when product or burst allowance is exhausted; seconds until all exhausted counters reset.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/PreviewQuotaResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/api/v1/previews":{"post":{"tags":["Previews"],"summary":"Create one bounded protected PNG preview.","description":"Creates or replays one protected preview through the workspace-shared allowance. Requests that reference workspace assets also require assets:read. Technical failures and idempotent cache hits do not consume another product unit.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"previews:write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewCreateRequest"}}}},"responses":{"200":{"description":"Protected PNG preview, stable input identity, and updated allowance.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-Preview-Protection":{"schema":{"enum":["watermarked-lowres","watermarked","none"]}},"X-Preview-Quota-Limit":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Used":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Remaining":{"schema":{"type":"integer","minimum":0}},"X-Preview-Quota-Reset":{"schema":{"type":"string","format":"date-time"}},"Retry-After":{"description":"Present when product or burst allowance is exhausted; seconds until all exhausted counters reset.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/PreviewCreateResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"429":{"$ref":"#/components/responses/PreviewLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"},"502":{"$ref":"#/components/responses/PreviewRenderFailed"},"503":{"$ref":"#/components/responses/ServiceUnavailable"}}}},"/api/v1/jobs":{"get":{"tags":["Jobs"],"summary":"List workspace-owned generation jobs.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"jobs:read","parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/BeforeDateCursor"},{"$ref":"#/components/parameters/GenerationJobStatus"},{"$ref":"#/components/parameters/RenderFingerprint"}],"responses":{"200":{"description":"Generation job history for the authenticated workspace.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GenerationJobListResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}},"post":{"tags":["Jobs"],"summary":"Create a paid pack request and reserve workspace balance once.","description":"Requires Idempotency-Key. A new accepted request reserves the required credits or active quota. Repeating the same key with the same body returns the existing request; changing the body for the same key returns a conflict.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"jobs:write","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerationJobCreateRequest"},"examples":{"logoAndMedia":{"summary":"Brand logo, background, and campaign media","value":{"contractId":"formatry-default","selectedSizeIds":["square-1080"],"outputFormat":"png","assetIds":{"logo":"00000000-0000-4000-8000-000000000001","background":"00000000-0000-4000-8000-000000000002","media":"00000000-0000-4000-8000-000000000003","font":"00000000-0000-4000-8000-000000000005"}}},"logoAndPerson":{"summary":"Brand logo plus person visual","value":{"contractId":"formatry-default","selectedSizeIds":["story-1080x1920"],"outputFormat":"webp","assetIds":{"logo":"00000000-0000-4000-8000-000000000001","person":"00000000-0000-4000-8000-000000000003"}}},"logoAndDevice":{"summary":"Brand logo plus full-device art","value":{"contractId":"formatry-default","selectedSizeIds":["square-1080"],"outputFormat":"jpg","assetIds":{"logo":"00000000-0000-4000-8000-000000000001","device":"00000000-0000-4000-8000-000000000004"}}}}}}},"responses":{"200":{"description":"Existing generation job returned for an idempotent replay.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GenerationJobSummary"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"202":{"description":"Accepted queued generation job.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GenerationJobSummary"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/BalanceExhausted"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"409":{"$ref":"#/components/responses/IdempotencyConflict"},"422":{"$ref":"#/components/responses/UnprocessableRequest"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/jobs/{jobId}":{"get":{"tags":["Jobs"],"summary":"Read workspace-owned generation job status.","description":"Poll this endpoint until the job reaches a terminal status. Use artifactId only after status is succeeded; a null artifactId means no downloadable artifact is available yet.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"jobs:read","parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"Generation job status.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GenerationJobSummary"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/JobNotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/jobs/{jobId}/cancel":{"post":{"tags":["Jobs"],"summary":"Cancel a queued generation job and release reserved balance.","description":"Cancellation is workspace-owned and idempotent by job state. Queued jobs move to canceled and release the prior usage ledger consumption through a refund ledger event. Terminal jobs return their current status without a second refund. Jobs already in progress cannot be canceled.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"jobs:write","parameters":[{"$ref":"#/components/parameters/JobId"}],"responses":{"200":{"description":"Canceled generation job, or current terminal job status for a repeated cancellation request.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/GenerationJobSummary"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/JobNotFound"},"409":{"$ref":"#/components/responses/RunningJobCancelRejected"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/artifacts/{artifactId}":{"get":{"tags":["Artifacts"],"summary":"Read the artifact family for a workspace-owned generation job.","description":"Returns the customer-facing artifact manifest for a completed job. Call the download endpoint only when status is ready and the manifest contains the expected files.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"artifacts:read","parameters":[{"$ref":"#/components/parameters/ArtifactId"}],"responses":{"200":{"description":"Artifact family with pack, manifest, and generated files.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/ArtifactManifest"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/ArtifactNotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/artifacts/{artifactId}/download":{"get":{"tags":["Artifacts"],"summary":"Get short-lived signed artifact download information.","description":"Returns download information for a ready artifact. Do not persist or log the returned URL; request a new one when the previous link expires.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"artifacts:read","parameters":[{"$ref":"#/components/parameters/ArtifactId"}],"responses":{"200":{"description":"Artifact download response.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","data","meta"],"properties":{"ok":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/ArtifactDownloadResponse"},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/ArtifactNotFound"},"409":{"$ref":"#/components/responses/ArtifactNotReady"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}},"/api/v1/artifacts/{artifactId}/files/{fileId}/download":{"get":{"tags":["Artifacts"],"summary":"Download one ready artifact file through scoped API authentication.","description":"Choose artifactId and fileId from the ready manifest. The server verifies workspace ownership, stored byte length, content type, and checksum before returning file bytes. The response never exposes a signed storage URL.","security":[{"bearerApiKey":[]},{"headerApiKey":[]}],"x-formatry-cc-required-scope":"artifacts:read","parameters":[{"$ref":"#/components/parameters/ArtifactId"},{"$ref":"#/components/parameters/FileId"}],"responses":{"200":{"description":"Verified artifact file bytes.","headers":{"X-Request-ID":{"description":"Correlation id for this request. Supply X-Request-ID to preserve a client-generated value.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Fixed-window request limit for this route family.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current fixed window after this response.","schema":{"type":"integer","minimum":0}},"X-RateLimit-Reset":{"description":"Exact UTC timestamp when the current fixed window resets.","schema":{"type":"string","format":"date-time"}},"Content-Type":{"schema":{"type":"string"}},"Content-Length":{"schema":{"type":"integer","minimum":0}},"Content-Disposition":{"schema":{"type":"string"}}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/ArtifactNotFound"},"409":{"$ref":"#/components/responses/ArtifactNotReady"},"429":{"$ref":"#/components/responses/RateLimited"},"501":{"$ref":"#/components/responses/ProviderNotConfigured"}}}}},"components":{"securitySchemes":{"bearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"Formatry API key","description":"Send the API key as Authorization: Bearer <key> from a server-side integration."},"headerApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternative server-side API key header for clients that cannot set Authorization."}},"parameters":{"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100}},"BeforeDateCursor":{"name":"before","in":"query","schema":{"type":"string","format":"date-time"}},"BeforeLedgerCursor":{"name":"before","in":"query","schema":{"type":"string","pattern":"^\\d+$"}},"AssetSlotId":{"name":"slotId","in":"query","schema":{"$ref":"#/components/schemas/AssetSlotId"}},"AssetStatus":{"name":"status","in":"query","schema":{"enum":["processing","ready","rejected"]}},"GenerationJobStatus":{"name":"status","in":"query","schema":{"enum":["queued","running","succeeded","failed","canceled"]}},"RenderFingerprint":{"name":"renderFingerprint","in":"query","description":"Return only reusable queued, running, or retained successful jobs with this server-owned render fingerprint.","schema":{"type":"string","pattern":"^[0-9a-f]{64}$"}},"AssetId":{"name":"assetId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"ApiKeyId":{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"UploadId":{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"UploadIdQuery":{"name":"uploadId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},"UploadIdHeader":{"name":"x-formatry-cc-upload-id","in":"header","required":false,"schema":{"type":"string","format":"uuid"}},"JobId":{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"ArtifactId":{"name":"artifactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"FileId":{"name":"fileId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Client-generated retry key for one mutating request. Reuse it only with the same method, endpoint, and request body.","schema":{"type":"string","minLength":1,"maxLength":200}}},"responses":{"BadRequest":{"description":"Request body, query, or required retry header is invalid.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"UnprocessableRequest":{"description":"The request is structurally valid, but the named asset, slot, size, combination, or output format is unsupported. Correct it before retrying.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"Unauthorized":{"description":"Missing, malformed, expired, revoked, or inactive API key.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ForbiddenScope":{"description":"API key does not include the required scope.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"RateLimited":{"description":"Fixed-window route rate limit exceeded.","headers":{"Retry-After":{"schema":{"type":"integer"}},"X-Request-ID":{"schema":{"type":"string"}},"X-RateLimit-Limit":{"schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Reset":{"schema":{"type":"string","format":"date-time"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"PreviewLimited":{"description":"Preview burst or product allowance is exhausted until the exact returned reset time.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}},"X-Request-ID":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"enum":["PREVIEW_RATE_LIMITED","PREVIEW_QUOTA_EXCEEDED"]},"message":{"type":"string"},"httpStatus":{"const":429},"requestId":{"type":"string"},"details":{"type":"object","required":["quota"],"properties":{"quota":{"$ref":"#/components/schemas/PreviewQuota"}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"PreviewRenderFailed":{"description":"Preview rendering or protection failed without charging product allowance.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"const":"PREVIEW_RENDER_FAILED"},"message":{"type":"string"},"httpStatus":{"const":502},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ProviderNotConfigured":{"description":"This origin is not configured for the requested API service.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ServiceUnavailable":{"description":"Preview storage or another required server dependency is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"BalanceExhausted":{"description":"Workspace does not have enough credits or subscription quota for the requested job.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"IdempotencyConflict":{"description":"Idempotency key was reused with incompatible data or stale state.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"AssetNotFound":{"description":"Asset was not found for this workspace.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"AssetUploadNotConfigured":{"description":"Uploaded file could not be verified for this workspace.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"PayloadTooLarge":{"description":"Uploaded object exceeds the byte length declared by the upload intent.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ApiKeyNotFound":{"description":"API key was not found for this workspace.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"JobNotFound":{"description":"Generation job was not found for this workspace.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"RunningJobCancelRejected":{"description":"Jobs already in progress cannot be canceled.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ArtifactNotFound":{"description":"Artifact was not found for this workspace.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}},"ArtifactNotReady":{"description":"Artifact exists but cannot be downloaded yet.","content":{"application/json":{"schema":{"type":"object","required":["ok","error","meta"],"properties":{"ok":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message","httpStatus","requestId","details"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"httpStatus":{"type":"integer"},"requestId":{"type":"string"},"details":{"type":"object","additionalProperties":true,"required":["nextAction","safeToRetryUnchanged"],"properties":{"nextAction":{"type":"string","description":"Nearest safe operator action after this failure."},"safeToRetryUnchanged":{"type":"boolean","description":"Whether the same request may be retried without changing its body or idempotency key."}}}}},"meta":{"type":"object","required":["apiVersion","requestId"],"properties":{"apiVersion":{"type":"string","const":"2026-06-18"},"requestId":{"type":"string"}}}}}}}}},"schemas":{"PreviewQuotaCounter":{"type":"object","required":["limit","used","remaining","resetAt"],"properties":{"limit":{"type":"integer","minimum":0},"used":{"type":"integer","minimum":0},"remaining":{"type":"integer","minimum":0},"resetAt":{"type":"string","format":"date-time"},"window":{"enum":["minute","hour","day"]}}},"PreviewQuota":{"type":"object","required":["product","burst"],"properties":{"product":{"$ref":"#/components/schemas/PreviewQuotaCounter"},"burst":{"$ref":"#/components/schemas/PreviewQuotaCounter"}}},"PreviewQuotaResponse":{"type":"object","required":["accessMode","quality","quota","timing"],"properties":{"accessMode":{"enum":["registered-trial","codex-trial","paid-workspace","admin-workspace"]},"quality":{"type":"object","required":["maxRasterSide","protection"],"properties":{"maxRasterSide":{"type":"integer","minimum":1},"protection":{"enum":["watermarked-lowres","watermarked","none"]}}},"quota":{"$ref":"#/components/schemas/PreviewQuota"},"timing":{"anyOf":[{"type":"object","required":["averageDurationMs","sampleSize"],"additionalProperties":false,"properties":{"averageDurationMs":{"type":"integer","minimum":1},"sampleSize":{"type":"integer","minimum":1,"maximum":20}}},{"type":"null"}]}}},"PreviewCreateRequest":{"type":"object","additionalProperties":false,"required":["sizeId"],"properties":{"sizeId":{"type":"string"},"customSize":{"type":"object","additionalProperties":false,"required":["id","width","height"],"properties":{"id":{"type":"string"},"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}}},"rasterSize":{"type":"object","additionalProperties":false,"required":["width","height"],"properties":{"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}}},"assetIds":{"type":"object","additionalProperties":{"type":"string"}},"copy":{"type":"object","additionalProperties":{"type":"string"}},"theme":{"type":"object","additionalProperties":{"type":"string"}},"typography":{"type":"object","additionalProperties":true},"renderOptions":{"type":"object","additionalProperties":true}}},"PreviewCreateResponse":{"type":"object","required":["previewId","inputHash","cacheStatus","charged","logicalSize","image","quota"],"properties":{"previewId":{"type":"string"},"inputHash":{"type":"string"},"cacheStatus":{"enum":["hit","miss"]},"charged":{"type":"boolean"},"logicalSize":{"type":"object","required":["width","height"],"properties":{"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}}},"image":{"type":"object","required":["mimeType","encoding","data","width","height","byteLength","protection"],"properties":{"mimeType":{"const":"image/png"},"encoding":{"const":"base64"},"data":{"type":"string","contentEncoding":"base64","contentMediaType":"image/png"},"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1},"byteLength":{"type":"integer","minimum":1},"protection":{"enum":["watermarked-lowres","watermarked","none"]}}},"quota":{"$ref":"#/components/schemas/PreviewQuota"}}},"BalanceResponse":{"type":"object","description":"Current paid access available to the authenticated key. Create a pack request only when credits, active quota, or unlimited access covers the requested output sizes.","required":["workspaceId","credits","subscriptionQuota","unlimited","unit","billingStatus","updatedAt"],"properties":{"workspaceId":{"type":"string","format":"uuid"},"credits":{"type":"integer","description":"Credit balance available for paid output sizes."},"subscriptionQuota":{"type":"integer","description":"Active subscription quota available for paid output sizes."},"unlimited":{"type":"boolean","description":"True for approved account access that is not limited by credits."},"unit":{"const":"credit"},"billingStatus":{"enum":["trial","active","past_due","canceled","suspended"]},"updatedAt":{"type":"string","format":"date-time"}}},"UsageLedgerResponse":{"type":"object","required":["workspaceId","items","limit","hasMore","nextCursor"],"properties":{"workspaceId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/UsageLedgerEvent"}},"limit":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"]}}},"UsageLedgerEvent":{"type":"object","required":["id","source","eventType","unit","amount","generationJobId","metadata","createdAt"],"properties":{"id":{"type":"string"},"source":{"enum":["stripe","yookassa","coinbase","lava","codex","admin","api","studio","system"]},"eventType":{"enum":["grant","purchase","consume","refund","adjustment","expiration"]},"unit":{"const":"credit"},"amount":{"type":"integer"},"generationJobId":{"type":["string","null"],"format":"uuid"},"metadata":{"type":"object","additionalProperties":{"type":["string","number","boolean"]}},"createdAt":{"type":"string","format":"date-time"}}},"CodexTrialKeyRequest":{"type":"object","required":["clientMarker"],"additionalProperties":false,"properties":{"clientMarker":{"type":"string","minLength":16,"maxLength":256,"description":"Stable privacy-preserving client marker derived and hashed locally by the Codex plugin. It is combined with IP and user agent, HMAC-hashed again server-side, and never stored raw."},"pluginVersion":{"type":"string","maxLength":80},"clientName":{"type":"string","maxLength":80}}},"CodexTrialKeyResponse":{"type":"object","required":["origin","apiKey","quota","workspace","privacy"],"properties":{"origin":{"type":"string","format":"uri"},"apiKey":{"type":"object","required":["secret","prefix","expiresAt","scopes"],"properties":{"secret":{"type":"string","description":"One-time temporary API key. Clients must redact it from logs and tool output after storing it in process memory."},"prefix":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}}}},"quota":{"type":"object","required":["unit","creditsGranted","limit","remaining","resetAt"],"properties":{"unit":{"const":"credit"},"creditsGranted":{"const":5},"limit":{"const":5},"remaining":{"type":"integer","minimum":0},"resetAt":{"type":"string","format":"date-time"}}},"workspace":{"type":"object","required":["id","slug","name"],"properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"}}},"privacy":{"type":"object","required":["identity","rawIdentifierStored"],"properties":{"identity":{"const":"hashed-client-marker-with-separate-ip-ceiling"},"rawIdentifierStored":{"const":false}}}}},"ApiKeyScope":{"description":"Permission granted to an API key. Each operation declares its required scope.","enum":["balance:read","assets:read","assets:write","jobs:write","jobs:read","artifacts:read","deliveries:write","previews:read","previews:write","api-keys:read","api-keys:write"]},"ApiKeySummary":{"type":"object","required":["id","workspaceId","name","keyPrefix","scopes","status","createdAt","lastUsedAt","expiresAt"],"properties":{"id":{"type":"string","format":"uuid"},"workspaceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"keyPrefix":{"type":"string"},"scopes":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"status":{"enum":["active","revoked","expired"]},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time"}}},"ApiKeyListResponse":{"type":"object","required":["workspaceId","items"],"properties":{"workspaceId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeySummary"}}}},"ApiKeyCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80},"scopes":{"type":"array","minItems":1,"description":"Optional. When omitted, Formatry creates a quickstart-safe key for balance, asset upload, jobs, and artifact downloads. A caller can only grant scopes already present on the authenticating key.","items":{"$ref":"#/components/schemas/ApiKeyScope"}},"expiresAt":{"type":["string","null"],"format":"date-time"}}},"ApiKeyCreateResponse":{"type":"object","required":["apiKey"],"properties":{"apiKey":{"allOf":[{"$ref":"#/components/schemas/ApiKeySummary"},{"type":"object","required":["secret","secretAvailable"],"properties":{"secret":{"type":"string"},"secretAvailable":{"const":true}}}]}}},"ApiKeyRevokeResponse":{"type":"object","required":["apiKey","revokedAt"],"properties":{"apiKey":{"$ref":"#/components/schemas/ApiKeySummary"},"revokedAt":{"type":"string","format":"date-time"}}},"AssetSlotId":{"enum":["logo","background","media","product","person","device","font","other"]},"AssetSummary":{"type":"object","required":["id","slotId","fileName","mimeType","byteLength","width","height","status","rejectionReason","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"slotId":{"$ref":"#/components/schemas/AssetSlotId"},"fileName":{"type":"string"},"mimeType":{"type":"string"},"byteLength":{"type":"integer"},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"status":{"enum":["processing","ready","rejected","deleted"]},"rejectionReason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"AssetListResponse":{"type":"object","required":["workspaceId","items","limit","hasMore","nextCursor"],"properties":{"workspaceId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/AssetSummary"}},"limit":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"],"format":"date-time"}}},"AssetDeleteResponse":{"type":"object","required":["asset","deletedAt"],"properties":{"asset":{"$ref":"#/components/schemas/AssetSummary"},"deletedAt":{"type":"string","format":"date-time"}}},"AssetUploadCreateRequest":{"type":"object","required":["slotId","fileName","mimeType","byteLength"],"description":"Register the file metadata before sending bytes. Supported slots and MIME types are listed in x-formatry-cc-consumer-contract.assets.supportedAssetInputs.","properties":{"slotId":{"$ref":"#/components/schemas/AssetSlotId"},"fileName":{"type":"string"},"mimeType":{"type":"string","enum":["image/svg+xml","image/png","image/jpeg","image/webp","font/otf","font/ttf","font/woff","font/woff2"]},"byteLength":{"type":"integer","minimum":1,"maximum":26214400},"width":{"type":"integer","minimum":1,"maximum":8192},"height":{"type":"integer","minimum":1,"maximum":8192},"sha256":{"type":"string"}}},"AssetUploadIntent":{"type":"object","required":["uploadId","assetId","method","url","headers","expiresAt"],"properties":{"uploadId":{"type":"string","format":"uuid"},"assetId":{"type":"string","format":"uuid"},"method":{"const":"PUT"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"expiresAt":{"type":"string","format":"date-time"}}},"AssetUploadCompleteRequest":{"type":"object","required":["assetId","byteLength"],"properties":{"uploadId":{"type":"string","format":"uuid","deprecated":true},"assetId":{"type":"string","format":"uuid"},"byteLength":{"type":"integer","minimum":1},"sha256":{"type":"string"}}},"AssetUploadCompleteResponse":{"type":"object","required":["uploadId","asset"],"properties":{"uploadId":{"type":"string","format":"uuid"},"asset":{"$ref":"#/components/schemas/AssetSummary"}}},"GenerationJobCreateRequest":{"type":"object","description":"Creates a queued paid pack request and reserves the required credits or active quota. assetIds must reference ready workspace-owned assets created through the upload flow. The API rejects unsupported asset combinations before balance is charged.","required":["contractId","selectedSizeIds"],"properties":{"contractId":{"type":"string","enum":["formatry-default"],"description":"Creative-pack contract identifier. Use the value supplied by Formatry for this API version."},"selectedSizeIds":{"type":"array","items":{"type":"string"},"description":"Output size ids plus any ids declared in customSizes.","minItems":1},"outputFormat":{"enum":["png","webp","jpg"],"default":"png","description":"Final generated file format for each export size. SVG is not a downloadable output format."},"customSizes":{"type":"array","description":"Optional custom output sizes. Custom ids must start with custom- and also appear in selectedSizeIds.","items":{"type":"object","required":["id","label","width","height","platforms"],"additionalProperties":false,"properties":{"id":{"type":"string","pattern":"^custom-"},"label":{"type":"string","maxLength":40},"width":{"type":"integer","minimum":20,"maximum":4096},"height":{"type":"integer","minimum":20,"maximum":4096},"platforms":{"type":"array","items":{"type":"string"},"maxItems":4}}},"maxItems":40},"assetIds":{"type":"object","additionalProperties":false,"properties":{"logo":{"type":"string","format":"uuid"},"background":{"type":"string","format":"uuid"},"media":{"type":"string","format":"uuid"},"secondaryMedia":{"type":"string","format":"uuid"},"product":{"type":"string","format":"uuid"},"device":{"type":"string","format":"uuid"},"person":{"type":"string","format":"uuid"},"font":{"type":"string","format":"uuid"}},"description":"Optional uploaded asset binding. Use logo for one ready SVG logo, background for one ready PNG/JPEG/WebP background, media and secondaryMedia for primary and secondary screen visuals, product for one contained product shot, device for one complete device visual, person for one person visual, and font for one ready TTF/OTF brand font. The API rejects unsupported combinations before balance is charged.","maxProperties":5},"copy":{"type":"object","additionalProperties":{"type":"string"}},"theme":{"type":"object","additionalProperties":{"type":"string"}},"typography":{"type":"object","description":"Optional curated Studio typography metadata for renderer config. Font file paths are not accepted here; use assetIds.font for a ready TTF/OTF upload when a custom font file must drive renderer outlines.","additionalProperties":false,"properties":{"family":{"type":"string","maxLength":160},"subtitleFamily":{"type":"string","maxLength":160},"descriptorFamily":{"type":"string","maxLength":160},"ctaFamily":{"type":"string","maxLength":160},"manifestFamily":{"type":"string","maxLength":160},"displayWeight":{"type":"integer","minimum":300,"maximum":1000},"ctaWeight":{"type":"integer","minimum":300,"maximum":1000},"subtitleFontLabel":{"type":"string","maxLength":160},"ctaFontLabel":{"type":"string","maxLength":160},"sourceLabel":{"type":"string","maxLength":160},"uploadedFontRoles":{"type":"object","description":"Optional role map for assetIds.font. Omitted keeps legacy headline and CTA font-outline behavior.","additionalProperties":false,"properties":{"headline":{"type":"boolean"},"subtitle":{"type":"boolean"},"cta":{"type":"boolean"}}}}},"renderOptions":{"type":"object","description":"Advanced output controls reserved for supported integrations.","additionalProperties":true}}},"GenerationJobSummary":{"type":"object","required":["id","renderFingerprint","status","contractId","selectedSizeIds","selectedSizes","outputFormat","cost","creditRefund","artifactId","studioContext","progress","recovery","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"renderFingerprint":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Server-owned identity of the normalized creative revision, rendered material, selected sizes, and output format."},"status":{"enum":["queued","running","succeeded","failed","canceled"]},"contractId":{"type":"string"},"selectedSizeIds":{"type":"array","items":{"type":"string"}},"selectedSizes":{"type":"array","items":{"type":"object","required":["id","width","height"],"properties":{"id":{"type":"string"},"width":{"type":"integer","minimum":1},"height":{"type":"integer","minimum":1}}}},"outputFormat":{"enum":["png","webp","jpg"]},"cost":{"type":"object","required":["creditsRequired","unit"],"properties":{"creditsRequired":{"type":"integer"},"unit":{"const":"credit"}}},"creditRefund":{"oneOf":[{"type":"object","required":["creditsReturned","unit"],"properties":{"creditsReturned":{"type":"integer","minimum":1},"unit":{"const":"credit"}}},{"type":"null"}],"description":"Authoritative failed-job refund evidence from the usage ledger. Null unless the returned credit amount exactly matches the original job cost."},"artifactId":{"type":["string","null"],"format":"uuid","description":"When a job succeeds, artifactId points to the downloadable ZIP pack when available; manifest artifacts remain listed through the artifact family endpoint."},"studioContext":{"oneOf":[{"type":"object","required":["projectId","projectName","creativeId","creativeName","creativeRevision"],"properties":{"projectId":{"type":"string","format":"uuid"},"projectName":{"type":"string"},"creativeId":{"type":"string","format":"uuid"},"creativeName":{"type":"string"},"creativeRevision":{"type":"integer","minimum":1}}},{"type":"null"}],"description":"Current Studio project and creative labels plus the immutable creative revision used by this job; null for jobs not linked to a Studio creative."},"progress":{"type":"object","required":["phase","completed","total","fraction","estimatedRemainingSeconds","startedAt"],"properties":{"phase":{"enum":["queued","claimed","rendering","uploading","packaging","completing"]},"completed":{"type":["integer","null"],"minimum":0},"total":{"type":["integer","null"],"minimum":1},"fraction":{"type":"number","minimum":0,"maximum":1},"estimatedRemainingSeconds":{"oneOf":[{"type":"object","required":["min","max"],"properties":{"min":{"type":"integer","minimum":1},"max":{"type":"integer","minimum":1}}},{"type":"null"}]},"startedAt":{"type":["string","null"],"format":"date-time"}},"description":"Persisted export phase and completed pipeline units. Remaining time is a measured range and is omitted until an active job has completed at least one unit."},"recovery":{"type":"object","required":["state","reason","canRecover","ageSeconds"],"properties":{"state":{"enum":["waiting","working","stalled","terminal"]},"reason":{"enum":["worker_not_started","worker_lease_expired","client_lease_expired","retry_backoff",null]},"canRecover":{"type":"boolean"},"ageSeconds":{"type":"integer","minimum":0}},"description":"Server classification of queue or worker health. Recovery requeues the same charged job instead of creating a replacement."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"GenerationJobListResponse":{"type":"object","required":["workspaceId","items","limit","hasMore","nextCursor"],"properties":{"workspaceId":{"type":"string","format":"uuid"},"items":{"type":"array","items":{"$ref":"#/components/schemas/GenerationJobSummary"}},"limit":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":["string","null"],"format":"date-time"}}},"ArtifactManifest":{"type":"object","description":"Lists the generated files for a completed job. Use the download endpoint to receive a short-lived signed URL for the downloadable artifact.","required":["id","jobId","status","files","expiresAt"],"properties":{"id":{"type":"string","format":"uuid"},"jobId":{"type":"string","format":"uuid"},"status":{"enum":["ready","expired","deleted"]},"files":{"type":"array","items":{"$ref":"#/components/schemas/ArtifactFile"}},"expiresAt":{"type":"string","format":"date-time"}}},"ArtifactDownloadResponse":{"type":"object","description":"Short-lived signed download information for the generated artifact.","required":["artifactId","url","method","expiresAt"],"properties":{"artifactId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"method":{"const":"GET"},"expiresAt":{"type":"string","format":"date-time"}}},"ArtifactFile":{"type":"object","required":["id","kind","fileName","contentType","byteLength"],"properties":{"id":{"type":"string"},"kind":{"enum":["export_png","export_webp","export_jpg","zip","manifest","contact_sheet"]},"fileName":{"type":"string"},"contentType":{"type":"string"},"byteLength":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"checksumSha256":{"type":"string"}}}},"x-formatry-cc-api-key-scopes":["balance:read","assets:read","assets:write","jobs:write","jobs:read","artifacts:read","deliveries:write","previews:read","previews:write","api-keys:read","api-keys:write"]}}