Rate limits
Limits keep the API fast for everyone. Normal app and server traffic stays far below them. When you go over, you get a `429` and, on most endpoints, a `Retry-After` header.
How a limit works
Each limit is a bucket: it allows a burst of requests at once, then refills at a steady rate. While the bucket is empty you get:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{ "error": "rate limited" }When Retry-After is sent, wait that many seconds before trying again. Where it isn't, back off for a second or two and retry. Every 429 body is listed in the Error reference.
Limits by endpoint
| Endpoints | Burst | Then | Counted per | Retry-After |
|---|---|---|---|---|
App and website calls: POST /v1/match, /v1/referrer, /v1/resolve, /v1/open, /v1/event, /v1/handoff/claim, /v1/store-sheet, and GET /v1/simulate |
60 | 1 a second | IP address | not sent |
Paste handoff: POST /v1/handoff/claim (on top of the line above) and opening a handoff link |
10 | 10 a minute | IP address | 60 |
Analytics: GET /v1/analytics |
30 | 1 every 2 seconds (30 a minute) | workspace | 2 |
Referral report: GET /v1/referrals |
30 | 1 every 2 seconds (30 a minute) | workspace | 2 |
QR codes: GET /v1/links/{slug}/qr |
60 | 1 a second | workspace | 1 |
Custom domain status: GET /v1/domains |
20 | 1 every 2 seconds | workspace | 5 |
Custom domain changes: POST /v1/domains and DELETE /v1/domains/{hostname} together |
10 | 1 every 6 minutes | workspace | 360 |
App Links checker: GET /v1/tools/app-links |
10 | 10 a minute | IP address | 60 |
Live tap trace: GET /v1/trace/{st} |
30 | 1 a second | IP address | not sent |
Link reports: POST /v1/report |
5 | 5 an hour | IP address | 3600 |
Deep health check: GET /healthz/deep |
20 | 1 every 3 seconds | IP address | 60 |
Hosted MCP server: POST /mcp |
60 | 1 a second | secret key | 1 |
| Hosted MCP server, wrong or missing keys | 20 | 20 a minute | IP address | 60 |
PNG QR codes also share one rendering budget across all workspaces (bigger images cost more of it). When it's busy you get 429 with Retry-After: 2: try again shortly, or ask for format=svg, which doesn't use that budget.
An SDK makes one or two of the app calls per link open, so one phone stays far below 60. People behind one office or mobile-carrier network share an IP address, so their calls count together.
Size limits
| What | Limit | Answer when over |
|---|---|---|
Links in one POST /v1/links/batch |
500 | 400 |
Request body for POST /v1/links/batch |
2 MB | 413 |
Request body for POST /mcp |
2 MB | 413 |
| Request body for every other public endpoint | 100 KB | 413 |
Page size (limit) for GET /v1/links |
1 to 100; more is treated as 100 | 400 below 1 |
Page size (limit) for webhook deliveries |
1 to 100 | 400 |
New workspaces
For its first 24 hours, a new workspace can create 25 links, and its links can be opened 500 times. This stops throwaway accounts from sending spam through short links; the limit lifts by itself after the first day.
- Creating a link past the cap answers
429with{ "error": "new_account_limit", "reason": "links", "message", "limit", "resetsAt" }and aRetry-Afterheader. - A tap past the cap shows the person a "taking a break" page instead of the destination, with
429. Link previews in chat apps still work.
Plan limits
Plan limits are monthly, not per second: new links a month (Free), taps a month, and the number of webhooks. Going over answers 402 with a reason (links, clicks or webhooks) and an upgradeUrl. Links you already shared keep working. Each plan's numbers are on Pricing.
Related
- Error reference: every error the API can send.
- Batch create: up to 500 links in one call, for imports.