Reference
Errors
Two kinds of failure, one page. The render edge fails silently — a blank image, no error — so start there. The API fails loudly with a code; that's the second table.
Silent failures (blank mockup)
The render edge returns a valid image even when something is wrong, so a mistake shows up as a blank or off-looking mockup, not an HTTP error. These five cover almost every case.
| You see | Because | Fix |
|---|---|---|
| Blank / empty product | Your asset= URL isn’t publicly fetchable (a localhost, file://, or auth-walled URL). The renderer fetches it server-side. | Host the artwork on a public CDN/object store and pass that URL. |
| Blank for a specific product code | The product code isn’t in the catalog. An unknown code renders blank, not a 404. | Look the code up in the catalog first. BEEB77 is a known-good demo product. |
| Blurry / low-res mockup | The requested width snaps down to the largest allowed size, and a non-16:9 frame with cover shows only a slice — so an under-sized request looks soft. | Request ~2× the displayed size; a 320–400px retina card wants width=1400–1600. Sizes: 400…4000 (floor, not nearest). |
| Mockup looks letterboxed / cropped wrong | Every render is 16:9 landscape. object-fit: contain letterboxes it; cropping into a non-16:9 frame is safe by design. | Display with object-fit: cover. To crop server-side, add &aspect=2:3 (only 16:9 or 2:3 are valid). |
| Art renders, but from the wrong shop | You copied a demo Shop ID. It’s shared and rate-limited. | Mint your own — Get started. One POST /shops/sandbox, no signup. |
HTTP status codes
Calls to api.snowcone.app return a JSON body { "code": "…", "message": "…" } with these codes.
| HTTP | Code | Meaning & fix |
|---|---|---|
| 400 | invalid_argument | Malformed or missing parameters in the request body/query. |
| 401 | unauthenticated | No credential, or an invalid one. Check you sent x-api-key / Authorization. |
| 403 | permission_denied | The key is valid but lacks the required scope (e.g. calling Orders without orders:add). |
| 404 | not_found | The resource (e.g. an order id) doesn't exist or isn't yours. |
| 409 | already_exists / failed_precondition | The action conflicts with current state (e.g. claiming an already-claimed shop). |
| 429 | resource_exhausted | Rate limit hit. Minting is 60/hr and 200 unclaimed sandbox shops per IP — reuse one shop_id instead of minting per attempt. |
Realtime error codes
The realtime socket reports problems with a code on the error message rather than an HTTP status.
| Code | Meaning & fix |
|---|---|
asset_not_allowed | A referenced asset origin isn’t on the shop’s asset-origin allowlist. Add the host or use an allowed one. |
unsupported_schema_version | The schemaVersion in your canvas_state isn’t supported. Match the version the realtime docs show. |
state_ref_failed | A stored design referenced by renderSavedState couldn’t be resolved (wrong/expired stateId). |
Catalog errors
The catalog is Meilisearch, so it speaks Meili’s errors. A product code that doesn’t exist returns
document_not_found (HTTP 404) from search.snowcone.app — distinct from a render, which would just go blank. Look codes up on the catalog page before rendering.
