Rate Limits & Errors
The U2L API enforces rate limits per plan and returns consistent error responses across all endpoints.
Rate Limits
Rate limits are applied per account on a per-minute and per-day basis. Every plan has API access; limits vary by plan:
| Plan | Requests / Minute | Requests / Day |
|---|---|---|
| Free | 10 | 500 |
| Pro | 60 | 10,000 |
| Advanced | 120 | 50,000 |
| Team | 300 | 200,000 |
| Enterprise | 600 | 1,000,000 |
Daily windows reset at midnight UTC.
Creation Limits
Independent of request rates, new links and QR codes are capped per day. This pool is shared with your dashboard — creations from the U2L app and the API count against the same daily allowance:
| Plan | New Links & QR Codes / Day |
|---|---|
| Free | 50 |
| Pro | 500 |
| Advanced | 5,000 |
| Team | 5,000 |
| Enterprise | 10,000 |
Plans with unlimited links are subject to these fair-use velocity limits; total storage is not capped.
Rate Limit Headers
Every API response includes headers to help you track your rate limit usage:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute for your plan |
X-RateLimit-Remaining | Remaining requests in the current minute window |
X-RateLimit-Reset | Unix timestamp (seconds) when the rate limit resets |
X-RateLimit-Daily-Limit | Maximum requests per day for your plan |
X-RateLimit-Daily-Remaining | Remaining requests in the current UTC day |
Example response headers
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 54
X-RateLimit-Reset: 1707600060
X-RateLimit-Daily-Limit: 10000
X-RateLimit-Daily-Remaining: 9946
Rate Limit Exceeded
When you exceed a limit, the API returns a 429 Too Many Requests response with a Retry-After header and a machine-readable code — rate_limit_exceeded (minute window), daily_limit_exceeded (day window), or creation_limit_exceeded (daily creation cap):
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"retryAfter": 45
}
}
Error Response Format
All errors follow a consistent format with a machine-readable code and a human-readable message:
{
"error": {
"code": "error_code",
"message": "Human-readable error message"
}
}
Validation errors may include a details object with per-field error messages:
{
"error": {
"code": "validation_error",
"message": "Invalid request body",
"details": {
"url": "Must be a valid URL",
"tags": "Tags feature requires Pro plan or higher"
}
}
}
Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | bad_request | Invalid or missing request parameters |
| 401 | unauthorized | Missing or invalid API key |
| 403 | forbidden | Feature not available on your plan |
| 404 | not_found | Resource not found |
| 409 | conflict | Resource already exists (e.g., slug taken) |
| 422 | validation_error | Request body validation failed |
| 429 | rate_limit_exceeded | Too many requests this minute |
| 429 | daily_limit_exceeded | Daily request limit reached |
| 429 | creation_limit_exceeded | Daily link/QR creation limit reached |
| 500 | internal_error | Unexpected server error |