Base URL
Every customer has their own tenant, so there is no single shared host. Yours is issued when the tenant is created:$BASE. Set it once and the rest copies and runs:
Never hard-code the host. A client that will be handed to someone on a different tenant should take
it as configuration, alongside the credentials.
Authentication
Bearer token. Exchange your email and password for a JWT, then send it on every call.Everything is asynchronous
Nothing blocks and nothing streams. Every long-running operation follows the same shape:1
Create
POST the thing. You get a key back, plus signed URLs where files are expected.2
Upload
PUT each file straight to its signed URL. This does not go through the API.3
Start
POST to start, where the resource has a separate start step.4
Poll
GET .../progress until the state is terminal.5
Collect
GET the result. Download URLs are short-lived and signed.Uploading files
When a create response carriesuploadTargets, each entry is a place to PUT one file.
403 SignatureDoesNotMatch:
- Send
Content-Type: text/csv. - Send the header named in
requiredHeader, split on the first colon. It may benull, in which case send nothing extra. - Do not send an
Authorizationheader. The signature covers the request. Your bearer token does not belong here and will break it.
Polling
Poll.../progress and stop when the state is terminal.
Training progress returns
nextPollAfterSeconds. Honour it. When it is absent, the job has
finished and there is nothing left to wait for.
Sensible intervals elsewhere: 15 to 30 seconds for datasets and predictions, 30 to 60 seconds for a
refinement, which runs for tens of minutes or longer.
Refinement progress also carries progressCompleted and progressTotal. The unit is internal and
has no standalone meaning, so rely on the ratio of the two and never on the raw numbers.
Errors
Standard HTTP status codes. The body carries a message written for a person.
A
409 on POST /datasets/{key}/clean has two distinct causes, and the message tells them apart:
an input file has not arrived yet, or the dataset was already cleaned. The second is usually
harmless.
Limits
Conventions
- Keys are UUIDs and opaque. Pass them back exactly as given.
- List endpoints require
offsetandlimit. They are not optional.limitis capped at 100 on refinements. - Timestamps are ISO-8601 UTC, for example
2026-09-14T16:27:03.028Z. - A
nullmetric means undefined, not zero. A test slice with no positive cases leaves recall undefined. Treat it as absent; reporting0says something different and wrong. - Multipart uploads use a part named
_file. The underscore is not a typo. It is the only name the server binds.
Next
Authentication
Tokens, lifetime, and handling expiry.
Recipes
Complete
curl flows for both products.Build an agent or CLI
The full contract in one page, written to be read by a machine.
Endpoint reference
Every endpoint, generated from the spec.