API reference
The HTTP API behind QRzoo. JSON in, JSON out. 6 endpoints.
Overview
Your networking page: the same operations the MCP server offers, for a script. Authenticate with an API key from your account page: Authorization: Bearer sk_qrzoo_…. A page lives at /<username> (3-30 lowercase letters, numbers or hyphens) and holds up to 12 QRs in order. A changed address keeps the old one reserved for your account for 90 days. Links are http(s) only. Errors are JSON { error, message }; too many changes in a minute is 429 rate_limited.
Base URL
https://qrzoo.com
Authentication
Send an API key in the Authorization header. Keys start with sk_qrzoo_. Create and revoke keys in your account. A key is shown once.
Authorization: Bearer sk_qrzoo_…
Page
Get your page
GET/api/page
Example
curl 'https://qrzoo.com/api/page' \
-H 'Authorization: Bearer sk_qrzoo_…'
Responses
200 The page and its QRs in order.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}401 No or invalid API key.
{
"error": "string",
"message": "string"
}Claim or change your page
PUT/api/page
Without a page: claims username with display_name (both required). With one: changes only what is given. theme, icon and show_all change how it looks.
Request body
- usernamestring
3-30 lowercase letters, numbers or hyphens, starting and ending with a letter or number.
- display_namestring
At most 60 characters.
- subtitlestring
At most 60 characters.
- themestring
The page's look (grafito by default); the QRs stay ink on white in every one.
One of: "grafito", "papel", "lino", "salvia", "cielo", "tinta", "galeria", "terracota", "pista", "medianoche".
- iconobject
The icon the page gets on the phone's home screen.
- modestringrequired
monogram: the name's initials in the look's colours; emoji: one emoji; glyph: a network's mark.
One of: "monogram", "emoji", "glyph".
- emojistring
At most 16 characters.
- kindstring
glyph mode: whose mark, e.g. whatsapp.
- modestringrequired
- show_allboolean
true (the default): the page ends with a QR that opens the whole page.
Example
curl -X PUT 'https://qrzoo.com/api/page' \
-H 'Authorization: Bearer sk_qrzoo_…' \
-H 'Content-Type: application/json' \
-d '{"username":"string","display_name":"string","subtitle":"string","theme":"grafito","icon":{"mode":"monogram","emoji":"string","kind":"string"},"show_all":true}'
Responses
200 The changed page.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}201 The claimed page.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}400 Invalid or reserved address, or a missing name.
{
"error": "string",
"message": "string"
}409 The address is taken (or held for 90 days by the account that released it).
{
"error": "string",
"message": "string"
}QRs
Add a QR at the end of the page
POST/api/items
Request body
- valuestring
The main value: a phone number with country code (whatsapp, phone), a LinkedIn profile URL or slug, a username or profile URL (instagram, x, tiktok, github, telegram), an email address (email) or an http(s) URL (link). Not used by vcard.
At most 500 characters.
- messagestring
whatsapp: the first message the person who scans sends.
At most 200 characters.
- labelstring
A title shown instead of the kind's name.
At most 30 characters.
- firststring
vcard: first name.
At most 50 characters.
- laststring
vcard: last name (a first or last name is required).
At most 50 characters.
- orgstring
vcard: company.
At most 80 characters.
- titlestring
vcard: job title.
At most 80 characters.
- phonestring
vcard: phone number with country code.
At most 30 characters.
- emailstring
vcard: email address.
At most 254 characters.
- urlstring
vcard: website, an http(s) URL.
At most 500 characters.
- kindstringrequired
One of: "whatsapp", "linkedin", "instagram", "x", "tiktok", "github", "telegram", "email", "phone", "link", "calendar", "vcard".
Example
curl -X POST 'https://qrzoo.com/api/items' \
-H 'Authorization: Bearer sk_qrzoo_…' \
-H 'Content-Type: application/json' \
-d '{"value":"string","message":"string","label":"string","first":"string","last":"string","org":"string","title":"string","phone":"string","email":"string","url":"string","kind":"whatsapp"}'
Responses
201 The new QR and the page.
{
"item": {
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
},
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}400 A field is not valid for the kind.
{
"error": "string",
"message": "string"
}403 The page has its 12 QRs.
{
"error": "string",
"message": "string"
}404 No page yet: claim an address first.
{
"error": "string",
"message": "string"
}Change a QR (only the given fields)
PATCH/api/items/{id}
Path parameters
- idstringrequired
Request body
- valuestring
The main value: a phone number with country code (whatsapp, phone), a LinkedIn profile URL or slug, a username or profile URL (instagram, x, tiktok, github, telegram), an email address (email) or an http(s) URL (link). Not used by vcard.
At most 500 characters.
- messagestring
whatsapp: the first message the person who scans sends.
At most 200 characters.
- labelstring
A title shown instead of the kind's name.
At most 30 characters.
- firststring
vcard: first name.
At most 50 characters.
- laststring
vcard: last name (a first or last name is required).
At most 50 characters.
- orgstring
vcard: company.
At most 80 characters.
- titlestring
vcard: job title.
At most 80 characters.
- phonestring
vcard: phone number with country code.
At most 30 characters.
- emailstring
vcard: email address.
At most 254 characters.
- urlstring
vcard: website, an http(s) URL.
At most 500 characters.
Example
curl -X PATCH 'https://qrzoo.com/api/items/string' \
-H 'Authorization: Bearer sk_qrzoo_…' \
-H 'Content-Type: application/json' \
-d '{"value":"string","message":"string","label":"string","first":"string","last":"string","org":"string","title":"string","phone":"string","email":"string","url":"string"}'
Responses
200 The page.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}400 A field is not valid for the kind.
{
"error": "string",
"message": "string"
}404 No such QR on your page.
{
"error": "string",
"message": "string"
}Remove a QR
DELETE/api/items/{id}
Path parameters
- idstringrequired
Example
curl -X DELETE 'https://qrzoo.com/api/items/string' \
-H 'Authorization: Bearer sk_qrzoo_…'
Responses
200 The page.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}404 No such QR on your page.
{
"error": "string",
"message": "string"
}Move a QR
POST/api/items/{id}/move
Path parameters
- idstringrequired
Request body
- tostring | integerrequired
up,down, or a 1-based place.
Example
curl -X POST 'https://qrzoo.com/api/items/string/move' \
-H 'Authorization: Bearer sk_qrzoo_…' \
-H 'Content-Type: application/json' \
-d '{"to":"up"}'
Responses
200 The page in its new order.
{
"page": {
"exists": true,
"url": "string",
"username": "string",
"display_name": "string",
"subtitle": "string",
"items": [
{
"id": "string",
"position": 0,
"kind": "whatsapp",
"title": "string",
"handle": "string",
"href": "string",
"data": null
}
],
"max_items": 0,
"theme": "grafito",
"icon": {
"mode": "monogram",
"emoji": "string",
"kind": "string"
},
"show_all": true,
"icon_urls": null
}
}404 No such QR on your page.
{
"error": "string",
"message": "string"
}