Skip to main content
This walkthrough takes you through the full workflow with runnable curl and Python: upload an image (one call), run a prediction, wait for the job, and download the resulting ROIs as GeoJSON — entirely over the API.

Before you start

1

Get an API key

Create one in the dashboard (Settings → API Keys) and export it:
See Authentication for details.
2

Install tooling (for the bash examples)

The curl snippets use jq to read JSON responses. The Python snippets use requests (pip install requests).

1. Upload your image

One request does everything: POST /upload streams the file in, creates the image record for you (named after the file), converts it, and returns the record already ready. No pre-registration, no polling.
Each image counts against your plan’s storage cap; POST /upload returns 402 once the cap is reached. Files can be up to 4 GB, but for anything larger than a few hundred MB — or a connection that might drop — use the resumable upload below.

2. Pick a model and submit a prediction

List the models available to your organization, then submit a prediction job for your image. GET /models returns shared public base models (such as cpsam, the Cellpose-SAM generalist) alongside any custom models your org has trained.
Each organization runs one job at a time. If you already have a job running, POST /job/prediction returns 400 — wait for it to finish. If an identical job is already queued, the response comes back with status: "skipped" and the existing job_id.

3. Wait until the job completes

Segmentation runs asynchronously on GPU workers, so poll GET /job/{job_id} until status is COMPLETED. The completed response carries the segmentation_id you’ll export.
status moves through SUBMITTEDSTARTEDCOMPLETED (or FAILED).

4. Export the results

Download the segmentation in whichever analysis-ready format you need. GeoJSON is handy for GIS and web tools; the CSV is one row per cell; the ZIP is an ImageJ/FIJI ROI archive.
That’s the whole loop: upload → predict → complete → export. 🎉

Large files: the resumable upload

For multi-GB files or unreliable connections, upload the pixels straight to object storage in chunks instead of through the API. Create the record with resumable: true — the response includes presigned part URLs — then PUT each chunk to its URL and call /complete. If a chunk fails, just retry that PUT; nothing else is lost.
The presigned PUT requests go straight to object storage — do not send your Authorization header on them. All other calls are authenticated with your API key as usual.
From here, continue at step 2 — everything downstream is identical.
The record counts against your storage cap from the moment it is created, and keeps counting until you delete it. If you abandon an upload, DELETE /image/{image_id} frees the slot (POST /upload/{image_id}/abort only discards the uploaded chunks and marks the record failed).

Full Python script

Next steps

API reference

Every endpoint, parameter, and response — with a live playground.

Using with AI agents

Point an agent at the MCP server and OpenAPI spec to drive this flow for you.