Pages et liens d'une page
Toutes les routes des pages et de leurs liens, avec pour chacune un exemple de requête et la réponse rendue. Une page se désigne par son identifiant ou par son adresse personnalisée (slug).
- GET
/v1/pagesLister les pages - POST
/v1/pagesCréer une page - GET
/v1/pages/{id}Lire une page - PATCH
/v1/pages/{id}Modifier une page - DELETE
/v1/pages/{id}Supprimer une page - POST
/v1/pages/{id}/duplicateDupliquer une page - GET
/v1/pages/{id}/linksLister les liens d'une page - POST
/v1/pages/{id}/linksAjouter un lien - GET
/v1/pages/{id}/links/{lien}Lire un lien - PATCH
/v1/pages/{id}/links/{lien}Modifier un lien - DELETE
/v1/pages/{id}/links/{lien}Supprimer un lien - PATCH
/v1/pages/{id}/linksModifier plusieurs liens - PUT
/v1/pages/{id}/links/orderRéordonner les liens - PUT
/v1/pages/{id}/links/{lien}/imageChanger l'image d'un lien - POST
/v1/pages/{id}/links/{lien}/imageChanger l'image d'un lien - DELETE
/v1/pages/{id}/links/{lien}/imageRetirer l'image d'un lien
Lister les pages
GET/v1/pages
Les pages de l'environnement, de la plus récente à la plus ancienne. Chaque page porte ses vues dans stats : total depuis sa création, last_30_days sur les 30 derniers jours. Portée Lecture.
?search=— cherche dans le nom, l'adresse personnalisée et l'identifiant?tag=— identifiant d'un tag : seules les pages qui le portent?page=et?per_page=— pagination, 50 par page par défaut, 100 au plus
curl "https://api.tinylink.fr/v1/pages?per_page=2" \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages?per_page=2', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages?per_page=2');
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?per_page=2',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "P6ac40109381964",
"type": "page",
"name": "Ma page",
"description": "Tous mes liens au même endroit.",
"slug": "ma-page",
"url": "https://tnylnk.fr/ma-page",
"status": "active",
"password_protected": false,
"restricted": false,
"tags": [],
"qr_code": null,
"created_at": "2026-10-05T21:56:57+02:00",
"edit_url": "https://app.tinylink.fr/page-edit?id=P6ac40109381964",
"stats": {
"metric": "views",
"total": 340,
"last_30_days": 85
}
}
],
"pagination": {
"page": 1,
"per_page": 2,
"total": 1,
"total_pages": 1
}
} 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 une page
POST/v1/pages
name est obligatoire. La réponse est la page créée, avec ses liens. Portée Écriture.
name— le nom de la page, 100 caractères au plusdescription— 2 000 caractères au plusslug— l'adresse personnalisée : lettres, chiffres,-,_et., 40 caractères au pluspassword— protège la page par un mot de passetags— liste d'identifiants de tags de l'environnementqr_code—truepour le QR code classique, ou l'identifiant d'un modèlelinks— liens à ajouter d'un coup (100 au plus), décrits comme dans « Ajouter un lien »
curl -X POST https://api.tinylink.fr/v1/pages \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"name": "Ma page",
"slug": "ma-page",
"links": [
{
"title": "Mon site",
"url": "https://exemple.fr"
},
{
"title": "Contact",
"url": "bonjour@exemple.fr"
}
]
}'
const response = await fetch('https://api.tinylink.fr/v1/pages', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Ma page',
slug: 'ma-page',
links: [
{ title: 'Mon site', url: 'https://exemple.fr' },
{ title: 'Contact', url: 'bonjour@exemple.fr' },
],
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages');
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' => 'Ma page',
'slug' => 'ma-page',
'links' => [
['title' => 'Mon site', 'url' => 'https://exemple.fr'],
['title' => 'Contact', 'url' => 'bonjour@exemple.fr'],
],
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'name': 'Ma page',
'slug': 'ma-page',
'links': [
{'title': 'Mon site', 'url': 'https://exemple.fr'},
{'title': 'Contact', 'url': 'bonjour@exemple.fr'},
],
},
)
data = response.json()
Réponses possibles
{
"id": "P6ac40109381964",
"type": "page",
"name": "Ma page",
"description": "",
"slug": "ma-page",
"url": "https://tnylnk.fr/ma-page",
"status": "active",
"password_protected": false,
"restricted": false,
"tags": [],
"qr_code": null,
"created_at": "2026-10-05T21:56:57+02:00",
"edit_url": "https://app.tinylink.fr/page-edit?id=P6ac40109381964",
"stats": {
"metric": "views",
"total": 0,
"last_30_days": 0
},
"links": [
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+02:00"
},
{
"id": "L6ac4011ee9fab",
"title": "Contact",
"description": "",
"url": "bonjour@exemple.fr",
"type": "email",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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."
}
} Nombre de pages de l'offre atteint
{
"error": {
"code": "plan_limit_reached",
"message": "The page limit of the plan has been reached."
}
} 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"
}
}
} Adresse personnalisée déjà utilisée par une page ou un lien
{
"error": {
"code": "slug_taken",
"message": "This slug is already taken.",
"details": {
"field": "slug"
}
}
} 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."
}
} Lire une page
GET/v1/pages/{id}
La page et ses liens, dans l'ordre d'affichage ; les liens archivés viennent en dernier. Portée Lecture.
curl https://api.tinylink.fr/v1/pages/ma-page \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/ma-page', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/ma-page');
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/ma-page',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"id": "P6ac40109381964",
"type": "page",
"name": "Ma page",
"description": "Tous mes liens au même endroit.",
"slug": "ma-page",
"url": "https://tnylnk.fr/ma-page",
"status": "active",
"password_protected": false,
"restricted": false,
"tags": [],
"qr_code": null,
"created_at": "2026-10-05T21:56:57+02:00",
"edit_url": "https://app.tinylink.fr/page-edit?id=P6ac40109381964",
"stats": {
"metric": "views",
"total": 340,
"last_30_days": 85
},
"links": [
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+02:00"
},
{
"id": "L6ac4011ee9fab",
"title": "Contact",
"description": "",
"url": "bonjour@exemple.fr",
"type": "email",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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 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."
}
} Modifier une page
PATCH/v1/pages/{id}
N'envoyez que les champs à changer : name, description, slug, password. null retire l'adresse personnalisée ou le mot de passe. La réponse est la page à jour. Portée Écriture.
curl -X PATCH https://api.tinylink.fr/v1/pages/P6ac40109381964 \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"description": "Tous mes liens au même endroit.",
"password": null
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964', {
method: 'PATCH',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
description: 'Tous mes liens au même endroit.',
password: null,
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964');
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([
'description' => 'Tous mes liens au même endroit.',
'password' => null,
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.patch(
'https://api.tinylink.fr/v1/pages/P6ac40109381964',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'description': 'Tous mes liens au même endroit.',
'password': None,
},
)
data = response.json()
Réponses possibles
{
"id": "P6ac40109381964",
"type": "page",
"name": "Ma page",
"description": "Tous mes liens au même endroit.",
"slug": "ma-page",
"url": "https://tnylnk.fr/ma-page",
"status": "active",
"password_protected": false,
"restricted": false,
"tags": [],
"qr_code": null,
"created_at": "2026-10-05T21:56:57+02:00",
"edit_url": "https://app.tinylink.fr/page-edit?id=P6ac40109381964",
"stats": {
"metric": "views",
"total": 340,
"last_30_days": 85
},
"links": [
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+02:00"
},
{
"id": "L6ac4011ee9fab",
"title": "Contact",
"description": "",
"url": "bonjour@exemple.fr",
"type": "email",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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 É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."
}
} Adresse personnalisée déjà utilisée par une page ou un lien
{
"error": {
"code": "slug_taken",
"message": "This slug is already taken.",
"details": {
"field": "slug"
}
}
} Aucun champ modifiable dans le corps
{
"error": {
"code": "validation_failed",
"message": "Nothing to update. Accepted fields: name, description, slug, password."
}
} É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."
}
} Supprimer une page
DELETE/v1/pages/{id}
Supprime la page, ses liens et ses statistiques. Irréversible. Portée Suppression.
curl -X DELETE https://api.tinylink.fr/v1/pages/P6ac40109381964 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
console.log(response.status); // 204
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964');
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/P6ac40109381964',
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."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Dupliquer une page
POST/v1/pages/{id}/duplicate
Crée une copie de la page dans le même environnement : réglages d'apparence et style suivi, logo et bannière, tous les liens, titres, composants et blocs d'intégration, dans le même ordre, avec leur visibilité, leur archivage et leurs images (fichiers propres à la copie). Ni l'adresse personnalisée, ni le mot de passe, ni les tags, ni le QR code ne sont repris. name (sinon le même nom) et slug sont facultatifs. Le plafond de pages de l'offre s'applique. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/duplicate \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{"name":"Ma page (copie)","slug":"ma-page-copie"}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/duplicate', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Ma page (copie)', slug: 'ma-page-copie' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/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' => 'Ma page (copie)', 'slug' => 'ma-page-copie']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/duplicate',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={'name': 'Ma page (copie)', 'slug': 'ma-page-copie'},
)
data = response.json()
Réponses possibles
{
"id": "P6ad34edcdd6ab6",
"type": "page",
"name": "Ma page (copie)",
"description": "",
"slug": "ma-page-copie",
"url": "https://tnylnk.fr/ma-page-copie",
"status": "active",
"password_protected": false,
"restricted": false,
"tags": [],
"qr_code": null,
"created_at": "2026-10-17T12:33:00+02:00",
"edit_url": "https://app.tinylink.fr/page-edit?id=P6ad34edcdd6ab6",
"stats": {
"metric": "views",
"total": 0,
"last_30_days": 0
},
"links": [
{
"id": "L6ad34edcdd9c3",
"title": "Site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": "https://content.tinylink.fr/page-image/logo_6ad34edcdd8b7.webp",
"created_at": "2026-10-17T12:33:00+02:00"
},
{
"id": "L6ad34edcddab2",
"title": "Section",
"description": "",
"url": null,
"type": "title",
"format": "TITLE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:33:00+02:00"
},
{
"id": "L6ad34edcddb85",
"title": "Caché",
"description": "",
"url": "https://exemple.org",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": false,
"archived": false,
"position": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:33:00+02:00"
},
{
"id": "L6ad34edcddc64",
"title": "Mes réseaux",
"description": null,
"url": null,
"type": "component",
"format": "COMPONENT",
"size": "FULL",
"visible": true,
"archived": false,
"position": 4,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:33:00+02:00",
"component_id": "C6ad34ed4599305"
}
]
} 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."
}
} Nombre de pages de l'offre atteint
{
"error": {
"code": "plan_limit_reached",
"message": "The page limit of the plan has been reached."
}
} 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."
}
} Adresse personnalisée déjà utilisée par une page ou un lien
{
"error": {
"code": "slug_taken",
"message": "This slug is already taken.",
"details": {
"field": "slug"
}
}
} 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."
}
} Lister les liens d'une page
GET/v1/pages/{id}/links
Les liens de la page, dans l'ordre d'affichage. type vaut url, email, tel, title, component (un composant posé sur la page, avec component_id) ou integration (un bloc d'intégration, avec integration) ; status vaut active, pending_review ou blocked. Portée Lecture.
curl https://api.tinylink.fr/v1/pages/P6ac40109381964/links \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964/links', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964/links');
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/P6ac40109381964/links',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+02:00"
},
{
"id": "L6ac4011eeb074",
"title": "Mes réseaux",
"description": "",
"url": null,
"type": "title",
"format": "TITLE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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 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."
}
} Ajouter un lien
POST/v1/pages/{id}/links
Ajoute un lien en bas de la page, ou plusieurs avec {"links": [ … ]} (100 au plus) : la réponse est alors {"data": [ … ]}. Les plafonds de liens de votre offre s'appliquent comme dans l'application. Portée Écriture.
title— obligatoire, sauf pour le formatSOCIAL; 100 caractères au plusurl— une adresse web, un e-mail ou un téléphone, avec ou sansmailto:/tel:; inutile pour unTITLEdescription— 1 000 caractères au plusformat—LIST(par défaut),BANNER,SQUARE,SOCIAL, ouTITLEpour un titre de sectionsize—FULL(par défaut) ouHALF, pourLIST,BANNERetSQUAREvisible—falsepour l'ajouter masquéposition— rang dans la page, 1 = en hautimage— l'adresse publique d'une image ou une data URI base64, recadrée en carré et en bannière ;crop.squareetcrop.banner({"x", "y", "w", "h"}) choisissent les zonesintegration_id,source… — pour un bloc alimenté par un compte connecté, voir Intégrations
curl -X POST https://api.tinylink.fr/v1/pages/P6ac40109381964/links \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{"title":"Mon site","url":"https://exemple.fr"}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964/links', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: 'Mon site', url: 'https://exemple.fr' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964/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' => 'Mon site', 'url' => 'https://exemple.fr']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ac40109381964/links',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={'title': 'Mon site', 'url': 'https://exemple.fr'},
)
data = response.json()
Réponses possibles
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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."
}
} Nombre de liens par page de l'offre atteint
{
"error": {
"code": "plan_limit_reached",
"message": "The plan allows 50 links per page (50 already used).",
"details": {
"max": 50,
"used": 50
}
}
} 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."
}
} 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"
}
}
} É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."
}
} Lire un lien
GET/v1/pages/{id}/links/{lien}
Un seul lien de la page, par son identifiant. Portée Lecture.
curl https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6');
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/P6ac40109381964/links/L6ac4011edb7c6',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"id": "L6ac4011edb7c6",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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 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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Modifier un lien
PATCH/v1/pages/{id}/links/{lien}
N'envoyez que les champs à changer : title, description, url, format, size, visible (masquer ou afficher), archived (archiver ou désarchiver) , position (déplacer) et image (comme à l'ajout ; null la retire). Un composant ne peut qu'être masqué, archivé ou déplacé ; un bloc d'intégration a ses propres champs, voir Intégrations. Portée Écriture.
curl -X PATCH https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6 \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{"title":"Mon site web","position":2,"visible":false}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6', {
method: 'PATCH',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({ title: 'Mon site web', position: 2, visible: false }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6');
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(['title' => 'Mon site web', 'position' => 2, 'visible' => false]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.patch(
'https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={'title': 'Mon site web', 'position': 2, 'visible': False},
)
data = response.json()
Réponses possibles
{
"id": "L6ac4011edb7c6",
"title": "Mon site web",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": false,
"archived": false,
"position": 2,
"status": "active",
"image": null,
"created_at": "2026-10-05T21:57:18+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 É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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Aucun champ modifiable dans le corps
{
"error": {
"code": "validation_failed",
"message": "Nothing to update. Accepted fields: title, description, url, format, size, visible, archived, position, image."
}
} 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"
}
}
} É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."
}
} Supprimer un lien
DELETE/v1/pages/{id}/links/{lien}
Supprime le lien, son image et ses statistiques, puis renumérote les suivants. Portée Suppression.
curl -X DELETE https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
console.log(response.status); // 204
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ac40109381964/links/L6ac4011edb7c6');
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/P6ac40109381964/links/L6ac4011edb7c6',
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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Modifier plusieurs liens
PATCH/v1/pages/{id}/links
Change plusieurs liens en une requête — par exemple la mise en page de toute une série : links liste jusqu'à 100 entrées {"id": …} suivies des champs à changer, comme pour un seul lien. Tout ou rien : à la première erreur, rien n'est enregistré, et le champ fautif est désigné (links[1].url). Les images s'envoient lien par lien. La réponse est la liste des liens de la page. Portée Écriture.
curl -X PATCH https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"links": [
{
"id": "L6ad34a0e84122",
"format": "BANNER",
"size": "HALF"
},
{
"id": "L6ad34a0e8467f",
"format": "BANNER",
"size": "HALF"
}
]
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links', {
method: 'PATCH',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
links: [
{ id: 'L6ad34a0e84122', format: 'BANNER', size: 'HALF' },
{ id: 'L6ad34a0e8467f', format: 'BANNER', size: 'HALF' },
],
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links');
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([
'links' => [
[
'id' => 'L6ad34a0e84122',
'format' => 'BANNER',
'size' => 'HALF',
],
[
'id' => 'L6ad34a0e8467f',
'format' => 'BANNER',
'size' => 'HALF',
],
],
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.patch(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'links': [
{'id': 'L6ad34a0e84122', 'format': 'BANNER', 'size': 'HALF'},
{'id': 'L6ad34a0e8467f', 'format': 'BANNER', 'size': 'HALF'},
],
},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "L6ad34a0e849a2",
"title": "Mes réseaux",
"description": "",
"url": null,
"type": "title",
"format": "TITLE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"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": 2,
"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": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:30+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 É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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Liste de liens absente ou vide
{
"error": {
"code": "validation_failed",
"message": "The \"links\" field must be a non-empty array of { \"id\": …, fields to change }.",
"details": {
"field": "links"
}
}
} 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"
}
}
} Bloc de composant : seuls l'affichage, l'archivage et la position se changent
{
"error": {
"code": "validation_failed",
"message": "A component block can only be shown, hidden, archived or moved here: edit the component itself through /v1/components."
}
} É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."
}
} Réordonner les liens
PUT/v1/pages/{id}/links/order
ids donne le nouvel ordre : les liens, titres et composants cités passent en tête, dans cet ordre ; les autres suivent dans leur ordre actuel. La réponse est la liste des liens de la page. Portée Écriture.
curl -X PUT https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/order \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{"ids":["L6ad34a0e849a2","L6ad34a0e84122"]}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/order', {
method: 'PUT',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({ ids: ['L6ad34a0e849a2', 'L6ad34a0e84122'] }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/order');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_votre_jeton', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['ids' => ['L6ad34a0e849a2', 'L6ad34a0e84122']]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.put(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/order',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={'ids': ['L6ad34a0e849a2', 'L6ad34a0e84122']},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "L6ad34a0e849a2",
"title": "Mes réseaux",
"description": "",
"url": null,
"type": "title",
"format": "TITLE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"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": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"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": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 3,
"status": "active",
"image": null,
"created_at": "2026-10-17T12:12:30+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 É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."
}
} Identifiant qui n'est pas un bloc de la page
{
"error": {
"code": "validation_failed",
"message": "Unknown link id: L6ac4011edb7c6.",
"details": {
"field": "ids[0]"
}
}
} É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."
}
} Changer l'image d'un lien
PUT/v1/pages/{id}/links/{lien}/image
POST/v1/pages/{id}/links/{lien}/image
image : l'adresse publique d'une image ou une data URI base64 ; pour envoyer un fichier, POST en multipart/form-data avec un champ image. JPEG, PNG ou WebP, 5 Mo au plus. Deux formats sont produits : un carré (formats LIST, SQUARE) et une bannière (BANNER), recadrables avec crop.square et crop.banner. Un titre ou un composant ne prend pas d'image. Portée Écriture.
curl -X PUT https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"image": "https://exemple.fr/visuel.jpg",
"crop": {
"square": {
"x": 0,
"y": 0,
"w": 800,
"h": 800
}
}
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image', {
method: 'PUT',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
image: 'https://exemple.fr/visuel.jpg',
crop: { square: { x: 0, y: 0, w: 800, h: 800 } },
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_votre_jeton', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode([
'image' => 'https://exemple.fr/visuel.jpg',
'crop' => ['square' => ['x' => 0, 'y' => 0, 'w' => 800, 'h' => 800]],
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.put(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'image': 'https://exemple.fr/visuel.jpg',
'crop': {'square': {'x': 0, 'y': 0, 'w': 800, 'h': 800}},
},
)
data = response.json()
Réponses possibles
{
"id": "L6ad34a0e84122",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": "https://content.tinylink.fr/page-image/logo_6ad34a0e8e7da.webp",
"created_at": "2026-10-17T12:12:30+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 É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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Image illisible, trop lourde ou d'un format refusé
{
"error": {
"code": "invalid_image",
"message": "The image could not be used: send a JPEG, PNG or WebP image (5 MB and 6000 px per side at most) as a public address, a base64 data URI, or a file sent with POST as multipart/form-data.",
"details": {
"field": "image"
}
}
} Un titre ou un composant ne prend pas d'image
{
"error": {
"code": "image_not_supported",
"message": "Titles and components do not take an image.",
"details": {
"field": "image"
}
}
} É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 l'image d'un lien
DELETE/v1/pages/{id}/links/{lien}/image
Supprime l'image du lien ; la réponse est le lien. Rien d'autre n'est supprimé : la portée Écriture suffit.
curl -X DELETE https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image', {
method: 'DELETE',
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_votre_jeton'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.delete(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a0e84122/image',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"id": "L6ad34a0e84122",
"title": "Mon site",
"description": "",
"url": "https://exemple.fr",
"type": "url",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"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."
}
} Aucun lien avec cet identifiant sur la page
{
"error": {
"code": "not_found",
"message": "Link not found on this page."
}
} Un titre ou un composant ne prend pas d'image
{
"error": {
"code": "image_not_supported",
"message": "Titles and components do not take an image.",
"details": {
"field": "image"
}
}
} É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."
}
}