API REFERENCE
Conversions
Create a conversion, read it, list them, unlock one, follow its progress.
POST/v1/conversions
Create a conversion
Converting is FREE: 1 credit = 1 image, spent when the image is UNLOCKED (here with unlock: true, or later with POST /conversions/{id}/unlock). A free conversion counts against the daily caps (guests 3 a UTC day, free accounts 10, customers 100). A guest never unlocks: unlock: true answers it 403 account_required. Accepted formats: PNG, JPG, WebP, AVIF, GIF, BMP and TIFF (read by their bytes; an animation or a multi-page TIFF at its first frame), at most 4096×4096. HEIC: send a PNG (the website converts it in the browser). Repeating an idempotencyKey answers 200 with the conversion it already made, never a second one and never a second charge.
Headers
Retry-Afterstring- On a 429 (
free_limit_reached, or every free conversion together reaching today's shared capacity of 2000): seconds until the caps renew, the next UTC midnight. On a 409too_many_active_jobs(guest 1, free 1, paid 5 at once): wait for one to end, or sendqueue: true.
Body
inputKeystringrequired- From POST /uploads. Must be the caller's.
inputHashstring- OPTIONAL assertion about what was uploaded. The API computes the real hash itself and answers
input_hash_mismatchon disagreement: a client-chosen cache key would be a cache-poisoning path. presetone ofdefaultoptionsobject- Optional choices about this image beside its preset.
{}for none. Two conversions share a cached result only with the same options. Not offered yet:merge(a redraw that merges two colors is not offered yet; merge them in the Colors tab, or ask for fewer colors). idempotencyKeystringrequired- Unique per conversion you mean: a retry with the same key is answered with the conversion it made.
filenamestring- OPTIONAL: the uploaded file's own name. Kept as a cleaned label (the base name, no extension, at most 80 characters); the download is
<name>.svg. unlockbooleandefault false- OPTIONAL: unlock the image with this conversion: 1 credit held now, committed when it completes, refunded if it fails. On an image already unlocked it holds nothing (a free re-run); on one a conversion still running is unlocking, 409
unlock_pending. No request spends a credit unless it says so. queuebooleandefault false- OPTIONAL: past the active limit, WAIT in line (status
waiting) instead of a 409too_many_active_jobs. It starts by itself when one of the caller's conversions ends, oldest first, and may be stopped while it waits (POST /conversions/{id}/cancel). Every cap applies at creation: a waiting conversion counts against the day, and a held credit is held while it waits.
Errors
| Status | Code | What to do |
|---|---|---|
| 402 | insufficient_ | Buy credits, then send the same request again. |
| 403 | account_ | Sign in or create an account. The conversions come with you. |
| 404 | not_ | Check the id. Another account's objects read as not found too. |
| 409 | idempotency_ | Make a new key for a new request. |
| 409 | too_ | Wait for one to finish, or send queue: true to wait in line. |
| 409 | unlock_ | Wait for that conversion to finish. |
| 429 | free_ | Come back after Retry-After (UTC midnight), or unlock with a credit. |
| 429 | free_ | Come back after Retry-After (UTC midnight), or unlock with a credit. |
Every refusal carries its code and a requestId. Errors and retries.
GET/v1/conversions
List conversions
The caller's conversions, newest first, a page at a time: pass a page's nextCursor back as cursor. With live=true, only the LIVE ones (waiting, queued, processing), oldest first: the queue as the server holds it, in one page (limit and cursor are then refused).
Query
liveone oftrue,falsetrue: only the live ones, oldest first.limitinteger, 1 to 100default 20cursorstring- A page's
nextCursor.
Errors
Every refusal carries its code and a requestId. Errors and retries.
GET/v1/conversions/{id}
Retrieve a conversion
A permalink: for the slow tail this is the normal way a conversion is seen, and it answers the same an hour later as while it runs. Another's conversion is 404, the same as none.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
Every refusal carries its code and a requestId. Errors and retries.
DELETE/v1/conversions/{id}
Delete a conversion
Deletes this VERSION of its image: erased at once, it leaves every list and permalink, and its files are deleted within the hour. The image's LAST version is not erased: deleting it deletes the image (Recently deleted, restorable), and deleted says which. Its unlock, if paid, stays the image's.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
| 409 | conversion_ | Wait for it to finish, then try again. |
Every refusal carries its code and a requestId. Errors and retries.
POST/v1/conversions/{id}/cancel
Cancel a waiting conversion
Only a WAITING conversion (created with queue: true, past the active limit) can be stopped: once it has started, a worker holds it. Stopped, it is canceled: a held credit comes back, it leaves the library (an image whose only version it was goes with it), and it is not counted against the day.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
| 409 | not_ | Let a running conversion finish. |
Every refusal carries its code and a requestId. Errors and retries.
POST/v1/conversions/{id}/unlock
Unlock a conversion's image
1 credit, at most once per image (the same uploaded bytes in this account). After it every result of the image downloads in every format and every re-run of it is free. A repeat, or a conversion of an image already unlocked, spends nothing (spent: 0), so a retry is safe. A POST, never folded into the download: a GET that spends a credit is a GET a link previewer spends.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 402 | insufficient_ | Buy credits, then send the same request again. |
| 404 | not_ | Check the id. Another account's objects read as not found too. |
| 409 | conversion_ | Convert the image again. Converting is free. |
| 409 | not_ | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | result_ | Convert the image again. |
| 409 | unlock_ | Wait for that conversion to finish. |
Every refusal carries its code and a requestId. Errors and retries.
GET/v1/conversions/{id}/events
Watch a conversion
Server-Sent Events: a status event at once with the current state, then one on each change of status or phase; its data is a ConversionEvent. The stream closes when the conversion ends. A serverless function has a bounded lifetime and a conversion can outlive it, so a client MUST reconnect and re-read the conversion rather than treat this stream as the only way to learn an outcome.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
Every refusal carries its code and a requestId. Errors and retries.
GET/v1/conversions/{id}/feedback
Retrieve the verdict
The caller's verdict on a result, or null.
Path
ididrequired
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
Every refusal carries its code and a requestId. Errors and retries.
PUT/v1/conversions/{id}/feedback
Give a verdict
One per result, given or changed: thumbs up or down; a down's reasons; a note; and shareImage. Moves no money: a failed result's credit comes back after a look, by an operator.
Path
ididrequired
Body
voteone ofup,downrequiredreasonsarray of one oflost_detail,wrong_colors,rough_edges,too_many_shapes,text,failed- Only with a thumb down.
notestringshareImagebooleandefault false
Errors
| Status | Code | What to do |
|---|---|---|
| 404 | not_ | Check the id. Another account's objects read as not found too. |
| 409 | conversion_ | Convert the image again. Converting is free. |
| 409 | not_ | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | result_ | Convert the image again. |
Every refusal carries its code and a requestId. Errors and retries.