API Reference

The authenticated REST API for QR code generation, analytics, and management. Available on the Developer and Pro plans.

Machine-readable spec: /api/v1/openapi.jsonGenerated from the same source as this page, so the two cannot disagree.

Quick Start (Authenticated API)

Get started with our authenticated API in minutes

1. Get Your API Key

Sign up for the Developer or Pro plan to get your API key from the dashboard.

curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://theqrcode.io/api/v1/qr-codes

2. Create Your First QR Code

Use our simple API to generate QR codes programmatically.

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type": "url", "content": "https://example.com"}' \
  https://theqrcode.io/api/v1/qr-codes

API Features

Features for developers and integrations

RESTful API

Clean, intuitive REST API following industry standards with comprehensive documentation.

API Key Authentication

Secure API key-based authentication with rate limiting and usage tracking.

High Performance

Fast API responses backed by a global CDN and optimized infrastructure.

Enterprise Security

Bank-level security with encryption, audit logs, and compliance standards.

Real-time Analytics

Access comprehensive analytics data through our analytics API endpoints.

Webhook Support

Real-time notifications for QR code events with configurable webhook endpoints.

API Endpoints

Complete reference for all available API endpoints

POST/api/v1/qr-codes
Pro

Create a new QR code

Request Example

{
  "name": "My QR Code",
  "type": "url",
  "content": "https://example.com",
  "settings": {
    "size": 256,
    "color": {
      "dark": "#000000",
      "light": "#FFFFFF"
    },
    "frame": {
      "style": "square",
      "color": "#000000",
      "size": 20
    }
  },
  "isDynamic": false
}
Request Parameters
namestringRequired

Display name for the QR code

typestringRequired

QR code type (url, text, wifi, contact, email, sms, vcard)

contentstringRequired

The content to encode in the QR code

settingsobject

QR code appearance settings

settings.sizenumber

QR code size in pixels (default: 256)

settings.colorobject

Color settings for the QR code

settings.color.darkstring

