Qravio

Developers

API Reference

Create, manage, and analyze QR codes programmatically with the Qravio REST API.

On this page

Introduction

The Qravio REST API lets you create, manage, and analyze QR codes programmatically. It’s available on the Pro and Agency plans. All requests are made over HTTPS and authenticated with an API key. Responses are JSON.

Base URL
https://api.qravio.app/api/public/v1

Authentication

Authenticate by sending your API key as a bearer token in the Authorization header (or the X-API-Key header). Create and manage keys in your dashboard under Developers. Keep keys secret — they carry full access to your workspace’s QR codes.

Authenticated request
curl https://api.qravio.app/api/public/v1/qrcodes \
  -H "Authorization: Bearer qr_live_your_api_key"

# Alternatively, use the X-API-Key header:
curl https://api.qravio.app/api/public/v1/qrcodes \
  -H "X-API-Key: qr_live_your_api_key"

Rate limits

Each workspace has a monthly call quota based on its plan. Every response includes rate-limit headers. Exceeding the quota returns 429 with a Retry-After header.

  • Free / StarterNo API access
  • Pro3,000 calls / month
  • Agency25,000 calls / month
Response headers
X-RateLimit-Limit: 25000
X-RateLimit-Remaining: 24871
X-RateLimit-Reset: 1781913600
X-RateLimit-Limitinteger

Your monthly call allowance.

X-RateLimit-Remaininginteger

Calls remaining in the current period.

X-RateLimit-Resetinteger

Unix epoch (seconds) when the quota resets.

Retry-Afterinteger

On 429 only — seconds until the quota resets.

Errors

Qravio uses standard HTTP status codes. Errors return a JSON body with a single detail message.

401Unauthorized

Missing, invalid, revoked, or expired API key.

402Payment Required

Your plan’s QR-code limit (max_qr) is reached.

403Forbidden

Workspace lacks api_access, or the QR type isn’t in your plan.

404Not Found

The QR code doesn’t exist in your workspace.

422Unprocessable Entity

Request payload failed validation.

429Too Many Requests

Monthly call quota exceeded. See Retry-After.

503Service Unavailable

Quota/usage lookup failed — retry shortly.

Error response
{
  "detail": "API access requires a Pro or higher plan."
}

The QR Code object

idstring (uuid)

Unique identifier for the QR code.

workspace_idstring (uuid)

The workspace that owns this QR code.

namestring

Display name.

typestring

QR type (e.g. website, vcard, business). See QR types.

categorystring

"dynamic" (editable destination) or "static".

short_codestring | null

6-char short code used in the scan URL.

statusstring | null

"active" or "inactive".

folder_idstring | null

Parent folder, if organized into one.

custom_domain_idstring | null

Verified custom domain used for the short link.

ab_enabledboolean

True when an A/B test is active (>1 active website destination). Server-computed.

is_password_protectedboolean

True when a visitor password gate is active.

destinationsarray<Destination>

Routing destinations (see below).

designobject | null

Visual design settings (dots, colors, logo, frame, output).

contentobject | null

Type-specific content payload. See QR types.

total_scansinteger

All-time scan count.

created_bystring | null

User who created the QR code.

created_atstring (ISO 8601) | null

Creation timestamp.

updated_atstring (ISO 8601) | null

Last update timestamp.

Destination object

idstring (uuid)

Destination identifier.

target_urlstring

The URL this destination routes to.

weightinteger | null

A/B routing weight 0–100 (default 100).

is_activeboolean | null

Whether this destination is active.

labelstring | null

Human-readable variant name.

variant_keystring | null

Stable variant id (a, b, c…) used for sticky routing & analytics.

rulesobject | null

Conditional routing rules (geo, device, time).

json
{
  "id": "9f8b2c1a-1234-4d5e-8f90-abc123def456",
  "workspace_id": "11111111-1111-1111-1111-111111111111",
  "name": "Spring campaign",
  "type": "website",
  "category": "dynamic",
  "short_code": "Ab3X9z",
  "status": "active",
  "ab_enabled": false,
  "is_password_protected": false,
  "destinations": [
    {
      "id": "22222222-2222-2222-2222-222222222222",
      "target_url": "https://example.com/spring",
      "weight": 100,
      "is_active": true,
      "label": "Landing",
      "variant_key": "a"
    }
  ],
  "content": { "url": "https://example.com/spring" },
  "total_scans": 1240,
  "created_at": "2026-06-22T10:15:00Z",
  "updated_at": "2026-06-22T10:15:00Z"
}

The Analytics object

total_scansinteger

All-time total scans.

unique_scansinteger

All-time unique (session-deduplicated) visitors.

scans_todayinteger

Scans so far in the current UTC day.

wow_changenumber

Week-over-week change as a percentage.

daily_scansarray<{ date, scans }>

Per-day series, clamped to your plan’s retention window.

scans_by_deviceobject

{ mobile, tablet, desktop, bot } counts.

scans_by_countryobject

Country code → scan count.

last_scanned_atstring (ISO 8601) | null

Timestamp of the most recent scan.

json
{
  "total_scans": 1240,
  "unique_scans": 980,
  "scans_today": 42,
  "wow_change": 12.5,
  "daily_scans": [
    { "date": "2026-06-21", "scans": 58 },
    { "date": "2026-06-22", "scans": 42 }
  ],
  "scans_by_device": { "mobile": 900, "tablet": 60, "desktop": 270, "bot": 10 },
  "scans_by_country": { "US": 720, "IN": 310, "GB": 95 },
  "last_scanned_at": "2026-06-22T11:02:00Z"
}
GET/qrcodes

List QR codes

Returns every QR code in the API key’s workspace, newest first.

