Getting started with the API
The TinyLink API gives your tools — a script, Zapier, Make, your website — the same moves as the app: create a page and add links to it, shorten an address, set tags, generate a QR code, read the stats. It is included in the Pro and Business plans.
Steps
- Open Library, then the Integrations tab: the TinyLink API card comes first.
- Click Generate a token: a panel opens on the right. Choose the token's scopes — Read, Write (create, edit, add links, generate QR codes) and Delete — then confirm. Only tick what your tool needs.
- The token appears at the top of the panel, hidden like a password: the eye shows it, the button next to it copies it. It stays available there, and you can come back for it later with the card's Manage button.
- Send it in the header of every request:
Authorization: Bearer tl_…, tohttps://api.tinylink.fr/v1.
One token per environment
The token only opens the environment it was generated in: your other spaces stay out of reach. It acts on behalf of the admin who generated it, and stops working if that person is no longer an admin of the environment.
The Manage panel is for admins only: they alone see the token and change it. It is stored encrypted at TinyLink. The scopes change without changing the token: your tools have nothing to update. Regenerate creates a new one and disables the old one right away — do it if you think it has leaked. Revoke deletes it. The panel also shows the date of the last call and the number of calls.
First call
GET/v1/me
Every response is JSON. GET /v1/me checks the token and returns the environment, the scopes and the plan limits. From November 1, 2026, limits.visits_per_month comes on top: the month's visits (used), the plan's quota (max, null without a quota) and the reset date (resets_on).
curl https://api.tinylink.fr/v1/me \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/me', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/me');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.get(
'https://api.tinylink.fr/v1/me',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"environment": {
"id": "Env_60c7cf02dd971TT",
"name": "My team",
"color": "#1e90ff",
"description": null,
"personal": false,
"blocked": false
},
"token": {
"scopes": [
"read",
"write"
],
"created_at": "2026-10-05T21:56:57+02:00",
"created_by": "Camille Martin",
"last_used_at": "2026-10-05T21:57:19+02:00"
},
"plan": "Pro",
"limits": {
"pages": {
"used": 4,
"max": 10
},
"links": {
"used": 27,
"max": 100
},
"links_per_page": 50,
"socials_per_page": 8,
"requests_per_minute": 120
}
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Read scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} No code needed: the browser extension
The same token connects the TinyLink extension for Chrome: it shortens the page you are reading and lists your short links from the browser toolbar.
In your language
Every example in this documentation exists in curl, JavaScript, PHP and Python: pick the tab, and your choice is kept from one page to the next. Nothing requires any of them — the API is HTTP and JSON, and any other client will do too: Postman, or the HTTP module of Zapier and Make. Shortening an address, for example:
curl -X POST https://api.tinylink.fr/v1/links \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/promo","slug":"promo"}'
const response = await fetch('https://api.tinylink.fr/v1/links', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ url: 'https://example.com/promo', slug: 'promo' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/links');
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(['url' => 'https://example.com/promo', 'slug' => 'promo']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/links',
headers={'Authorization': 'Bearer tl_your_token'},
json={'url': 'https://example.com/promo', 'slug': 'promo'},
)
data = response.json()
Conventions
The same rules apply to every route:
- The base address is
https://api.tinylink.fr/v1.GET /v1, without a token, returns the API's name, its version and the address of this documentation. - A request body is a JSON object, sent with
Content-Type: application/json. GETreads, with the Read scope.POSTcreates,PATCHedits andPUTsets a tag, with the Write scope.DELETEdeletes, with the Delete scope.- A creation returns
201with the object created, an edit200with the updated object, a deletion204with no content. - The lists of pages, short links and a tag's elements are paginated:
?page=and?per_page=(50 by default, 100 at most). The response carries apaginationobject:page,per_page,total,total_pages. - A page or a short link is referred to by its id or by its custom address (slug). In the limits,
nullmeans unlimited.