QR codes
The routes for the QR codes of a page or a short link, and the one for the environment's templates. The QR code encodes the element's short address: it stays valid if you change the destination or the custom address.
- POST
/v1/pages/{id}/qr-codeGenerate a QR code - POST
/v1/links/{id}/qr-codeGenerate a QR code - POST
/v1/pages/{id}/qr-code{"template": "none"}Generate without a logo - POST
/v1/links/{id}/qr-code{"template": "none"}Generate without a logo - GET
/v1/pages/{id}/qr-codeRead a QR code - GET
/v1/links/{id}/qr-codeRead a QR code - GET
/v1/pages/{id}/qr-code?format=pngDownload the file - GET
/v1/links/{id}/qr-code?format=svgDownload the file - GET
/v1/qr-templatesList the templates - POST
/v1/pages/{id}/qr-code{"template": "QRT_…"}Generate with one of your templates - POST
/v1/links/{id}/qr-code{"template": "QRT_…"}Generate with one of your templates
Generate a QR code
POST/v1/pages/{id}/qr-code
POST/v1/links/{id}/qr-code
Without a request body, the QR code is the classic template: black on white, with the TinyLink logo. Generating again replaces the previous QR code. For a QR code without a logo or in your colours, see the next two blocks. Write scope.
curl -X POST https://api.tinylink.fr/v1/links/6ac401093831b/qr-code \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code', {
method: 'POST',
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/links/6ac401093831b/qr-code',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"png": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.png",
"svg": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.svg",
"template": "classic",
"shape": "square",
"encoded_url": "https://tnlnk.fr/6ac401093831b&qr"
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} No short link with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Link not found in this environment."
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Generate without a logo
POST/v1/pages/{id}/qr-code{"template": "none"}
POST/v1/links/{id}/qr-code{"template": "none"}
template set to "none": black on white, without the TinyLink logo. Write scope.
curl -X POST https://api.tinylink.fr/v1/links/6ac401093831b/qr-code \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"template":"none"}'
const response = await fetch('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ template: 'none' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['template' => 'none']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/links/6ac401093831b/qr-code',
headers={'Authorization': 'Bearer tl_your_token'},
json={'template': 'none'},
)
data = response.json()
Possible responses
{
"png": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.png",
"svg": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.svg",
"template": "none",
"shape": "square",
"encoded_url": "https://tnlnk.fr/6ac401093831b&qr"
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} No short link with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Link not found in this environment."
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Read a QR code
GET/v1/pages/{id}/qr-code
GET/v1/links/{id}/qr-code
The addresses of the PNG (2048 px) and the SVG. With no QR code generated, the response is 404 qr_code_not_generated. Read scope.
curl https://api.tinylink.fr/v1/links/6ac401093831b/qr-code \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.get(
'https://api.tinylink.fr/v1/links/6ac401093831b/qr-code',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"png": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.png",
"svg": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.svg",
"template": "classic",
"shape": "square",
"encoded_url": "https://tnlnk.fr/6ac401093831b&qr"
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Read scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} No short link with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Link not found in this environment."
}
} The element has no QR code yet
{
"error": {
"code": "qr_code_not_generated",
"message": "No QR code has been generated for this element yet. Use POST on this address to create one."
}
} Element blocked or under review
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation: its QR code is not available."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Download the file
GET/v1/pages/{id}/qr-code?format=png
GET/v1/links/{id}/qr-code?format=svg
With ?format=png or ?format=svg, the response is no longer JSON but the file itself (image/png or image/svg+xml). Read scope.
curl "https://api.tinylink.fr/v1/links/6ac401093831b/qr-code?format=png" \
-H "Authorization: Bearer tl_your_token" \
-o qr-promo.png
const response = await fetch('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code?format=png', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const image = await response.blob();
$ch = curl_init('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code?format=png');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
file_put_contents('qr-promo.png', curl_exec($ch));
curl_close($ch);
import requests
response = requests.get(
'https://api.tinylink.fr/v1/links/6ac401093831b/qr-code?format=png',
headers={'Authorization': 'Bearer tl_your_token'},
)
with open('qr-promo.png', 'wb') as f:
f.write(response.content)
Possible responses
(the file itself: image/png or image/svg+xml) No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Read scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} No short link with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Link not found in this environment."
}
} The element has no QR code yet
{
"error": {
"code": "qr_code_not_generated",
"message": "No QR code has been generated for this element yet. Use POST on this address to create one."
}
} Element blocked or under review
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation: its QR code is not available."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} List the templates
GET/v1/qr-templates
The templates usable in template: the two TinyLink templates, then those created in the environment (Library, QR codes tab), with their shape (square, rounded or dots) and their colours (background, foreground). The environment's templates only appear with a plan that includes them, Pro or Business. Read scope.
curl https://api.tinylink.fr/v1/qr-templates \
-H "Authorization: Bearer tl_your_token"
const response = await fetch('https://api.tinylink.fr/v1/qr-templates', {
headers: { Authorization: 'Bearer tl_your_token' },
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/qr-templates');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token'],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.get(
'https://api.tinylink.fr/v1/qr-templates',
headers={'Authorization': 'Bearer tl_your_token'},
)
data = response.json()
Possible responses
{
"data": [
{
"id": "classic",
"name": "TinyLink",
"description": "Black on white, with the TinyLink logo.",
"shape": "square"
},
{
"id": "none",
"name": "No logo",
"description": "Black on white, without a logo.",
"shape": "square"
},
{
"id": "QRT_6a9f2935302bb",
"name": "Brand 2026",
"description": null,
"shape": "rounded",
"background": "#FFFFFF",
"foreground": "#212121"
}
]
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Read scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"read\" scope.",
"details": {
"required_scope": "read"
}
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
} Generate with one of your templates
POST/v1/pages/{id}/qr-code{"template": "QRT_…"}
POST/v1/links/{id}/qr-code{"template": "QRT_…"}
Pass in template the QRT_… id returned by the template list: the QR code takes its shape, colours and logo, and the response names it in template. The template must belong to the token's environment, and the plan must include templates; otherwise the response is 422 validation_failed. Write scope.
curl -X POST https://api.tinylink.fr/v1/links/6ac401093831b/qr-code \
-H "Authorization: Bearer tl_your_token" \
-H "Content-Type: application/json" \
-d '{"template":"QRT_6a9f2935302bb"}'
const response = await fetch('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code', {
method: 'POST',
headers: {
Authorization: 'Bearer tl_your_token',
'Content-Type': 'application/json',
},
body: JSON.stringify({ template: 'QRT_6a9f2935302bb' }),
});
const data = await response.json();
$ch = curl_init('https://api.tinylink.fr/v1/links/6ac401093831b/qr-code');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer tl_your_token', 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode(['template' => 'QRT_6a9f2935302bb']),
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
response = requests.post(
'https://api.tinylink.fr/v1/links/6ac401093831b/qr-code',
headers={'Authorization': 'Bearer tl_your_token'},
json={'template': 'QRT_6a9f2935302bb'},
)
data = response.json()
Possible responses
{
"png": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.png",
"svg": "https://content.tinylink.fr/QR_Code/QRCode_6ac4011f7a12f.svg",
"template": "QRT_6a9f2935302bb",
"shape": "rounded",
"encoded_url": "https://tnlnk.fr/6ac401093831b&qr"
} The body is not a JSON object
{
"error": {
"code": "invalid_json",
"message": "The request body must be a JSON object."
}
} No token in the request
{
"error": {
"code": "missing_token",
"message": "Send your token in the header: Authorization: Bearer tl_…"
}
} Unknown or revoked token
{
"error": {
"code": "invalid_token",
"message": "This token does not exist or has been revoked."
}
} The owner's plan does not include the API
{
"error": {
"code": "plan_required",
"message": "The TinyLink API is included in the Pro and Business plans. Upgrade the plan of this environment's owner to use it."
}
} The token does not carry the Write scope
{
"error": {
"code": "insufficient_scope",
"message": "This token does not have the \"write\" scope.",
"details": {
"required_scope": "write"
}
}
} No page with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Page not found in this environment."
}
} No short link with this id or slug in the environment
{
"error": {
"code": "not_found",
"message": "Link not found in this environment."
}
} Template missing from the environment
{
"error": {
"code": "validation_failed",
"message": "Unknown QR code template. Use \"classic\", \"none\" or a template id from GET /v1/qr-templates.",
"details": {
"field": "template"
}
}
} Element blocked by moderation
{
"error": {
"code": "element_blocked",
"message": "This element is blocked by moderation and can no longer be modified."
}
} More than 120 requests within the minute
{
"error": {
"code": "rate_limited",
"message": "Too many requests: 120 per minute per token."
}
}