Rate limits and quotas
Calls a minute, clips at a time, failed calls a day and allowances a month, per organisation: all its keys together, following your plan. Calls without a key count per address.
| Plan | Calls a minute | Marks a month | Data returned a month | Clips at a time |
|---|---|---|---|---|
| Free | 10 | 1,000 | 1 GB | 1 |
| Indie | 60 | 20,000 | 20 GB | 2 |
| Startup | 300 | 150,000 | 150 GB | 3 |
| Scale | 1,000 | 1,000,000 | 500 GB | 5 |
| Enterprise | Set in your contract | |||
Calls a minute
Every authenticated call counts toward its organisation's limit, all its keys together: marks, time-stamps and usage alike. Windows are whole minutes on the clock (UTC), so the count starts again at the top of each minute. Every response says where you stand:
X-RateLimit-Limit: 10 # calls this minute, for this organisation
X-RateLimit-Remaining: 7 # left this minute
X-RateLimit-Reset: 1792663260 # Unix time (s) when the minute endsPast the limit the API answers 429 rate_limited with Retry-After in seconds. Spread work across the minute, or move to a bigger plan. The Python SDK waits out a Retry-After of up to a minute by itself.
Failed calls
A mark or check that fails after we worked on it (mark_failed, or a check the checker couldn't finish) counts nothing, so these failures have a daily cap per organisation: Free 100, Indie 300, Startup 1,000, Scale 3,000 a day (UTC). Past it, POST /v1/mark and POST /v1/check answer 429 until 00:00 UTC. Refusals before any work (a file we can't read, a block, the marks left) don't count.
Clips
A clip is marked as a job, and each plan marks a few at a time (Free 1, Indie 2, Startup 3, Scale 5). A clip sent while they're all running answers 429 rate_limited with Retry-After: 30.
A clip that fails after we worked on it (its watermark doesn't read back, or it can't be marked in time: mark_failed) counts nothing, so these failures have a daily cap: Free 3, Indie 10, Startup 10, Scale 20 in 24 hours. Past it, new clips answer 429 until the first of those failures is a day old. GET /v1/marks/{id} says why each failed. Refusals before any work (a clip over our limits, a block, the marks left) don't count.
Calls without a key
The public endpoints count per address instead, with the same headers. An IPv6 address counts by its /64, the block one connection usually comes with.
- POST /v1/verify: 10 files a minute and 200 a day. Without a key, the whole service also answers at most 5,000 checks a day (UTC), and 500 with
signed=true; with a key (free), checks count toward your organisation's calls a minute instead. The checker page reads files in your browser and doesn't count here. - The transparency log,
GET /v1/credentialsandGET /v1/verify/key: 120 calls a minute.
Monthly allowances
- Marks: one per successful
POST /v1/mark, and two per picture the safety check reads (POST /v1/check, orcheckon a mark). Test keys have their own allowance: 100 marks a month on Free, as many as live on paid plans. Free's 1,000 marks are one allowance per person: their first organisation has them, and any other they create starts with none until it has a paid plan. - Data returned: the bytes of marked files we send back in cloud mode (1 GB = 10⁹ bytes).
- Time-stamps: one per
POST /v1/tsa, up to your plan's marks, again live and test apart.
Allowances run by calendar month in UTC. When one is used up the API answers 402 quota_exceeded until the 1st of the next month, or until you upgrade. A mark is reserved when a request is accepted and given back if anything fails, so only delivered marks count. Your current numbers are in the dashboard, in the X-Marks-Used and X-Marks-Limit headers, and at GET /v1/usage.
Monthly paid plans continue past their allowance at the published extra prices, billed on the 1st, up to ten times the allowance; annual plans stop at it, like Free.