Errors and limits
What the API returns when a call fails, how many calls a token can make, and what becomes of the token if the plan changes.
Shape of an error
An error returns an HTTP status and an error object: code identifies the case, message explains it in English, and details.field names the faulty field when there is one — links[1].title in a bulk request.
curl -X POST https://api.tinylink.fr/v1/tags \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"color":"#1E90FF"}'
const response = await fetch('https://api.tinylink.fr/v1/tags', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ color: '#1E90FF' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/tags');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['color' => '#1E90FF']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/tags',
headers={'Authorization': 'Bearer tl_your_token'},
json={'color': '#1E90FF'},
)
data = response.json()
Response 422
{
"error": {
"code": "validation_failed",
"message": "The \"name\" field is required.",
"details": {
"field": "name"
}
}
}
Error codes
400—invalid_json: the body is not a JSON object401—missing_token,invalid_token(unknown or revoked token),token_owner_lost_access(the person who generated it is no longer an admin of the environment)403—insufficient_scope(missing scope, named indetails.required_scope),plan_limit_reached(plan limit reached),plan_required(plan without the API),account_not_verified,account_disabled,forbidden404—not_found(unknown route, or element missing from the environment),qr_code_not_generated405—method_not_allowed: theAllowheader lists the accepted methods409—slug_taken: custom address already taken422—validation_failed(missing or invalid field),invalid_url,suspicious_url(address flagged as suspicious),too_many_blocks423—element_blocked(element blocked by moderation),environment_blocked429—rate_limited(too many requests),too_many_failed_attempts(too many invalid tokens from the same address)500—internal_error,qr_code_failed: try again later
Request limit
Each token gets 120 requests per minute. Every response carries three headers: X-RateLimit-Limit, X-RateLimit-Remaining (what is left in the minute) and X-RateLimit-Reset (the reset time, in Unix seconds). Beyond that, the API returns 429 with a Retry-After header.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 83
X-RateLimit-Reset: 1791230280
Content review
Content created through the API goes through the same review as content from the app: a page, a link or a short link may show the status pending_review while it happens, then active or blocked. A blocked element can no longer be edited.
If your plan changes
The token follows the plan of the environment's owner. If it moves to a plan without the API, the token is suspended: the card says so and every call returns 403 plan_required. It is not deleted and resumes as soon as you are back on a Pro or Business plan. An admin can revoke it at any time, plan or not.