Quick start
Send your API key as a Bearer token. Never expose a secret key in public browser code or a mobile app.
Authorization: Bearer qrl_test_YOUR_KEYSandbox keys start with qrl_test_. Production keys start with qrl_live_.
Usage limits
100 requests/month
3 total dynamic codes shared with the website
50,000 requests/month
1,000 active API codes
100,000 requests/month
2,000 active API codes
Enterprise allowances are configured for the agreed workload. Exceeding the monthly request allowance returns HTTP 429.
Endpoints
Base URL: https://qrlion.io
| Method | Path | Purpose |
|---|---|---|
| GET | /api/v1/usage | Return request usage, monthly allowance and active QR-code limits. |
| GET | /api/v1/qr-codes?limit=25 | List QR codes using cursor pagination. |
| POST | /api/v1/qr-codes | Create a dynamic QR code. |
| GET | /api/v1/qr-codes/{id} | Retrieve one QR code by UUID. |
| PATCH | /api/v1/qr-codes/{id} | Update an API-created code's destination, title, design or status. |
| DELETE | /api/v1/qr-codes/{id} | Permanently delete an API-created code. |
Create a QR code
title — string, 1–120 characters, required
type — supported content-type string, required
data — object containing fields for the selected type, required
customization — optional object supporting foreground, background and shape
Request
curl --request POST https://qrlion.io/api/v1/qr-codes \
--header "Authorization: Bearer qrl_test_YOUR_KEY" \
--header "Content-Type: application/json" \
--data '{
"title": "Product brochure",
"type": "pdf",
"data": {
"url": "https://example.com/brochure.pdf"
},
"customization": {
"foreground": "#10231d",
"background": "#ffffff",
"shape": "square"
}
}'HTTP 201 response
{
"data": {
"id": "2fc2d88e-...",
"slug": "AbC123xyz",
"title": "Product brochure",
"content_type": "pdf",
"active": true,
"environment": "sandbox",
"redirect_url": "https://qrlion.io/q/AbC123xyz"
}
}Supported content types
Purpose-specific types remain visible in API records and analytics.
| Type | Required data | Notes |
|---|---|---|
| url | data.url | Website or landing-page URL |
| data.url | Public PDF or brochure URL | |
| app | data.url | App Store, Google Play or app landing-page URL |
| social | data.url | Social profile, page or channel URL |
| google_form | data.url | Published Google Form URL |
| menu | data.url | Restaurant menu or ordering URL |
| data.email | Optional subject and message | |
| phone | data.phone | International number recommended |
| sms | data.phone | Optional message |
| data.phone | Digits with country code; optional message | |
| location | data.query | Address, place name or coordinates |
| calendar | data.title, data.start, data.end | ISO-8601 dates; optional location and details |
| vcard | A name or company | Names, company, job title, phone, email and website |
Listing, pagination and sources
Set limit from 1–100. When pagination.has_more is true, send pagination.next_cursor as the next request's cursor.
A sandbox key lists every QR code owned by the account. The source is website, sandbox_api, or live_api. Website-created codes are readable but protected from sandbox editing and deletion. Production keys list only live API records.
Errors and rate-limit headers
Errors use a consistent JSON envelope: {"error":{"code":"invalid_content","message":"..."}}
Malformed request, invalid key, or missing record.
Code limit, validation failure, or monthly request limit.
Authenticated responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.