Save the uuid returned when you create the task, along with the launch parameters. You will need them to recover interrupted work. Upload and download links expire and cannot replace the task ID.
States
waiting_for_upload → running → succeeded | failed | cancelled| State | Meaning | Next action |
|---|---|---|
waiting_for_upload | Created but not launched; the file may already be uploaded | Fetch upload URLs, upload if needed, then launch |
running | Launch accepted; work may still be queued | Poll with backoff |
succeeded | Result is available while the task remains accessible | Request fresh download URLs |
failed | Processing ended with an error | Read the task's error.code |
cancelled | Task was cancelled | Stop polling |
The API currently has no cancel or delete endpoint.
Recover after an interrupted request
| Interrupted operation | Recovery |
|---|---|
Create, with no confirmed uuid | Inspect waiting tasks; check before creating another task |
| Upload | Fetch upload URLs again. get_url and head_url mean the file is uploaded; put_url means it still needs uploading |
| Launch | GET the task; if necessary repeat launch with the same parameters |
| Poll | Keep the uuid and resume GET with bounded backoff |
| Download | Request new download URLs while the task is accessible |
Uploaded files cannot be replaced. Create a new task for a different source. Repeating an accepted launch with identical normalized parameters returns the existing resource, including after failure; it never restarts failed work. Changed parameters return 409 TRANSFORM_ALREADY_LAUNCHED.
Concurrent conversions
Each user can have at most 3 running tasks, counting PDF and EPUB together. Accepted work that is waiting for a worker still occupies a slot. Creation and file upload do not occupy a slot.
If you receive 409 TRANSFORM_CONCURRENCY_LIMIT, the task has not started and remains waiting_for_upload. The uploaded file is kept, and the expiry time is unchanged.
Check the running list at intervals and retry launch when another task finishes. You can reuse the same task, provided it has not expired.
Lists and pagination
Use the list endpoints to recover work across sessions. Waiting includes uploaded files that have not been launched. Running includes queued tasks. Finished includes successful, failed and cancelled tasks.
The response contains transforms and, when another page exists, next_cursor. Pass that value unchanged as cursor to the same list. Lists are not snapshots: tasks can move between lists while you paginate. There is no total count.
Retention and expiry
The service sets task expiry. Use the returned expires_at; timestamps in documentation examples are illustrative.
Accepting a launch request clears the upload deadline. A request rejected because of the concurrency limit keeps its original deadline. Recently finished tasks may initially have no expires_at; the service can set one later as more tasks finish.
Polling does not extend retention. Once a task expires, queries return 404 and it disappears from lists, even if the files have not yet been deleted.
Download and save your results promptly, including when expires_at is absent.
Failed work
Read GET /transforms/{uuid} for error.code and error.message. Observation only supplies the status and optional progress/preview. Correct the cause before creating a new task; see errors and retry decisions.