Composants
Un composant est un bloc de liens et de titres partagé entre les pages d'un environnement : posé sur trois pages, il s'y affiche à l'identique, et le modifier les modifie toutes. Ses liens se gèrent avec les mêmes routes que ceux d'une page. Créer, dupliquer ou poser un composant dépend de l'offre.
- GET
/v1/componentsLister les composants - POST
/v1/componentsCréer un composant - GET
/v1/components/{id}Lire un composant - PATCH
/v1/components/{id}Modifier un composant - POST
/v1/components/{id}/duplicateDupliquer un composant - DELETE
/v1/components/{id}Supprimer un composant - GET
/v1/components/{id}/linksGérer les liens d'un composant - POST
/v1/components/{id}/linksGérer les liens d'un composant - PATCH
/v1/components/{id}/linksGérer les liens d'un composant - PUT
/v1/components/{id}/links/orderGérer les liens d'un composant - GET
/v1/components/{id}/links/{lien}Gérer les liens d'un composant - PATCH
/v1/components/{id}/links/{lien}Gérer les liens d'un composant - DELETE
/v1/components/{id}/links/{lien}Gérer les liens d'un composant - PUT
/v1/components/{id}/links/{lien}/imageGérer les liens d'un composant - GET
/v1/pages/{id}/componentsLister les composants d'une page - POST
/v1/pages/{id}/componentsPoser un composant sur une page - DELETE
/v1/pages/{id}/components/{composant}Retirer un composant d'une page - POST
/v1/pages/{id}/components/{composant}/detachDétacher un composant
Lister les composants
GET/v1/components
Les composants de l'environnement, par ordre alphabétique. links_count compte les liens non archivés, pages_count les pages où le composant est posé. Portée Lecture.
curl https://api.tinylink.fr/v1/components \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/components', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
$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_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"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"
}
]
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Lecture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Créer un composant
POST/v1/components
name est obligatoire (100 caractères au plus), description facultative (500 au plus). links ajoute d'un coup jusqu'à 100 liens, décrits comme sur une page. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/components \
-H "Authorization: Bearer tl_votre_jeton" \
-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_votre_jeton',
'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_votre_jeton', '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_votre_jeton'},
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()
Réponses possibles
{
"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": []
} Le corps n'est pas un objet JSON
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas les composants
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Écriture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Champ obligatoire absent ou vide
{
"error": {
"code": "validation_failed",
"message": "The \"name\" field is required.",
"details": {
"field": "name"
}
}
} Champ obligatoire absent ou vide
{
"error": {
"code": "validation_failed",
"message": "The \"title\" field is required.",
"details": {
"field": "title"
}
}
} Ni adresse web, ni e-mail, ni téléphone
{
"error": {
"code": "invalid_url",
"message": "This is not a valid web address, e-mail address or phone number.",
"details": {
"field": "url"
}
}
} Domaine signalé comme suspect
{
"error": {
"code": "suspicious_url",
"message": "This address is on our list of suspicious domains and cannot be used.",
"details": {
"field": "url"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Lire un composant
GET/v1/components/{id}
Le composant, ses liens dans l'ordre d'affichage et les pages où il est posé. Portée Lecture.
curl https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
$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_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"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": []
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Lecture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} Aucun composant avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Modifier un composant
PATCH/v1/components/{id}
name, description, ou les deux. Portée Écriture.
curl -X PATCH https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_votre_jeton" \
-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_votre_jeton',
'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_votre_jeton', '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_votre_jeton'},
json={'name': 'Réseaux sociaux'},
)
data = response.json()
Réponses possibles
{
"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": []
} Le corps n'est pas un objet JSON
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Écriture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Aucun composant avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} Aucun champ modifiable dans le corps
{
"error": {
"code": "validation_failed",
"message": "Nothing to update. Accepted fields: name, description."
}
} Champ obligatoire absent ou vide
{
"error": {
"code": "validation_failed",
"message": "The \"name\" field is required.",
"details": {
"field": "name"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Dupliquer un composant
POST/v1/components/{id}/duplicate
Copie le composant et ses liens non archivés, images comprises, sous le nom name (à défaut : le nom suivi de « (copy) »). La copie n'est posée sur aucune page. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/components/C6ad34a13d28745/duplicate \
-H "Authorization: Bearer tl_votre_jeton" \
-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_votre_jeton',
'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_votre_jeton', '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_votre_jeton'},
json={'name': 'Réseaux (copie)'},
)
data = response.json()
Réponses possibles
{
"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": []
} Le corps n'est pas un objet JSON
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas les composants
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Écriture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Aucun composant avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Supprimer un composant
DELETE/v1/components/{id}
Supprime le composant, ses liens et leurs statistiques, et le retire de toutes les pages où il était posé. Irréversible. Portée Suppression.
curl -X DELETE https://api.tinylink.fr/v1/components/C6ad34a13d28745 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/components/C6ad34a13d28745', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
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_votre_jeton'},
)
print(response.status_code) # 204
Réponses possibles
Sans contenu
Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Suppression
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"delete\" scope.",
"details": {
"required_scope": "delete"
}
}
} Aucun composant avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Gérer les liens d'un composant
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
Mêmes routes, mêmes champs et mêmes réponses que les liens d'une page, en remplaçant /pages/{id} par /components/{id} : ajout (un ou plusieurs), lecture, modification, modification groupée, nouvel ordre, image, suppression. Un composant accepte aussi les blocs d'intégration. Portée selon la méthode.
curl -X POST https://api.tinylink.fr/v1/components/C6ad34a13d28745/links \
-H "Authorization: Bearer tl_votre_jeton" \
-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_votre_jeton',
'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_votre_jeton', '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_votre_jeton'},
json={'title': 'TikTok', 'url': 'https://tiktok.com/@exemple'},
)
data = response.json()
Réponses possibles
{
"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"
} Le corps n'est pas un objet JSON
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Lecture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} Aucun composant avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Component not found in this environment."
}
} Aucun lien avec cet identifiant dans le composant
{
"error": {
"code": "not_found",
"message": "Link not found in this component."
}
} Champ obligatoire absent ou vide
{
"error": {
"code": "validation_failed",
"message": "The \"title\" field is required.",
"details": {
"field": "title"
}
}
} Ni adresse web, ni e-mail, ni téléphone
{
"error": {
"code": "invalid_url",
"message": "This is not a valid web address, e-mail address or phone number.",
"details": {
"field": "url"
}
}
} Domaine signalé comme suspect
{
"error": {
"code": "suspicious_url",
"message": "This address is on our list of suspicious domains and cannot be used.",
"details": {
"field": "url"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Lister les composants d'une page
GET/v1/pages/{id}/components
Les composants posés sur la page : pour chacun, son bloc dans la page (block, avec sa position et sa visibilité) et le composant lui-même. Le bloc figure aussi dans GET /v1/pages/{id}/links, avec type: "component" et component_id. Portée Lecture.
curl https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
$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_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"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"
}
}
]
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Lecture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} Aucune page avec cet identifiant ou ce slug dans l'environnement
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Poser un composant sur une page
POST/v1/pages/{id}/components
component_id est obligatoire ; le composant doit être de l'environnement de la page, et n'y être pas déjà. position le place (1 = en haut), sinon il va en bas. La réponse est le bloc créé dans la page ; il se masque, s'archive et se déplace comme un lien. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components \
-H "Authorization: Bearer tl_votre_jeton" \
-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_votre_jeton',
'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_votre_jeton', '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_votre_jeton'},
json={'component_id': 'C6ad34a13d28745', 'position': 1},
)
data = response.json()
Réponses possibles
{
"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"
} Le corps n'est pas un objet JSON
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas les composants
{
"error": {
"code": "plan_feature_unavailable",
"message": "Components are not included in the plan of this environment's owner."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Écriture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Aucune page avec cet identifiant ou ce slug dans l'environnement
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} Composant déjà présent sur la page
{
"error": {
"code": "component_already_on_page",
"message": "This component is already on this page.",
"details": {
"field": "component_id"
}
}
} Composant absent de l'environnement
{
"error": {
"code": "validation_failed",
"message": "Component not found in this environment.",
"details": {
"field": "component_id"
}
}
} Élément bloqué par la modération
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Retirer un composant d'une page
DELETE/v1/pages/{id}/components/{composant}
Retire le composant de la page, sans toucher au composant ni à ses liens. Portée Suppression.
curl -X DELETE https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a1406db15', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
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_votre_jeton'},
)
print(response.status_code) # 204
Réponses possibles
Sans contenu
Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Suppression
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"delete\" scope.",
"details": {
"required_scope": "delete"
}
}
} Aucune page avec cet identifiant ou ce slug dans l'environnement
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} Le composant n'est pas sur la page
{
"error": {
"code": "not_found",
"message": "This component is not on this page."
}
} Élément bloqué par la modération
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Détacher un composant
POST/v1/pages/{id}/components/{composant}/detach
Remplace le composant par une copie de ses liens, à sa place et dans le même ordre (masqués et archivés compris, images dupliquées) : ils deviennent des liens ordinaires de la page, que les modifications du composant ne suivront plus. Le composant n'est pas touché. La réponse est la liste des liens de la page. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/components/C6ad34a13d28745/detach', {
method: 'POST',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
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_votre_jeton'],
]);
$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_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"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"
}
]
} Jeton absent de la requête
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Jeton inconnu ou révoqué
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} L'offre du propriétaire n'inclut pas l'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."
}
} Le jeton ne porte pas la portée Écriture
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} Aucune page avec cet identifiant ou ce slug dans l'environnement
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} Le composant n'est pas sur la page
{
"error": {
"code": "not_found",
"message": "This component is not on this page."
}
} Élément bloqué par la modération
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
}