A plan with the API
API access is included in the plans listed on the feature page. You also need an account with a confirmed email.
Everything you need to create and manage QR codes from your software: authentication, copy-ready examples and limits. The full reference for every endpoint is in the interactive documentation.
API access is included in the plans listed on the feature page. You also need an account with a confirmed email.
In Settings → API, name the key and copy it right away: we show it only once, then keep just a fingerprint.
Send the key in the Authorization header of every request. Responses are JSON, except images.
Every request to /api/v1/qrcodes carries the key as a Bearer token. The key starts with ogqr_ followed by 64 hex characters; website session tokens are not accepted.
Authorization: Bearer $QRCODENOW_API_KEY
https://dev.qrcodenow.ai/api/v1.429 with Retry-After: 60.401.A dynamic QR code points to our redirect address, so the destination can change after printing. For a link, type 2 with target_url is enough.
curl -X POST https://dev.qrcodenow.ai/api/v1/qrcodes \
-H "Authorization: Bearer $QRCODENOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"idtype": 2, "title": "Volantino autunno", "target_url": "https://example.com/autunno"}'
201 response (shortened)
{
"success": 1,
"data": {
"id": 128,
"code": "k3x9q2m7ab",
"idtype": 2,
"is_dynamic": 1,
"is_paused": 0,
"title": "Volantino autunno",
"target_url": "https://example.com/autunno",
"qr_image_url": "https://…/i/k3x9q2m7ab.png",
"scan_count": 0,
"my_role": "owner"
}
}
Keep id for later calls and code for the image. The QR code takes a slot in your plan quota, just like one created from the dashboard: when the quota is full the response is 403 with code: plan_qr_limit.
Types that encode the content in the QR code itself (vCard, WiFi, email…) read their fields from qr_payload, without target_url:
{
"idtype": 4,
"title": "Biglietto da visita",
"qr_payload": {
"firstname": "Giulia",
"lastname": "Bianchi",
"phone": "+39 333 1234567",
"email": "giulia@example.com"
}
}
The list is paginated: p is the page (from 1), c the items per page (100 max), srt the sort field (date_create, date_update, title, scan_count), o the direction (ASC or DESC) and s a search on title and code.
curl "https://dev.qrcodenow.ai/api/v1/qrcodes?p=1&c=50&srt=scan_count&o=DESC" \
-H "Authorization: Bearer $QRCODENOW_API_KEY"
The response contains rows, total (all results), count (those on this page) and page. A single QR code is GET /api/v1/qrcodes/{id}.
With PATCH you change title and target_url. The printed code stays the same: whoever scans it lands on the new destination right away. You need at least the editor role on the QR code.
curl -X PATCH https://dev.qrcodenow.ai/api/v1/qrcodes/128 \
-H "Authorization: Bearer $QRCODENOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"target_url": "https://example.com/inverno"}'
Every QR code has a public PNG image at qr_image_url; change the extension to .svg for the print-ready vector. No key needed. Add ?download=1 to download it as a file.
curl -o qr.svg "https://…/i/k3x9q2m7ab.svg?download=1"
To encode text without saving it to your account use POST /api/v1/qrcodes/static: it replies with the PNG directly and uses no quota. The text can be up to 1273 bytes long.
curl -X POST https://dev.qrcodenow.ai/api/v1/qrcodes/static \
-H "Authorization: Bearer $QRCODENOW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "Testo da codificare"}' \
-o static-qr.png
Only the owner can delete a QR code. The response is 204 with no body; from then on the printed code no longer redirects.
curl -X DELETE https://dev.qrcodenow.ai/api/v1/qrcodes/128 \
-H "Authorization: Bearer $QRCODENOW_API_KEY"
Dynamic types require target_url. The others are direct: the content lives inside the QR code and goes in qr_payload.
idtype |
Type | Mode | Fields |
|---|---|---|---|
1 |
App store (iOS, Android, desktop) | Dynamic | target_url, url_ios, url_android, url_desktop |
2 |
Website link | Dynamic | target_url |
3 |
Digital menu | Dynamic | target_url |
4 |
Business card (vCard) | Direct | firstname, lastname, phone, email, company, role, address, website |
5 |
Social profile | Dynamic | target_url |
6 |
WiFi network | Direct | ssid, password, encryption (WPA | WEP | NOPASS), hidden |
7 |
Pre-filled email | Direct | email_to, email_subject, email_body |
8 |
Pre-filled SMS | Direct | sms_phone, sms_message |
9 |
WhatsApp chat | Direct | wa_phone, wa_message |
10 |
Phone call | Direct | phone_number |
11 |
Text | Direct | text |
12 |
Online document (PDF) | Dynamic | target_url |
13 |
Calendar event | Direct | event_title, event_location, event_start, event_end, event_description |
14 |
Map location | Direct | geo_lat, geo_lng |
Event dates in the format 2026-10-20T18:00. Required field combinations are checked on creation: on error the 422 response says which field is missing.
Application errors use the format below: error is a message and code an identifier. Validation returns 400 with error, message and optional per-field errors; 401 may omit code, and 429 has no body: check the HTTP status and Retry-After.
{ "success": 0, "error": "…", "code": "plan_qr_limit" }
400 |
Invalid JSON or fields that do not match the schema: check message and errors. |
|---|---|
401 |
API key missing, invalid or revoked. |
403 |
The QR code isn't shared with you, your role isn't enough, or the plan quota is full. |
404 |
QR code not found or deleted. |
409 |
Conflict: for example a member already present or the last owner of a QR code. |
422 |
Content rejected: missing field, invalid URL, unsupported type. |
429 |
Too many requests: retry after the seconds given in Retry-After. |