Dark color (hex code, default: #000000)

settings.color.lightstring

Light color (hex code, default: #FFFFFF)

settings.frameobject

Frame settings for the QR code (Pro plan; ignored otherwise, with a warning in the response)

settings.frame.stylestring

Frame style: square (no frame), rounded, circle, dashed

settings.frame.colorstring

Frame color (hex code)

settings.frame.sizenumber

Frame size in pixels

isDynamicboolean

Whether the QR code can be updated after creation (default: false)

Response Example

{
  "id": "qr_123456789",
  "name": "My QR Code",
  "type": "url",
  "content": "https://example.com",
  "shortUrl": null,
  "settings": {
    "size": 256,
    "color": {
      "dark": "#000000",
      "light": "#FFFFFF"
    }
  },
  "isDynamic": false,
  "qrImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}
GET/api/v1/qr-codes
Pro

List all QR codes with pagination and filtering

Request Example

{
  "query": "?page=1&limit=20&type=url&isDynamic=false"
}
Request Parameters
pagenumber

Page number for pagination (default: 1)

limitnumber

Number of items per page (default: 20, max: 100)

typestring

Filter by QR code type (url, text, wifi, contact, email, sms, vcard)

isDynamicboolean

Filter by dynamic QR codes (true/false)

searchstring

Search by QR code name or content

sortstring

Sort field (createdAt, updatedAt, name, scanCount)

orderstring

Sort order (asc, desc, default: desc)

Response Example

{
  "data": [
    {
      "id": "qr_123456789",
      "name": "My QR Code",
      "type": "url",
      "content": "https://example.com",
      "shortUrl": null,
      "settings": {
        "size": 256
      },
      "isDynamic": false,
      "scanCount": 42,
      "lastScanned": "2024-01-15T10:30:00Z",
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 1,
    "pages": 1
  }
}
GET/api/v1/qr-codes/{id}
Pro

Get specific QR code details with recent scans

Request Example

{}

Response Example

{
  "id": "qr_123456789",
  "name": "My QR Code",
  "type": "url",
  "content": "https://example.com",
  "shortUrl": null,
  "settings": {
    "size": 256
  },
  "isDynamic": false,
  "scanCount": 42,
  "lastScanned": "2024-01-15T10:30:00Z",
  "recentScans": [
    {
      "id": "scan_123",
      "scannedAt": "2024-01-15T10:30:00Z",
      "device": "mobile",
      "country": "US",
      "browser": "Chrome",
      "os": "iOS"
    }
  ],
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}
PUT/api/v1/qr-codes/{id}
Pro

Update QR code name, content, or settings

Request Example

{
  "name": "Updated QR Code",
  "content": "https://updated-example.com",
  "settings": {
    "size": 512,
    "color": {
      "dark": "#FF0000",
      "light": "#FFFFFF"
    }
  }
}
Request Parameters
namestring

Updated display name for the QR code

contentstring

Updated content to encode in the QR code

settingsobject

Updated QR code appearance settings

settings.sizenumber

Updated QR code size in pixels

settings.colorobject

Updated color settings for the QR code

settings.color.darkstring

Updated dark color (hex code)

settings.color.lightstring

Updated light color (hex code)

settings.frameobject

Updated frame settings for the QR code (Pro plan; ignored otherwise, with a warning in the response)

settings.frame.stylestring

Updated frame style: square (no frame), rounded, circle, dashed

settings.frame.colorstring

Updated frame color (hex code)

settings.frame.sizenumber

Updated frame size in pixels

Response Example

{
  "id": "qr_123456789",
  "name": "Updated QR Code",
  "type": "url",
  "content": "https://updated-example.com",
  "shortUrl": null,
  "settings": {
    "size": 512,
    "color": {
      "dark": "#FF0000",
      "light": "#FFFFFF"
    }
  },
  "isDynamic": false,
  "qrImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T11:00:00Z"
}
DELETE/api/v1/qr-codes/{id}
Pro

Delete a QR code and all associated data

Request Example

{}

Response Example

null
POST/api/v1/qr-codes/bulk
Pro

Create multiple QR codes in a single request (up to 100)

Request Example

{
  "qrCodes": [
    {
      "name": "Product 1 QR",
      "type": "url",
      "content": "https://example.com/product1",
      "settings": {
        "size": 256,
        "color": {
          "dark": "#000000",
          "light": "#FFFFFF"
        }
      },
      "isDynamic": false
    },
    {
      "name": "Product 2 QR",
      "type": "url",
      "content": "https://example.com/product2",
      "settings": {
        "size": 256,
        "color": {
          "dark": "#0000FF",
          "light": "#FFFFFF"
        }
      },
      "isDynamic": true
    }
  ]
}
Request Parameters
qrCodesarrayRequired

Array of QR codes to create (max 100)

qrCodes[].namestringRequired

Display name for the QR code

qrCodes[].typestringRequired

QR code type (url, text, wifi, contact, email, sms, vcard)

qrCodes[].contentstringRequired

The content to encode in the QR code

qrCodes[].settingsobject

QR code appearance settings

qrCodes[].settings.sizenumber

QR code size in pixels (default: 256)

qrCodes[].settings.colorobject

Color settings for the QR code

qrCodes[].isDynamicboolean

Whether the QR code can be updated after creation (default: false)

Response Example

{
  "created": [
    {
      "id": "qr_123456789",
      "name": "Product 1 QR",
      "type": "url",
      "content": "https://example.com/product1",
      "shortUrl": null,
      "settings": {
        "size": 256,
        "color": {
          "dark": "#000000",
          "light": "#FFFFFF"
        }
      },
      "isDynamic": false,
      "qrImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-15T10:30:00Z"
    },
    {
      "id": "qr_987654321",
      "name": "Product 2 QR",
      "type": "url",
      "content": "https://example.com/product2",
      "shortUrl": "https://qr.io/abc123",
      "settings": {
        "size": 256,
        "color": {
          "dark": "#0000FF",
          "light": "#FFFFFF"
        }
      },
      "isDynamic": true,
      "qrImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...",
      "createdAt": "2024-01-15T10:30:01Z",
      "updatedAt": "2024-01-15T10:30:01Z"
    }
  ],
  "errors": [],
  "summary": {
    "total": 2,
    "successful": 2,
    "failed": 0
  }
}
DELETE/api/v1/qr-codes/bulk
Pro

Delete multiple QR codes in a single request (up to 100)

Request Example

{
  "qrCodeIds": [
    "qr_123456789",
    "qr_987654321",
    "qr_111222333"
  ]
}
Request Parameters
qrCodeIdsarrayRequired

Array of QR code IDs to delete (max 100)

Response Example

{
  "deleted": 2,
  "notFound": [
    "qr_111222333"
  ],
  "summary": {
    "total": 3,
    "deleted": 2,
    "notFound": 1
  }
}
GET/api/v1/analytics
Pro

Get comprehensive analytics data

Request Example

{
  "query": "?qrCodeId=qr_123&timeRange=30d&includeScans=true"
}
Request Parameters
qrCodeIdstring

Specific QR code ID to get analytics for

timeRangestring

Time range for analytics (1h, 1d, 7d, 30d, 90d, 1y, default: 30d)

includeScansboolean

Include individual scan data in response (default: false)

timezonestring

IANA time zone for date grouping, e.g. America/Chicago. Omit for UTC and a rolling window; supply it to bucket by that zone's calendar days and measure timeRange in whole local days.

Response Example

{
  "summary": {
    "totalScans": 1250,
    "totalQRCodes": 5,
    "timeRange": "30d",
    "startDate": "2024-01-01T00:00:00Z",
    "endDate": "2024-01-31T23:59:59Z",
    "timeZone": "UTC",
    "uniqueVisitors": 850,
    "avgScansPerQR": 250,
    "mostActiveDay": "2024-01-15"
  },
  "breakdowns": {
    "devices": {
      "mobile": 800,
      "desktop": 300,
      "tablet": 150
    },
    "countries": {
      "US": 600,
      "CA": 300,
      "UK": 200,
      "DE": 150
    },
    "browsers": {
      "Chrome": 700,
      "Safari": 300,
      "Firefox": 150,
      "Edge": 100
    },
    "os": {
      "iOS": 400,
      "Android": 400,
      "Windows": 300,
      "macOS": 150
    }
  },
  "distributions": {
    "hourly": [
      {
        "hour": 0,
        "count": 10
      },
      {
        "hour": 1,
        "count": 5
      }
    ],
    "weekly": [
      {
        "day": 0,
        "count": 200
      },
      {
        "day": 1,
        "count": 180
      }
    ]
  },
  "dailyScans": [
    {
      "date": "2024-01-01",
      "count": 25
    },
    {
      "date": "2024-01-02",
      "count": 30
    }
  ],
  "topQRCodes": [
    {
      "id": "qr_123",
      "name": "Main QR Code",
      "type": "url",
      "scanCount": 500,
      "isDynamic": true
    }
  ]
}
GET/api/v1/api-keys
Pro

List all API keys for the authenticated user

Request Example

{}

Response Example

{
  "data": [
    {
      "id": "ak_123456789",
      "name": "Production API Key",
      "permissions": [
        "qr:read",
        "qr:write",
        "analytics:read"
      ],
      "rateLimit": 1000,
      "isActive": true,
      "lastUsedAt": "2024-01-15T10:30:00Z",
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}
POST/api/v1/api-keys
Pro

Create a new API key with custom permissions

Request Example

{
  "name": "Development API Key",
  "permissions": [
    "qr:read",
    "qr:write"
  ],
  "expiresAt": "2024-12-31T23:59:59Z"
}
Request Parameters
namestringRequired

Display name for the API key

permissionsarrayRequired

Array of permissions (qr:read, qr:write, analytics:read, webhooks:manage)

expiresAtstring

Expiration date for the API key (ISO 8601 format)

rateLimitnumber

Custom rate limit (requests per hour, max based on plan)

descriptionstring

Optional description for the API key

Response Example

{
  "id": "ak_987654321",
  "name": "Development API Key",
  "apiKey": "qrc_1234567890abcdef...",
  "permissions": [
    "qr:read",
    "qr:write"
  ],
  "rateLimit": 1000,
  "expiresAt": "2024-12-31T23:59:59Z",
  "isActive": true,
  "createdAt": "2024-01-15T10:30:00Z"
}
GET/api/v1/webhooks
Pro

List all webhooks

Request Example

{}

Response Example

{
  "data": [
    {
      "id": "wh_123456789",
      "name": "Scan Notifications",
      "url": "https://myapp.com/webhooks/qr-scans",
      "events": [
        "scan.created",
        "qr.created"
      ],
      "isActive": true,
      "lastTriggeredAt": "2024-01-15T10:30:00Z",
      "failureCount": 0,
      "eventCount": 150,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}
POST/api/v1/webhooks
Pro

Create a new webhook

Request Example

{
  "name": "QR Code Events",
  "url": "https://myapp.com/webhooks/qr-events",
  "events": [
    "qr.created",
    "qr.updated",
    "qr.deleted"
  ]
}
Request Parameters
namestringRequired

Display name for the webhook

urlstringRequired

Webhook endpoint URL (must be a public HTTPS address)

eventsarrayRequired

Events to subscribe to: scan.created, qr.created, qr.updated, qr.deleted

Response Example

{
  "id": "wh_987654321",
  "name": "QR Code Events",
  "url": "https://myapp.com/webhooks/qr-events",
  "events": [
    "qr.created",
    "qr.updated",
    "qr.deleted"
  ],
  "secret": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "isActive": true,
  "createdAt": "2024-01-15T10:30:00Z"
}
GET/api/v1/webhooks/{id}
Pro

Get one webhook, with its recent delivery attempts

Request Example

{}

Response Example

{
  "id": "wh_123456789",
  "name": "Scan Notifications",
  "url": "https://myapp.com/webhooks/qr-scans",
  "events": [
    "scan.created"
  ],
  "isActive": true,
  "failureCount": 0,
  "eventCount": 42,
  "recentEvents": [
    {
      "id": "evt_1",
      "eventType": "scan.created",
      "status": "delivered",
      "attempts": 1,
      "createdAt": "2024-01-15T10:30:00Z",
      "deliveredAt": "2024-01-15T10:30:01Z"
    }
  ]
}
PUT/api/v1/webhooks/{id}
Pro

Update a webhook — change its URL, events, or pause it

Request Example

{
  "isActive": false
}
Request Parameters
namestring

Display name

urlstring

Endpoint URL (must be publicly reachable)

eventsarray

Events to subscribe to

isActiveboolean

Set false to pause delivery without deleting

Response Example

{
  "id": "wh_123456789",
  "name": "Scan Notifications",
  "url": "https://myapp.com/webhooks/qr-scans",
  "events": [
    "scan.created"
  ],
  "isActive": false,
  "updatedAt": "2024-01-15T11:00:00Z"
}
DELETE/api/v1/webhooks/{id}
Pro

Delete a webhook and its delivery history. Returns 204.

Request Example

{}

Response Example

{}
GET/api/v1/scans
Pro

List scan events across your QR codes. Supports `since` for polling — this is the endpoint the Zapier integration uses.

Request Example

{}
Request Parameters
qrCodeIdstring

Restrict to one QR code

sincestring

ISO timestamp; returns only scans after it

pagenumber

Page number, from 1

limitnumber

Results per page, max 100

Response Example

{
  "data": [
    {
      "id": "scan_123",
      "qrCodeId": "qr_123456789",
      "qrCodeName": "Restaurant Menu",
      "qrCodeType": "url",
      "shortUrl": "https://theqrcode.io/s/abc123",
      "scannedAt": "2024-01-15T10:30:00Z",
      "device": "mobile",
      "os": "iOS",
      "browser": "Safari",
      "country": "US",
      "city": "New York",
      "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 100,
    "total": 1,
    "pages": 1
  }
}

Webhooks

Get real-time notifications when QR codes are created, updated, or scanned. Useful for building reactive systems and keeping your data in sync.

Available Events

QR Code Events

Available
qr.createdNew QR code created
qr.updatedQR code content updated
qr.deletedQR code deleted

Scan Events

Available
scan.createdQR code scanned

Getting Started

1. Create a Webhook

POST /api/v1/webhooks
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "name": "My Webhook",
  "url": "https://myapp.com/webhooks/qr-events",
  "events": ["qr.created", "scan.created"]
}

2. Handle Incoming Events

// Verify webhook signature
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);

// Generate expected signature
const expectedSignature = hmac('sha256', secret)
  .update(payload)
  .digest('hex');

if (signature === expectedSignature) {
  // Process webhook event
  const event = req.body;
  console.log('Event type:', event.type);
  console.log('Data:', event.data);
}

Requirements

  • HTTPS endpoint required: All webhook URLs must use HTTPS for security
  • Fast response expected: Your endpoint should respond with 2xx status within 10 seconds
  • Retry policy: Failed webhooks will be retried up to 3 times with exponential backoff

Simple, transparent pricing

API access is included on the Developer and Pro plans. No hidden fees.

Free

Good for trying out QR codes

$0
Get Started
  • 10 QR codes
  • 1 dynamic (editable) code
  • 1,000 scans per month
  • Dashboard only, no API access

Starter

Dynamic codes and full analytics

$9/month
Subscribe
  • 100 QR codes
  • Every code can be dynamic
  • Full analytics: geo, device, time
  • Dashboard only, no API access
Recommended

Developer

Headless Pro: full API access, no dashboard

$19/month
Start Building
  • 500 QR codes
  • REST API: 5,000 req/hr
  • API keys (production + sandbox)
  • Analytics API
  • Webhooks
  • Authenticated MCP (Claude, Cursor)

Pro

Visual dashboard plus full API access

$29/month
Subscribe
  • 500 QR codes
  • REST API: 5,000 req/hr
  • Webhooks
  • Bulk management UI
  • Real-time visual analytics
  • Priority support

Full feature comparison →

Ready to start building?

Get your API key and start integrating QR codes into your applications today.

QR Code API: Docs, Examples & OpenAPI | TheQRCode.io