Components
A component is a block of links and titles shared between the pages of an environment: placed on three pages, it shows identically on each, and changing it changes them all. Its links are managed with the same routes as a page's. Creating, duplicating or placing a component depends on the plan.
- GET
/v1/componentsList the components - POST
/v1/componentsCreate a component - GET
/v1/components/{id}Read a component - PATCH
/v1/components/{id}Change a component - POST
/v1/components/{id}/duplicateDuplicate a component - DELETE
/v1/components/{id}Delete a component - GET
/v1/components/{id}/linksManage a component's links - POST
/v1/components/{id}/linksManage a component's links - PATCH
/v1/components/{id}/linksManage a component's links - PUT
/v1/components/{id}/links/orderManage a component's links - GET
/v1/components/{id}/links/{lien}Manage a component's links - PATCH
/v1/components/{id}/links/{lien}Manage a component's links - DELETE
/v1/components/{id}/links/{lien}Manage a component's links - PUT
/v1/components/{id}/links/{lien}/imageManage a component's links - GET
/v1/pages/{id}/componentsList the components of a page - POST
/v1/pages/{id}/componentsPlace a component on a page - DELETE
/v1/pages/{id}/components/{component}Remove a component from a page - POST
/v1/pages/{id}/components/{component}/detachDetach a component
List the components
GET/v1/components
The components of the environment, in alphabetical order. links_count counts the non-archived links, pages_count the pages where the component is placed. Read scope.
curl https://api.tinylink.fr/v1/components \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/components', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components');
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/components',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"data": [
{
"id": "C6ad34a13d28745",
"name": "Mes réseaux",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 2,
"pages_count": 0,
"created_at": "2026-10-17T12:12:35+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a13d28745"
}
]
} 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."
}
} Create a component
POST/v1/components
name is required (100 characters at most), description optional (500 at most). links adds up to 100 links at once, described as on a page. Write scope.
curl -X POST https://api.tinylink.fr/v1/components \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{
"name": "Mes réseaux",
"description": "Les mêmes liens sur toutes mes pages",
"links": [
{
"title": "Instagram",
"url": "https://instagram.com/exemple"
},
{
"title": "YouTube",
"url": "https://youtube.com/@exemple"
}
]
}'
const response = await fetch('https://api.tinylink.fr/v1/components', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Mes réseaux',
description: 'Les mêmes liens sur toutes mes pages',
links: [
{ title: 'Instagram', url: 'https://instagram.com/exemple' },
{ title: 'YouTube', url: 'https://youtube.com/@exemple' },
],
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components');
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([
'name' => 'Mes réseaux',
'description' => 'Les mêmes liens sur toutes mes pages',
'links' => [
[
'title' => 'Instagram',
'url' => 'https://instagram.com/exemple',
],
['title' => 'YouTube', 'url' => 'https://youtube.com/@exemple'],
],
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/components',
headers={'Authorization': 'Bearer tl_your_token'},
json={
'name': 'Mes réseaux',
'description': 'Les mêmes liens sur toutes mes pages',
'links': [
{'title': 'Instagram', 'url': 'https://instagram.com/exemple'},
{'title': 'YouTube', 'url': 'https://youtube.com/@exemple'},
],
},
)
data = response.json()
Possible responses
{
"id": "C6ad34a13d28745",
"name": "Mes réseaux",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 2,
"pages_count": 0,
"created_at": "2026-10-17T12:12:35+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a13d28745",
"links": [
{
"id": "L6ad34a13d2956",
"title": "Instagram",
"description": "",
"url": "https://instagram.com/exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
},
{
"id": "L6ad34a13d2dcb",
"title": "YouTube",
"description": "",
"url": "https://youtube.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
}
],
"pages": []
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} 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 components
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} 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 Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Required field missing or empty
{
"error": {
"code": "validation_failed",
"message": "The \"name\" field is required.",
"details": {
"field": "name"
}
}
} Required field missing or empty
{
"error": {
"code": "validation_failed",
"message": "The \"title\" field is required.",
"details": {
"field": "title"
}
}
} Neither a web address, nor an e-mail, nor a phone number
{
"error": {
"code": "invalid_url",
"message": "This is not a valid web address, e-mail address or phone number.",
"details": {
"field": "url"
}
}
} Domain flagged as suspicious
{
"error": {
"code": "suspicious_url",
"message": "This address is on our list of suspicious domains and cannot be used.",
"details": {
"field": "url"
}
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Read a component
GET/v1/components/{id}
The component, its links in display order and the pages where it is placed. Read scope.
curl https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components/C6ad34a13d28745');
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/components/C6ad34a13d28745',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"id": "C6ad34a13d28745",
"name": "Mes réseaux",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 2,
"pages_count": 0,
"created_at": "2026-10-17T12:12:35+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a13d28745",
"links": [
{
"id": "L6ad34a13d2956",
"title": "Instagram",
"description": "",
"url": "https://instagram.com/exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
},
{
"id": "L6ad34a13d2dcb",
"title": "YouTube",
"description": "",
"url": "https://youtube.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
}
],
"pages": []
} 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"
}
}
} No component with this id in the environment
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Change a component
PATCH/v1/components/{id}
name, description, or both. Write scope.
curl -X PATCH https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"name":"Réseaux sociaux"}'
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745', {
method: 'PATCH',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Réseaux sociaux' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components/C6ad34a13d28745');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['name' => 'Réseaux sociaux']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.patch(
'https://api.tinylink.fr/v1/components/C6ad34a13d28745',
headers={'Authorization': 'Bearer tl_your_token'},
json={'name': 'Réseaux sociaux'},
)
data = response.json()
Possible responses
{
"id": "C6ad34a13d28745",
"name": "Réseaux sociaux",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 2,
"pages_count": 0,
"created_at": "2026-10-17T12:12:35+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a13d28745",
"links": [
{
"id": "L6ad34a13d2956",
"title": "Instagram",
"description": "",
"url": "https://instagram.com/exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
},
{
"id": "L6ad34a13d2dcb",
"title": "YouTube",
"description": "",
"url": "https://youtube.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
}
],
"pages": []
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} 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 Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No component with this id in the environment
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} No editable field in the body
{
"error": {
"code": "validation_failed",
"message": "Nothing to update. Accepted fields: name, description."
}
} Required field missing or empty
{
"error": {
"code": "validation_failed",
"message": "The \"name\" field is required.",
"details": {
"field": "name"
}
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Duplicate a component
POST/v1/components/{id}/duplicate
Copies the component and its non-archived links, images included, under the name name (by default: the name followed by “(copy)”). The copy is placed on no page. Write scope.
curl -X POST https://api.tinylink.fr/v1/components/C6ad34a13d28745/duplicate \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"name":"Réseaux (copie)"}'
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745/duplicate', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Réseaux (copie)' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components/C6ad34a13d28745/duplicate');
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(['name' => 'Réseaux (copie)']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/components/C6ad34a13d28745/duplicate',
headers={'Authorization': 'Bearer tl_your_token'},
json={'name': 'Réseaux (copie)'},
)
data = response.json()
Possible responses
{
"id": "C6ad34a1406db15",
"name": "Réseaux (copie)",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 3,
"pages_count": 0,
"created_at": "2026-10-17T12:12:36+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a1406db15",
"links": [
{
"id": "L6ad34a1406fb3",
"title": "Instagram",
"description": "",
"url": "https://instagram.com/exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
},
{
"id": "L6ad34a14070bb",
"title": "YouTube",
"description": "",
"url": "https://youtube.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
},
{
"id": "L6ad34a14071a7",
"title": "TikTok",
"description": "",
"url": "https://tiktok.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
}
],
"pages": []
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} 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 components
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} 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 Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No component with this id in the environment
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Delete a component
DELETE/v1/components/{id}
Deletes the component, its links and their statistics, and removes it from every page where it was placed. Irreversible. Delete scope.
curl -X DELETE https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_your_token' },
});
console.log(response.status); // 204
$ch = curl_init('https://api.tinylink.fr/v1/components/C6ad34a13d28745');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); // 204
curl_close($ch);
import requests
response = requests.delete(
'https://api.tinylink.fr/v1/components/C6ad34a13d28745',
headers={'Authorization': 'Bearer tl_your_token'},
)
print(response.status_code) # 204
Possible responses
No content
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 Delete scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"delete\" scope.",
"details": {
"required_scope": "delete"
}
}
} No component with this id in the environment
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Manage a component's links
GET/v1/components/{id}/links
POST/v1/components/{id}/links
PATCH/v1/components/{id}/links
PUT/v1/components/{id}/links/order
GET/v1/components/{id}/links/{lien}
PATCH/v1/components/{id}/links/{lien}
DELETE/v1/components/{id}/links/{lien}
PUT/v1/components/{id}/links/{lien}/image
Same routes, same fields and same responses as the links of a page, replacing /pages/{id} with /components/{id}: adding (one or several), reading, changing, bulk changes, new order, image, deletion. A component also accepts integration blocks. Scope depending on the method.
curl -X POST https://api.tinylink.fr/v1/components/C6ad34a13d28745/links \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"title":"TikTok","url":"https://tiktok.com/@exemple"}'
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745/links', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: 'TikTok', url: 'https://tiktok.com/@exemple' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/components/C6ad34a13d28745/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(['title' => 'TikTok', 'url' => 'https://tiktok.com/@exemple']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/components/C6ad34a13d28745/links',
headers={'Authorization': 'Bearer tl_your_token'},
json={'title': 'TikTok', 'url': 'https://tiktok.com/@exemple'},
)
data = response.json()
Possible responses
{
"id": "L6ad34a13f2dcd",
"title": "TikTok",
"description": "",
"url": "https://tiktok.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:35+02:00"
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} 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"
}
}
} No component with this id in the environment
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} No link with this id in the component
{
"error": {
"code": "not_found",
"message": "Link not found in this component."
}
} Required field missing or empty
{
"error": {
"code": "validation_failed",
"message": "The \"title\" field is required.",
"details": {
"field": "title"
}
}
} Neither a web address, nor an e-mail, nor a phone number
{
"error": {
"code": "invalid_url",
"message": "This is not a valid web address, e-mail address or phone number.",
"details": {
"field": "url"
}
}
} Domain flagged as suspicious
{
"error": {
"code": "suspicious_url",
"message": "This address is on our list of suspicious domains and cannot be used.",
"details": {
"field": "url"
}
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} List the components of a page
GET/v1/pages/{id}/components
The components placed on the page: for each, its block in the page (block, with its position and visibility) and the component itself. The block also appears in GET /v1/pages/{id}/links, with type: "component" and component_id. Read scope.
curl https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components');
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/pages/P6ad34a0e4fef09/components',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"data": [
{
"block": {
"id": "L6ad34a140effd",
"title": "Réseaux sociaux",
"description": null,
"url": null,
"type": "component",
"format": "COMPONENT",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00",
"component_id": "C6ad34a13d28745"
},
"component": {
"id": "C6ad34a13d28745",
"name": "Réseaux sociaux",
"description": "Les mêmes liens sur toutes mes pages",
"links_count": 3,
"pages_count": 1,
"created_at": "2026-10-17T12:12:35+02:00",
"edit_url": "https://app.tinylink.fr/component-edit?id=C6ad34a13d28745"
}
}
]
} 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"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Place a component on a page
POST/v1/pages/{id}/components
component_id is required; the component must belong to the page's environment and not be on the page already. position places it (1 = top), otherwise it goes to the bottom. The response is the block created in the page; it is hidden, archived and moved like a link. Write scope.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"component_id":"C6ad34a13d28745","position":1}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ component_id: 'C6ad34a13d28745', position: 1 }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components');
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(['component_id' => 'C6ad34a13d28745', 'position' => 1]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components',
headers={'Authorization': 'Bearer tl_your_token'},
json={'component_id': 'C6ad34a13d28745', 'position': 1},
)
data = response.json()
Possible responses
{
"id": "L6ad34a140effd",
"title": "Réseaux sociaux",
"description": null,
"url": null,
"type": "component",
"format": "COMPONENT",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00",
"component_id": "C6ad34a13d28745"
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} 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 components
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} 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 Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} Component already on the page
{
"error": {
"code": "component_already_on_page",
"message": "This component is already on this page.",
"details": {
"field": "component_id"
}
}
} Component missing from the environment
{
"error": {
"code": "validation_failed",
"message": "Component not found in this environment.",
"details": {
"field": "component_id"
}
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Remove a component from a page
DELETE/v1/pages/{id}/components/{component}
Removes the component from the page, without touching the component or its links. Delete scope.
curl -X DELETE https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15 \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_your_token' },
});
console.log(response.status); // 204
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); // 204
curl_close($ch);
import requests
response = requests.delete(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15',
headers={'Authorization': 'Bearer tl_your_token'},
)
print(response.status_code) # 204
Possible responses
No content
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 Delete scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"delete\" scope.",
"details": {
"required_scope": "delete"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} The component is not on the page
{
"error": {
"code": "not_found",
"message": "This component is not on this page."
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Detach a component
POST/v1/pages/{id}/components/{component}/detach
Replaces the component with a copy of its links, in its place and in the same order (hidden and archived included, images duplicated): they become ordinary links of the page, which changes to the component will no longer follow. The component is not touched. The response is the list of the page's links. Write scope.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach', {
method: 'POST',
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"data": [
{
"id": "L6ad34a1426b80",
"title": "Instagram",
"description": "",
"url": "https://instagram.com/exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
},
{
"id": "L6ad34a1426bd5",
"title": "YouTube",
"description": "",
"url": "https://youtube.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
},
{
"id": "L6ad34a1426c29",
"title": "TikTok",
"description": "",
"url": "https://tiktok.com/@exemple",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:36+02:00"
},
{
"id": "L6ad34a0e849a2",
"title": "Mes réseaux",
"description": "",
"url": null,
"type": "title",
"format": "TITLE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 4,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:30+02:00"
},
{
"id": "L6ad34a0e84122",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "BANNER",
"size": "HALF",
"visible": true,
"archived": false,
"position": 5,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:30+02:00"
},
{
"id": "L6ad34a0e8467f",
"title": "Ma boutique",
"description": "",
"url": "https://exemple.fr/boutique",
"type": "url",
"format": "BANNER",
"size": "HALF",
"visible": true,
"archived": false,
"position": 6,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:30+02:00"
}
]
} 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 Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} The component is not on the page
{
"error": {
"code": "not_found",
"message": "This component is not on this page."
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
}