Errors and limits
Every error code the API returns, what causes it and how to handle it, plus rate limits and plan caps.
Errors come back as JSON with a human-readable error message you can show to a person, and, where your code should react differently, a stable machine-readable code. Branch on code and the HTTP status, never on the message text.
{
"error": "You can keep 20 links on your plan. Delete one, or upgrade to Pro for unlimited links.",
"code": "plan_limit"
}Error codes#
| Status | code | What happened | What to do |
|---|---|---|---|
| 401 | unauthorized | Missing, malformed or revoked API key. | Check the Authorization header. See Authentication. |
| 403 | banned | The account is suspended. | Contact support. Do not retry. |
| 403 | plan_limit | Link limit reached on the Free plan. | Delete a link or upgrade. |
| 403 | storage_limit | The upload would go over your total storage. | Delete files or upgrade. |
| 400 | size_limit | The file is bigger than your plan allows per file, but Pro would allow it. | Upgrade, or send a smaller file. |
| 400 | none | Bad input: unsupported or blocked file type, the bytes don't match the extension, empty file, or a taken link name. | Fix the request. Read error for details. |
| 409 | path_in_use | That upload path was already used for a link. | Start a new upload. |
| 429 | rate_limited | Too many requests for this API key, or too many uploads this hour. | Wait the number of seconds in the Retry-After header, then retry. |
| 503 | retry | A temporary problem finishing the upload. | Retry with the same idempotencyKey. |
| 500 | none | Something failed on our side. | Retry with the same idempotencyKey. |
Rate limits#
Each API key has a request budget, counted in units. An analytics call (/api/v1/analytics, /api/v1/links/{slug}/analytics and the MCP analytics tools) costs 5 units; every other call costs 1. CORS preflight requests are free. The minute is a clock minute; the day is a UTC day.
| Plan | Per minute | Per day (UTC) |
|---|---|---|
| Free | 60 units | 2,000 units |
| Pro and Lifetime | 300 units | 20,000 units |
Every response carries X-RateLimit-Limit and X-RateLimit-Remaining for the current minute. Over the limit, the API answers 429 with a Retry-After header and a body like the one below (the MCP server returns a JSON-RPC error with the same details in data). A refused request does not use up your budget. scope says which limit you hit: minute, day, burst, auth (too many invalid keys from one address) or upload_hour (the hourly upload cap). One MCP batch that costs more than the whole per-minute limit can never succeed, so it gets 400 with code batch_too_expensive instead: split it into smaller batches. Analytics reports are cached on the server for 60 seconds, so asking for the same report more often returns the same numbers.
{
"error": "Too many API requests (60 units per minute). Try again in 12 seconds.",
"code": "rate_limited",
"scope": "minute",
"retryAfter": 12
}Limits#
- Hourly uploads: 30 per hour for Free accounts using an API key, on top of the rate limit above. Paid plans and new-account protections use the website's normal limits.
- Plan caps: links, per-file size and total storage follow your plan. See Plans and limits.
- Signed URLs expire after 10 minutes and accept exactly the size you declared.
- MCP inline uploads (
upload_file) take files up to 3 MB; usecreate_upload_urlfor larger ones.
Retry the right things
429 after its Retry-After, and 500 and 503 with a backoff, using the same idempotencyKey. Do not retry 400, 401 or 403: the same request will fail the same way.Last updated 4 October 2026. Something unclear or missing? Tell us.