QR Suite API
Create, manage, and track dynamic QR codes programmatically. Our REST API allows you to integrate QR code functionality directly into your applications.
Base URL
https://qrsuite.gr/api/v1
Quick Start
- 1 Create an API key in your account settings
-
2
Include your API key in the
Authorizationheader - 3 Make requests to create and manage QR codes
Available Endpoints
QR Codes
GET/qrcodesPOST/qrcodesGET/qrcodes/{shortCode}PUT/qrcodes/{shortCode}DELETE/qrcodes/{shortCode}POST/qrcodes/{shortCode}/toggle
Analytics
GET/qrcodes/{shortCode}/statsGET/qrcodes/{shortCode}/scans
Account
GET/accountGET/account/usage
Authentication
The API uses Bearer token authentication. Include your API key in the Authorization header of every request.
Keep your API key secure
Never expose your API key in client-side code or public repositories. Store it securely on your server.
Header Format
Authorization: Bearer YOUR_API_KEY
Example Request
curl -X GET "https://qrsuite.gr/api/v1/qrcodes" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
$client = new GuzzleHttp\Client();
$response = $client->request('GET', 'https://qrsuite.gr/api/v1/qrcodes', [
'headers' => [
'Authorization' => 'Bearer YOUR_API_KEY',
'Accept' => 'application/json',
],
]);
$data = json_decode($response->getBody(), true);
const response = await fetch('https://qrsuite.gr/api/v1/qrcodes', {
method: 'GET',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
},
});
const data = await response.json();
import requests
response = requests.get(
'https://qrsuite.gr/api/v1/qrcodes',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
}
)
data = response.json()
API Key Permissions
When creating an API key, you can select which permissions it has:
| Permission | Description | Allowed Operations |
|---|---|---|
read |
View QR codes and analytics | GET endpoints |
write |
Create and update QR codes | POST, PUT endpoints |
delete |
Delete QR codes | DELETE endpoints |
Rate Limits
API rate limits are based on your subscription plan. Rate limits are applied per API key on an hourly basis.
Rate Limit Headers
Every API response includes headers to help you track your rate limit usage:
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed per hour |
X-RateLimit-Remaining |
Remaining requests in the current window |
X-RateLimit-Reset |
Unix timestamp when the rate limit resets |
Retry-After |
Seconds until you can retry (only when rate limited) |
Rate Limit Exceeded Response
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. You can make 1000 requests per hour.",
"retry_after": 1847
}
Error Handling
The API uses standard HTTP status codes to indicate success or failure. All error responses include a JSON body with details.
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Insufficient permissions or feature access |
| 404 | Not Found | Resource does not exist |
| 422 | Validation Error | Invalid input data |
| 429 | Too Many Requests | Rate limit or quota exceeded |
| 500 | Server Error | Internal server error |
Error Response Format
{
"error": "Validation Error",
"message": "Invalid input data.",
"errors": {
"destination_url": [
"The destination url field is required."
]
}
}
QR Codes
Create and manage dynamic QR codes. Dynamic QR codes allow you to change the destination URL without reprinting the QR code.
Get a paginated list of your dynamic QR codes.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page |
integer | Page number (default: 1) |
per_page |
integer | Items per page, max 100 (default: 15) |
Example Response
{
"data": [
{
"id": 1,
"short_code": "abc123",
"title": "Summer Campaign",
"destination_url": "https://example.com/summer",
"redirect_url": "https://qrsuite.gr/go/abc123",
"is_active": true,
"is_expired": false,
"has_password": false,
"total_scans": 1250,
"unique_scans": 890,
"scan_limit": null,
"expires_at": null,
"utm_parameters": {
"utm_source": "qr",
"utm_campaign": "summer"
},
"created_at": "2024-01-15T10:30:00+00:00",
"updated_at": "2024-01-20T14:45:00+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 72
}
}
Create a new dynamic QR code. Requires write permission.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
destination_url |
string | Yes | Target URL for the QR code |
title |
string | No | Title for the QR code |
expires_at |
datetime | No | Expiration date (ISO 8601 format) |
password |
string | No | Password to protect the QR code (4-100 chars) |
scan_limit |
integer | No | Maximum number of scans allowed |
utm_source |
string | No | UTM source parameter |
utm_medium |
string | No | UTM medium parameter |
utm_campaign |
string | No | UTM campaign parameter |
Example Request
{
"destination_url": "https://example.com/landing-page",
"title": "Summer Campaign 2024",
"expires_at": "2024-12-31T23:59:59Z",
"utm_source": "qr",
"utm_medium": "print",
"utm_campaign": "summer-2024"
}
Example Response (201)
{
"message": "QR code created successfully.",
"data": {
"id": 123,
"short_code": "xyz789",
"title": "Summer Campaign 2024",
"destination_url": "https://example.com/landing-page",
"redirect_url": "https://qrsuite.gr/go/xyz789",
"is_active": true,
"is_expired": false,
"has_password": false,
"total_scans": 0,
"unique_scans": 0,
"scan_limit": null,
"expires_at": "2024-12-31T23:59:59+00:00",
"utm_parameters": {
"utm_source": "qr",
"utm_medium": "print",
"utm_campaign": "summer-2024"
},
"created_at": "2024-06-15T10:30:00+00:00",
"updated_at": "2024-06-15T10:30:00+00:00"
}
}
Retrieve details of a specific QR code by its short code.
Path Parameters
shortCode |
string | The unique short code of the QR code |
Update an existing QR code. Requires write permission. Only include fields you want to update.
Request Body
| Field | Type | Description |
|---|---|---|
destination_url |
string | New target URL |
title |
string | New title |
is_active |
boolean | Enable or disable the QR code |
expires_at |
datetime|null | New expiration date, or null to remove |
password |
string | Set a new password |
remove_password |
boolean | Set to true to remove password protection |
scan_limit |
integer|null | New scan limit, or null to remove |
Example Request
{
"destination_url": "https://example.com/new-page",
"is_active": true
}
Permanently delete a QR code. Requires delete permission. This action cannot be undone.
Deleting a QR code will also delete all associated scan data and analytics.
Toggle the active state of a QR code (activate/deactivate). Requires write permission.
Analytics
View scan statistics and detailed analytics for your QR codes. Analytics access requires a subscription plan with analytics features enabled.
Returns comprehensive statistics including total scans, geographic distribution, device breakdown, and time-based analytics.
Query Parameters
range |
string | Date range: 7, 30, 90, year, or all (default: 30) |
Example Response
{
"data": {
"short_code": "abc123",
"overview": {
"total_scans": 1250,
"unique_scans": 890,
"period_scans": 150,
"period_unique": 95
},
"is_active": true,
"is_expired": false,
"has_reached_limit": false,
"can_be_scanned": true,
"countries": [
{
"country_code": "US",
"country_name": "United States",
"count": 450,
"unique_count": 320
},
{
"country_code": "GB",
"country_name": "United Kingdom",
"count": 180,
"unique_count": 120
}
],
"devices": [
{"device_type": "mobile", "count": 800},
{"device_type": "desktop", "count": 350},
{"device_type": "tablet", "count": 100}
],
"browsers": [
{"browser_name": "Chrome", "count": 600},
{"browser_name": "Safari", "count": 450}
],
"date_range": {
"start": "2024-05-15T00:00:00+00:00",
"end": "2024-06-15T00:00:00+00:00"
},
"created_at": "2024-01-15T10:30:00+00:00"
}
}
Returns a paginated list of individual scan events with location, device, and timing information.
Query Parameters
page |
integer | Page number (default: 1) |
per_page |
integer | Items per page, max 100 (default: 25) |
start_date |
date | Filter from this date (Y-m-d format) |
end_date |
date | Filter until this date (Y-m-d format) |
unique_only |
boolean | Only return unique scans (default: false) |
Example Response
{
"data": [
{
"id": 12345,
"scanned_at": "2024-06-15T14:30:00+00:00",
"is_unique": true,
"location": {
"country_code": "US",
"country_name": "United States",
"region": "California",
"city": "San Francisco",
"timezone": "America/Los_Angeles"
},
"device": {
"type": "mobile",
"brand": "Apple",
"model": "iPhone"
},
"browser": {
"name": "Safari",
"version": "17.0"
},
"os": {
"name": "iOS",
"version": "17.5"
},
"referrer": {
"url": null,
"domain": null
},
"is_bot": false,
"language": "en-US"
}
],
"meta": {
"current_page": 1,
"last_page": 50,
"per_page": 25,
"total": 1250
}
}
Account
View your account information and usage statistics.
Returns basic account information including subscription plan and feature access.
Example Response
{
"data": {
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"timezone": "Europe/Athens",
"locale": "en",
"plan": {
"name": "Professional",
"slug": "professional"
},
"features": {
"has_analytics": true,
"has_advanced_analytics": true,
"has_api_access": true
},
"email_verified_at": "2024-01-01T12:00:00+00:00",
"created_at": "2024-01-01T00:00:00+00:00"
}
}
Returns current usage statistics including QR code counts, scan quotas, and API rate limit information.
Example Response
{
"data": {
"static_qr": {
"used": 45,
"limit": 100,
"unlimited": false
},
"dynamic_qr": {
"used": 12,
"limit": 50,
"unlimited": false
},
"scans": {
"used": 2500,
"limit": 10000,
"unlimited": false
},
"api_calls_this_hour": 45,
"api_rate_limit": 1000
}
}