Request
curl https://api.qravio.app/api/public/v1/qrcodes \
  -H "Authorization: Bearer qr_live_your_api_key"
200 OKAn array of QR Code objects.
Response
[
  { "id": "9f8b2c1a-…", "name": "Spring campaign", "type": "website", "total_scans": 1240, "…": "…" }
]
POST/qrcodes

Create a QR code

Creates a QR code in your workspace. For dynamic QRs, include at least one destination. The content object shape depends on type — see QR types. Plan limits (max_qr) and allowed dynamic_qr_types are enforced.

Body parameters

namestringRequired

Display name.

typestringRequired

QR type (e.g. website, vcard, business).

categorystringRequired

"dynamic" or "static".

contentobjectRequired

Type-specific payload. See QR types.

destinationsarray<Destination>

Required for dynamic QRs — where the code routes.

statusstring

Defaults to "active".

folder_idstring (uuid)

Organize into a folder.

custom_domain_idstring (uuid)

Use a verified custom domain.

designobject

Visual design (dots, colors, logo, frame, output).

page_designobject

Landing-page theme for page-type QRs.

Request
curl -X POST https://api.qravio.app/api/public/v1/qrcodes \
  -H "Authorization: Bearer qr_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spring campaign",
    "type": "website",
    "category": "dynamic",
    "content": { "url": "https://example.com/spring" },
    "destinations": [{ "target_url": "https://example.com/spring" }]
  }'
201 CreatedThe created QR Code object.
Response
{ "id": "9f8b2c1a-…", "short_code": "Ab3X9z", "type": "website", "…": "…" }
402 Payment RequiredQR-code limit reached for your plan.
403 ForbiddenThe QR type isn’t available on your plan.
GET/qrcodes/{id}

Retrieve a QR code

Fetches a single QR code by id.

Path parameters

idstring (uuid)Required

The QR code id. Must belong to your API key’s workspace.

Request
curl https://api.qravio.app/api/public/v1/qrcodes/9f8b2c1a-1234-4d5e-8f90-abc123def456 \
  -H "Authorization: Bearer qr_live_your_api_key"
200 OKThe QR Code object.
404 Not FoundNo such QR code in your workspace.
PATCH/qrcodes/{id}

Update a QR code

Partially updates a QR code. Send only the fields you want to change. Passing destinations replaces all existing destinations.

Path parameters

idstring (uuid)Required

The QR code id. Must belong to your API key’s workspace.

Body parameters

namestring

New display name.

statusstring

"active" or "inactive".

contentobject

Updated type-specific content.

destinationsarray<Destination>

Replaces all destinations.

designobject

Updated design.

folder_idstring | null

Move to a folder, or null to remove.

passwordstring

Enable a visitor password gate.

remove_passwordboolean

Set true to disable the password gate.

Request
curl -X PATCH https://api.qravio.app/api/public/v1/qrcodes/9f8b2c1a-1234-4d5e-8f90-abc123def456 \
  -H "Authorization: Bearer qr_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Summer campaign", "status": "active" }'
200 OKThe updated QR Code object.
DELETE/qrcodes/{id}

Delete a QR code

Permanently deletes a QR code. Printed codes using this short link will stop working.

Path parameters

idstring (uuid)Required

The QR code id. Must belong to your API key’s workspace.

Request
curl -X DELETE https://api.qravio.app/api/public/v1/qrcodes/9f8b2c1a-1234-4d5e-8f90-abc123def456 \
  -H "Authorization: Bearer qr_live_your_api_key"
204 No ContentDeleted. No response body.
GET/qrcodes/{id}/analytics

Get QR analytics

Returns scan analytics for a QR code. The daily series is clamped to your plan’s retention window.

Path parameters

idstring (uuid)Required

The QR code id. Must belong to your API key’s workspace.

Request
curl https://api.qravio.app/api/public/v1/qrcodes/9f8b2c1a-1234-4d5e-8f90-abc123def456/analytics \
  -H "Authorization: Bearer qr_live_your_api_key"
200 OKThe Analytics object.

QR types

When creating a QR code, the content object’s shape depends on the type. Each type reads from one field below (* = required). Available dynamic types depend on your plan.

Free

website, vcard_plus

Starter

website, vcard_plus, pdf, list_links, business

Pro / Agency

all 13: website, pdf, images, vcard_plus, video, list_links, mp3, business, social_media, event, coupon, apps, landing_page

website / urlcontent.urlurl
textcontent.texttext
emailcontent.emailContentemail*, subject, body
smscontent.smsContentnumber*, message*
whatsappcontent.whatsAppContentnumber*, message
wificontent.wifiContentnetwork_name*, encryption*, password, hidden
bitcoincontent.bitcoinContentaddress*, amount*, label, message
paypalcontent.paypalContentusername*, amount*, note
vcard / vcard_pluscontent.vCardContentfirst_name*, last_name*, phone, email, company, …
businesscontent.businessContentbusiness_name*, phone, email, address, business_hours, theme
social_mediacontent.socialMediaContentprofileName*, instagram, facebook, twitter, linkedin, youtube, website
eventcontent.eventContentevent_name, start_date, location, rsvp_url, …
couponcontent.couponContenttitle*, discountType, discountValue, code, terms
appscontent.appContentappName*, appStoreUrl, playStoreUrl
landing_pagecontent.landingPageContenttitle*, subtitle, buttonText, buttonUrl, theme
pdf / video / mp3content.fileContentfile_id*, file_path*, file_name*, content_type*, size_bytes*
imagescontent.imagesContentarray of file objects
list_linkscontent.listOfLinkContentprofile_name*, bio, links[] (id*, title*, url*)

Static types (available on all plans): url, text, vcard, email, sms, whatsapp, wifi, bitcoin, paypal.