~/docs cat credits-and-limits.md
Credits and limits
Every detection is paid in prepaid credits. credits_used in the response is the real charge for that run; prefer it over any estimate.
Cost per media type
| Media | Credits |
|---|---|
| Image | 1 credit per image. |
| Video | 1 credit per scored frame: about one a second for the first 20 seconds, 20 sampled for anything longer. A frame with a null score is not charged. At most 20 per clip. |
| Audio | 1 credit per minute, rounded up, minimum 1. |
| Link | The same as the media it resolves to. |
When a run is not charged
The same file, byte for byte, from the same account within 30 days is not charged: the run still happens, credits_used is 0 and zero_charge_reason is "duplicate", and it is stored like any other run. A request that is refused before a detector runs, and a 422 the platform could not judge, are never charged.
A sandbox key runs the same detection and charges nothing; the response says zero_charge_reason: "sandbox". Sandbox is a property of the key, not a flag on the request. A sandbox key is set up on your account by us; ask your account contact.
Size caps
image ≤ 10 MB, video ≤ 100 MB, audio ≤ 50 MB. A file over its cap answers 413. The dashboard uploader applies its own ceilings (video and audio ≤ 25 MB), so a file that uploads there uploads here.
Rate limits
Detections are limited per API key: 100 per minute; the account and usage reads sit behind a separate, higher per-key ceiling. Every response reports the limiter that applied to it in X-RateLimit-* and, on the detection route, RateLimit-* headers. Over the limit the call answers 429 with Retry-After; back off and honour it. A retry starts another detection and may be charged; sandbox keys and recognised duplicate files are exempt. Read credits_used and zero_charge_reason for the actual charge. Retry refused requests only when the error is retryable. Set your client timeout to 300 seconds or more: an image answers in seconds, a video in up to about a minute, and a link adds the fetch. If a call times out, read the credit ledger before sending the same media again: the run may have completed and been charged.
When a check is refused
Credits are the gate. A run the balance cannot cover is refused before it starts with 402 INSUFFICIENT_CREDITS. A gate that cannot be read at all is a 503 BILLING_UNAVAILABLE, never a silent pass.
Balance, usage and the credit ledger live in the dashboard. Plans and per-credit prices are on the pricing page.
Start building
Create an API key in the dashboard and send your first file. To go through an integration or an on-prem deployment with our team, request a demo.