Intégrations
Les comptes connectés dans Bibliothèque → Intégrations (YouTube, Shopify, Instagram, RSS…) alimentent des blocs de page qui se mettent à jour seuls : la dernière vidéo, un produit, le prochain événement. La connexion d'un compte se fait dans l'application ; l'API les lit et pose leurs blocs, sur une page comme dans un composant.
- GET
/v1/integrationsLister les intégrations - GET
/v1/integrations/{id}Lire une intégration - GET
/v1/integrations/{id}/elements?source=Lister les éléments d'une source - POST
/v1/pages/{id}/linksAjouter un bloc d'intégration - POST
/v1/pages/{id}/linksBloc d'un élément précis - PATCH
/v1/pages/{id}/links/{lien}Modifier un bloc d'intégration
Lister les intégrations
GET/v1/integrations
Les comptes connectés de l'environnement, le plus récent d'abord. status vaut active, reconnect_required (autorisation à renouveler dans l'application) ou error ; suspended signale un compte au-delà du plafond de l'offre ; used dit si un bloc l'affiche. Portée Lecture.
curl https://api.tinylink.fr/v1/integrations \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/integrations', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/integrations');
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/integrations',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "Int_6aac6c7feedf0",
"platform": "youtube",
"platform_name": "YouTube",
"name": "Axton",
"handle": "@axton_99",
"profile_url": "https://www.youtube.com/@axton_99",
"status": "active",
"suspended": false,
"used": false,
"last_synced_at": "2026-10-17T12:10:33+02:00",
"created_at": "2026-09-18T00:41:03+02:00"
},
{
"id": "Int_6aa862f59643e",
"platform": "shopify",
"platform_name": "Shopify",
"name": "POW'HER",
"handle": "powher.shop",
"profile_url": "https://powher.shop",
"status": "active",
"suspended": false,
"used": true,
"last_synced_at": "2026-10-17T12:10:54+02:00",
"created_at": "2026-09-14T23:11:17+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"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Lire une intégration
GET/v1/integrations/{id}
Le compte et ses sources : pour chacune, ses variables (fields, à citer dans les gabarits), son gabarit par défaut et ce qu'elle demande — none, rank (un rang, 1 à 5) ou required (un élément précis). Portée Lecture.
curl https://api.tinylink.fr/v1/integrations/Int_6aac6c7feedf0 \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/integrations/Int_6aac6c7feedf0', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/integrations/Int_6aac6c7feedf0');
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/integrations/Int_6aac6c7feedf0',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"id": "Int_6aac6c7feedf0",
"platform": "youtube",
"platform_name": "YouTube",
"name": "Axton",
"handle": "@axton_99",
"profile_url": "https://www.youtube.com/@axton_99",
"status": "active",
"suspended": false,
"used": false,
"last_synced_at": "2026-10-17T12:10:33+02:00",
"created_at": "2026-09-18T00:41:03+02:00",
"sources": [
{
"id": "chaine",
"label": "The channel",
"element": "none",
"fields": [
{
"name": "name",
"label": "Name",
"type": "text"
},
{
"name": "handle",
"label": "Handle",
"type": "text"
},
{
"name": "description",
"label": "Description",
"type": "text"
},
{
"name": "subscribers",
"label": "Subscribers",
"type": "number"
},
{
"name": "videos",
"label": "Number of videos",
"type": "number"
},
{
"name": "views",
"label": "Total views",
"type": "number"
},
{
"name": "avatar",
"label": "Profile picture",
"type": "image"
},
{
"name": "url",
"label": "Address",
"type": "url"
},
{
"name": "app_name",
"label": "Service name",
"type": "text"
}
],
"default_template": {
"title": "{{name}}",
"description": "{{subscribers}} Subscribers",
"image": "{{avatar}}"
}
},
{
"id": "derniere_video",
"label": "The latest video",
"element": "rank",
"fields": [
{
"name": "title",
"label": "Title",
"type": "text"
},
{
"name": "description",
"label": "Description",
"type": "text"
},
{
"name": "date",
"label": "Publication date",
"type": "date"
},
{
"name": "channel",
"label": "Channel name",
"type": "text"
},
{
"name": "views",
"label": "Views",
"type": "number"
},
{
"name": "likes",
"label": "Likes",
"type": "number"
},
{
"name": "comments",
"label": "Comments",
"type": "number"
},
{
"name": "thumbnail",
"label": "Thumbnail",
"type": "image"
},
{
"name": "url",
"label": "Address",
"type": "url"
},
{
"name": "app_name",
"label": "Service name",
"type": "text"
}
],
"default_template": {
"title": "{{title}}",
"description": "{{channel}}",
"image": "{{thumbnail}}"
}
}
]
} 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 intégration avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Integration 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."
}
} Lister les éléments d'une source
GET/v1/integrations/{id}/elements?source=
Pour une source à élément, les éléments proposés par le compte (produits d'une boutique, vidéos d'une chaîne…) : leur id est la valeur de element. Une liste vide n'est pas une erreur : certaines boutiques ferment leur catalogue, l'adresse de l'élément fonctionne alors toujours. Portée Lecture.
curl "https://api.tinylink.fr/v1/integrations/Int_6aa862f59643e/elements?source=produit" \
-H "Authorization: Bearer tl_votre_jeton"
const response = await fetch('https://api.tinylink.fr/v1/integrations/Int_6aa862f59643e/elements?source=produit', {
headers: { Authorization: 'Bearer tl_votre_jeton' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/integrations/Int_6aa862f59643e/elements?source=produit');
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/integrations/Int_6aa862f59643e/elements?source=produit',
headers={'Authorization': 'Bearer tl_votre_jeton'},
)
data = response.json()
Réponses possibles
{
"data": [
{
"id": "pack-explorher",
"title": "Pack Explor'HER",
"detail": "99,50 €",
"image": "https://cdn.shopify.com/s/files/1/0966/8814/4724/files/Les_indispensables_le_Pack_Explor_HER_POW_HER.png?v=1762246179"
},
{
"id": "pack-routine-skincare",
"title": "Pack ROUTINE SKINCARE",
"detail": "86,70 €",
"image": "https://cdn.shopify.com/s/files/1/0966/8814/4724/files/Pack_Skincare_POWHER_Routine_anti-age_Clean_Exfoli_Lift.png?v=1763384467"
}
]
} 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 intégration avec cet identifiant dans l'environnement
{
"error": {
"code": "not_found",
"message": "Integration not found in this environment."
}
} Source sans choix d'élément
{
"error": {
"code": "validation_failed",
"message": "The \"source\" parameter must be one of: produit.",
"details": {
"field": "source"
}
}
} Plus de 120 requêtes dans la minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Ajouter un bloc d'intégration
POST/v1/pages/{id}/links
La route d'ajout d'un lien, avec integration_id et source. Le bloc compte dans les liens de l'offre. La réponse donne le contenu actuel (title, url, image) et, dans integration, les gabarits. Portée Écriture.
integration_id— le compte connecté, obligatoiresource— ce que le bloc affiche (derniere_video,chaine,produit…), voirsourcesdu compteelement— pour une source à élément ("element": "required") : l'identifiant ou l'adresse de l'élément ; pour une source à rang ("rank") : 1 (le plus récent, par défaut) à 5title,description— gabarits avec les variables de la source, comme{{title}}; à défaut ceux dedefault_template. 100 et 200 caractères au plusimage_template— une variable d'image de la source ({{thumbnail}}), ounullpour aucune imageformat—LIST,BANNERouSQUARE;size,visible,positioncomme pour un lien- Pas de
url: l'adresse vient de la source (la vidéo, le produit…).
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"integration_id": "Int_6aac6c7feedf0",
"source": "derniere_video",
"format": "BANNER"
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
integration_id: 'Int_6aac6c7feedf0',
source: 'derniere_video',
format: 'BANNER',
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/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([
'integration_id' => 'Int_6aac6c7feedf0',
'source' => 'derniere_video',
'format' => 'BANNER',
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'integration_id': 'Int_6aac6c7feedf0',
'source': 'derniere_video',
'format': 'BANNER',
},
)
data = response.json()
Réponses possibles
{
"id": "L6ad34a155e711",
"title": "TurboBringue 2026 (22:22, Axton, Roi Rufus, One-T)",
"description": "Axton",
"url": "https://www.youtube.com/watch?v=_t55GnPn3bo",
"type": "integration",
"format": "BANNER",
"size": "FULL",
"visible": true,
"archived": false,
"position": 1,
"status": "active",
"image": "https://content.tinylink.fr/page-image/integ_Int_6aac6c7feedf0_derniere_video_thumbnail.webp",
"created_at": "2026-10-17T12:12:37+02:00",
"integration": {
"id": "Int_6aac6c7feedf0",
"platform": "youtube",
"source": "derniere_video",
"element": null,
"title_template": "{{title}}",
"description_template": "{{channel}}",
"image_template": "{{thumbnail}}",
"image_source": "platform"
}
} 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."
}
} Intégration suspendue par le plafond de l'offre
{
"error": {
"code": "integration_suspended",
"message": "This integration is suspended: it exceeds the plan of this environment's owner.",
"details": {
"field": "integration_id"
}
}
} 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."
}
} Intégration absente de l'environnement
{
"error": {
"code": "validation_failed",
"message": "Integration not found in this environment.",
"details": {
"field": "integration_id"
}
}
} Source que l'intégration ne propose pas
{
"error": {
"code": "validation_failed",
"message": "The \"source\" field must be one of: chaine, derniere_video, dernier_short, video, short.",
"details": {
"field": "source"
}
}
} Source « un … précis » sans élément
{
"error": {
"code": "validation_failed",
"message": "This source shows one precise element: the \"element\" field is required (see GET /v1/integrations/{id}/elements?source=…).",
"details": {
"field": "element"
}
}
} Élément introuvable chez la plateforme
{
"error": {
"code": "integration_element_not_found",
"message": "This element could not be read on the platform: unknown, unpublished, or a rank the account has not reached yet.",
"details": {
"field": "element"
}
}
} Gabarit qui cite une variable inconnue de la source
{
"error": {
"code": "invalid_template",
"message": "The \"title\" template uses a variable this source does not know. Variables: {{name}}, {{handle}}, {{description}}, {{subscribers}}, {{videos}}, {{views}}, {{avatar}}, {{url}}, {{app_name}}.",
"details": {
"field": "title"
}
}
} Adresse envoyée pour un bloc d'intégration
{
"error": {
"code": "validation_failed",
"message": "The address of an integration block comes from its source: do not send \"url\".",
"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."
}
} Bloc d'un élément précis
POST/v1/pages/{id}/links
Une source à élément demande element : il est relevé tout de suite chez la plateforme, et refusé s'il est introuvable. Ici un produit Shopify, avec un titre composé. Portée Écriture.
curl -X POST https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"integration_id": "Int_6aa862f59643e",
"source": "produit",
"element": "pack-explorher",
"title": "{{title}} — {{price}}",
"description": ""
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
integration_id: 'Int_6aa862f59643e',
source: 'produit',
element: 'pack-explorher',
title: '{{title}} — {{price}}',
description: '',
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/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([
'integration_id' => 'Int_6aa862f59643e',
'source' => 'produit',
'element' => 'pack-explorher',
'title' => '{{title}} — {{price}}',
'description' => '',
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'integration_id': 'Int_6aa862f59643e',
'source': 'produit',
'element': 'pack-explorher',
'title': '{{title}} — {{price}}',
'description': '',
},
)
data = response.json()
Réponses possibles
{
"id": "L6ad34a1de7ebe",
"title": "Pack Explor'HER — 99,50 €",
"description": "",
"url": "https://powher.shop/products/pack-explorher",
"type": "integration",
"format": "LIST",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": "https://content.tinylink.fr/page-image/integ_Int_6aa862f59643e_produit-pack-explorher_thumbnail.webp",
"created_at": "2026-10-17T12:12:45+02:00",
"integration": {
"id": "Int_6aa862f59643e",
"platform": "shopify",
"source": "produit",
"element": "pack-explorher",
"title_template": "{{title}} — {{price}}",
"description_template": "",
"image_template": "{{thumbnail}}",
"image_source": "platform"
}
} 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."
}
} Intégration suspendue par le plafond de l'offre
{
"error": {
"code": "integration_suspended",
"message": "This integration is suspended: it exceeds the plan of this environment's owner.",
"details": {
"field": "integration_id"
}
}
} 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."
}
} Intégration absente de l'environnement
{
"error": {
"code": "validation_failed",
"message": "Integration not found in this environment.",
"details": {
"field": "integration_id"
}
}
} Source que l'intégration ne propose pas
{
"error": {
"code": "validation_failed",
"message": "The \"source\" field must be one of: chaine, derniere_video, dernier_short, video, short.",
"details": {
"field": "source"
}
}
} Source « un … précis » sans élément
{
"error": {
"code": "validation_failed",
"message": "This source shows one precise element: the \"element\" field is required (see GET /v1/integrations/{id}/elements?source=…).",
"details": {
"field": "element"
}
}
} Élément introuvable chez la plateforme
{
"error": {
"code": "integration_element_not_found",
"message": "This element could not be read on the platform: unknown, unpublished, or a rank the account has not reached yet.",
"details": {
"field": "element"
}
}
} Gabarit qui cite une variable inconnue de la source
{
"error": {
"code": "invalid_template",
"message": "The \"title\" template uses a variable this source does not know. Variables: {{name}}, {{handle}}, {{description}}, {{subscribers}}, {{videos}}, {{views}}, {{avatar}}, {{url}}, {{app_name}}.",
"details": {
"field": "title"
}
}
} Adresse envoyée pour un bloc d'intégration
{
"error": {
"code": "validation_failed",
"message": "The address of an integration block comes from its source: do not send \"url\".",
"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."
}
} Modifier un bloc d'intégration
PATCH/v1/pages/{id}/links/{lien}
title, description, image_template, element, plus les champs de tout lien (format, size, visible, archived, position, image). Le compte et la source ne changent pas : pour afficher autre chose, ajoutez un bloc. Une image envoyée remplace celle de la plateforme ; la retirer retire aussi le gabarit d'image. Portée Écriture.
curl -X PATCH https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a1de7ebe \
-H "Authorization: Bearer tl_votre_jeton" \
-H "Content-Type: application/json" \
-d '{
"title": "{{title}}",
"description": "{{price}}",
"format": "SQUARE"
}'
const response = await fetch('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a1de7ebe', {
method: 'PATCH',
headers: {
Authorization: 'Bearer tl_votre_jeton',
'Content-Type': 'application/json',
},
body: JSON.stringify({
title: '{{title}}',
description: '{{price}}',
format: 'SQUARE',
}),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a1de7ebe');
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' => '{{title}}',
'description' => '{{price}}',
'format' => 'SQUARE',
]),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.patch(
'https://api.tinylink.fr/v1/pages/P6ad34a0e4fef09/links/L6ad34a1de7ebe',
headers={'Authorization': 'Bearer tl_votre_jeton'},
json={
'title': '{{title}}',
'description': '{{price}}',
'format': 'SQUARE',
},
)
data = response.json()
Réponses possibles
{
"id": "L6ad34a1de7ebe",
"title": "Pack Explor'HER",
"description": "99,50 €",
"url": "https://powher.shop/products/pack-explorher",
"type": "integration",
"format": "SQUARE",
"size": "FULL",
"visible": true,
"archived": false,
"position": 2,
"status": "active",
"image": "https://content.tinylink.fr/page-image/integ_Int_6aa862f59643e_produit-pack-explorher_thumbnail.webp",
"created_at": "2026-10-17T12:12:45+02:00",
"integration": {
"id": "Int_6aa862f59643e",
"platform": "shopify",
"source": "produit",
"element": "pack-explorher",
"title_template": "{{title}}",
"description_template": "{{price}}",
"image_template": "{{thumbnail}}",
"image_source": "platform"
}
} 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."
}
} Intégration suspendue par le plafond de l'offre
{
"error": {
"code": "integration_suspended",
"message": "This integration is suspended: it exceeds the plan of this environment's owner.",
"details": {
"field": "integration_id"
}
}
} 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."
}
} Source « un … précis » sans élément
{
"error": {
"code": "validation_failed",
"message": "This source shows one precise element: the \"element\" field is required (see GET /v1/integrations/{id}/elements?source=…).",
"details": {
"field": "element"
}
}
} Élément introuvable chez la plateforme
{
"error": {
"code": "integration_element_not_found",
"message": "This element could not be read on the platform: unknown, unpublished, or a rank the account has not reached yet.",
"details": {
"field": "element"
}
}
} Gabarit qui cite une variable inconnue de la source
{
"error": {
"code": "invalid_template",
"message": "The \"title\" template uses a variable this source does not know. Variables: {{name}}, {{handle}}, {{description}}, {{subscribers}}, {{videos}}, {{views}}, {{avatar}}, {{url}}, {{app_name}}.",
"details": {
"field": "title"
}
}
} Adresse envoyée pour un bloc d'intégration
{
"error": {
"code": "validation_failed",
"message": "The address of an integration block comes from its source: do not send \"url\".",
"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."
}
}