Limits and quotas¶
This page documents the caps the service actually enforces on upload activity, and what a partner integration must send to get a correct analysis result. Every cap below is scoped to your API key: your key's own usage never affects another partner's headroom, and none of these caps is shared globally across all partners. Each cap is stated with its exact enforced figure and the error you will see if you exceed it, so you can size your integration before you send a single request.
Caps at a glance¶
| Cap | Enforced value | Scope | On breach |
|---|---|---|---|
| Upload-spot rate | 10 spots per rolling 15-minute window | Per API key | 429 spots_per_window_exceeded |
| Unclaimed bytes | 1 GiB, aggregate across all your unclaimed uploads | Per API key | 429 unclaimed_bytes_exceeded |
| Upload spot lifetime | 15 minutes (900 seconds) from mint | Per upload spot | 410 upload_spot_expired |
| Upload handle reuse | Single-use; the same exercise_id is idempotent |
Per upload handle | 409 upload_already_claimed |
Full error envelope shapes and message text for every code above are documented in the error catalog.
Upload spot rate limit¶
You may mint up to 10 upload spots within a rolling 15-minute window,
per API key. Minting an eleventh spot before the window clears is
refused with a 429 spots_per_window_exceeded response.
The rolling window is the same 15 minutes as the spot lifetime, so capacity does not free up all at once at a fixed reset time. As each of your spots crosses the 15-minute mark, it stops counting against your window usage and a new mint becomes available. Plan your upload cadence around a continuous rolling allowance rather than a periodic reset.
Unclaimed-bytes cap¶
The total size of bytes you have uploaded and left unclaimed by a
submitted job may not exceed 1 GiB, per API key. This is an aggregate
cap across every upload spot you currently hold, not a limit on any
single file. Uploading a file that would push your held total over
the cap is refused with a 429 unclaimed_bytes_exceeded response.
Once you submit a job for an uploaded video, its bytes stop counting
toward this cap.
Upload spot lifetime¶
An upload spot is valid for 15 minutes (900 seconds) from the moment
it is minted. Using a spot to upload a video, or submitting a job
against it, after that window has passed fails with a 410
upload_spot_expired response. Mint a new spot and upload again if
this happens.
Single-use upload handles¶
An upload handle can be claimed by exactly one job. Submitting a job against a handle that has already been claimed behaves differently depending on what you send:
- Submitting the same
exercise_idagain is idempotent: you get back a201response with the originaljob_id, not an error. It is safe to retry a submission with identical parameters. - Submitting a different
exercise_idagainst an already-claimed handle is refused with a409upload_already_claimedresponse, because the handle can only ever be tied to one exercise.
If you need to submit a second job, mint a new upload spot rather than reusing a claimed handle.
No enforced size or duration ceiling¶
The service enforces no per-file size ceiling and no duration bound on the video you upload. The 1 GiB figure above is a per-key aggregate across unclaimed uploads, not a per-file size limit: a single large video can consume most of your available headroom, but the service does not fail an individual file for being large or long on its own. Design your integration around the unclaimed-bytes and spot-rate caps above, since those are the only enforced storage-abuse bounds today.
Configuration and scope¶
The figures on this page are the values enforced by the current production deployment. They are controlled by operator-side configuration and default to the values shown here; a future deployment could change them. They are not a per-partner negotiated limit, and there is no request path to raise them for an individual key: every key is held to the same production defaults.
Video input requirements¶
For a correct analysis result, the file you upload must be a genuine video with a video track. The service does not check this today. It accepts whatever bytes are written to the signed upload URL and does not inspect their content, container, or codec before handing them to the analysis pipeline.
Sending a file that is not a real video does not produce an error. Instead, the analysis model runs on whatever it receives and returns a confident but wrong result: it fabricates an analysis rather than failing outright. Nothing in the response tells you the input was bad, because from the service's point of view nothing went wrong.
Validating that a file is a genuine video with a video track before you upload it is your responsibility as the integrator. Treat it as a precondition your own client enforces, not a guarantee the API enforces on your behalf.
Bad video input yields a wrong result, not an error
A non-video upload is analyzed anyway and comes back as a confident, incorrect result rather than a failure you can detect from the response alone. Validate your input before you upload.