# ScanBlitz API Reference > Complete API reference for the ScanBlitz QR code and analytics platform. Base URL: `https://scanblitz.com/api/enterprise` Auth: `Authorization: Bearer sb_api_...` Source tracking: Include `X-Source-Type: agent` header to tag your traffic. --- ## Authentication All endpoints require a Bearer token in the Authorization header. API keys use the `sb_api_` prefix followed by 64 hex characters. Keys are hashed with SHA-256 and stored securely. The key is only shown once at creation time. ### Permissions Keys can have granular permissions: | Permission | Actions | |------------|---------| | `qr_codes` | read, write, delete | | `campaigns` | read, write, delete | | `analytics` | read | --- ## Agent Self-Registration Agents can create accounts programmatically without a browser. ### POST /agent-register Send a 6-digit verification code to an email address. **URL:** `https://kylpeyhiqtdonlqqguty.supabase.co/functions/v1/agent-register` **Body:** ```json { "email": "agent@example.com", "agent_name": "My Agent" } ``` **Response (200):** ```json { "success": true, "message": "Verification code sent to agent@example.com", "expires_in_seconds": 600, "next_step": { "method": "POST", "url": "https://kylpeyhiqtdonlqqguty.supabase.co/functions/v1/agent-register/verify", "body": { "email": "agent@example.com", "code": "<6-digit code from email>" } } } ``` ### POST /agent-register/verify Complete registration and receive an API key. **URL:** `https://kylpeyhiqtdonlqqguty.supabase.co/functions/v1/agent-register/verify` **Body:** ```json { "email": "agent@example.com", "code": "123456" } ``` **Response (201):** ```json { "success": true, "api_key": "sb_api_...", "account": { "id": "uuid", "email": "agent@example.com", "name": "My Agent", "tier": "free" }, "limits": { "qr_codes": 50, "scans_per_month": 1000, "api_calls_per_month": 5000, "rate_limit": "60/min", "analytics_retention": "7 days" }, "mcp_setup": { "command": "npx", "args": ["-y", "@scanblitz/mcp-server"], "env": { "SCANBLITZ_API_KEY": "sb_api_..." } } } ``` **Rate limits:** 5 registration attempts per IP per hour. Codes expire in 10 minutes. Max 3 verify attempts per code. --- ## QR Codes ### POST /qr-codes Create a dynamic QR code with scan tracking. **Body:** ```json { "name": "Product Launch", "destination_url": "https://example.com/launch", "is_active": true, "expiry_date": "2026-12-31T23:59:59Z" } ``` Required: `name`, `destination_url` **Response (201):** ```json { "success": true, "data": { "id": "uuid", "short_id": "xK7mQ3", "name": "Product Launch", "destination_url": "https://example.com/launch", "scan_count": 0, "is_active": true, "created_at": "2026-05-14T12:00:00Z" } } ``` ### GET /qr-codes List QR codes with filtering and pagination. **Query params:** - `page` (int, default 1) - `limit` (int, default 50, max 100) - `search` (string) — search by name or URL - `active` (boolean) — filter by active status - `sort_by` (string) — `created_at`, `scan_count`, `name` - `sort_order` (string) — `asc`, `desc` ### GET /qr-codes/:id Get a single QR code by UUID. ### PUT /qr-codes/:id Update a QR code. Updatable fields: `name`, `destination_url`, `is_active`, `expiry_date`. ### DELETE /qr-codes/:id Delete a QR code permanently. ### POST /qr-codes/bulk Create up to 100 QR codes in one request. Pro and Scale plans only. **Body:** ```json { "qr_codes": [ { "name": "Store #1", "destination_url": "https://example.com/store/1" }, { "name": "Store #2", "destination_url": "https://example.com/store/2" } ] } ``` ### GET /qr-codes/:id/analytics Get scan analytics for a specific QR code. **Query params:** - `start_date` (ISO 8601) - `end_date` (ISO 8601) - `group_by` — `hour`, `day`, `week`, `month` **Response includes:** total scans, device breakdown, country/city breakdown, daily trends, referrers. --- ## Campaigns ### POST /campaigns Create a campaign to group QR codes. **Body:** ```json { "name": "Q1 Launch", "description": "Spring product launch campaign", "qr_code_ids": ["uuid1", "uuid2"] } ``` ### GET /campaigns List campaigns with QR code counts. **Query params:** `page`, `limit`, `search`, `sort_by`, `sort_order` ### GET /campaigns/:id Get a single campaign. Add `?include_qr_codes=true` to include associated QR codes. ### PUT /campaigns/:id Update campaign. If `qr_code_ids` is provided, replaces all associations. ### DELETE /campaigns/:id Delete campaign and all QR code associations. ### GET /campaigns/:id/analytics Aggregated analytics across all QR codes in the campaign. ### POST /campaigns/:id/qr-codes Add QR codes to a campaign. **Body:** ```json { "qr_code_ids": ["uuid1", "uuid2"] } ``` ### DELETE /campaigns/:id/qr-codes/:qr_code_id Remove a QR code from a campaign. --- ## Analytics ### GET /analytics/overview High-level dashboard data. **Response includes:** total scans, top 5 QR codes, scans by day (last 7), top 5 countries, device breakdown (mobile/desktop/tablet). ### GET /analytics/scans Detailed scan data with filtering. **Query params:** - `start_date`, `end_date` (ISO 8601) - `qr_code_ids` (comma-separated UUIDs) - `campaign_ids` (comma-separated UUIDs) - `group_by` — `hour`, `day`, `week`, `month` - `page`, `limit` (max 1000) ### GET /analytics/performance Performance metrics for QR codes and campaigns, sortable by scan count. ### GET /analytics/geographic Geographic scan distribution. **Query params:** - `level` — `country` or `city` - `start_date`, `end_date` ### POST /analytics/export Export analytics as JSON or CSV. **Body:** ```json { "format": "csv", "start_date": "2026-01-01", "end_date": "2026-05-14", "qr_code_ids": ["uuid1"], "campaign_ids": ["uuid2"] } ``` --- ## Account ### GET /info Returns API version, available endpoints, your rate limit tier, and permissions. ### GET /usage Usage statistics for a date range. **Query params:** `start_date`, `end_date` **Response includes:** total requests, successful/error counts, average response time, requests by endpoint, quota usage. ### GET /api-keys List your API keys (key values are not returned). ### POST /api-keys Create a new API key. **Body:** ```json { "name": "Production Key", "permissions": [ { "resource": "qr_codes", "actions": ["read", "write", "delete"] }, { "resource": "analytics", "actions": ["read"] } ], "expires_at": "2027-01-01T00:00:00Z" } ``` ### DELETE /api-keys/:keyId Revoke an API key. ### GET /health Health check (no auth required). Returns `{ status: "healthy" }`. --- ## Rate Limits | Tier | Requests/min | Requests/hour | Requests/day | |------|-------------|---------------|-------------| | Free (basic) | 60 | 1,000 | 10,000 | | Pro (premium) | 300 | 10,000 | 100,000 | | Scale (enterprise) | 1,000 | 50,000 | 1,000,000 | Rate limit headers on every response: - `X-RateLimit-Remaining` - `X-RateLimit-Reset` - `X-RateLimit-Limit` --- ## MCP Server Install: `npx -y @scanblitz/mcp-server` **18 tools available:** | Tool | Description | |------|-------------| | `register` | Register for an account (no API key needed) | | `verify_registration` | Complete registration with email code | | `create_qr_code` | Create a trackable QR code | | `list_qr_codes` | List with search, filter, pagination | | `get_qr_code` | Get QR code details by ID | | `update_qr_code` | Update destination, name, or status | | `delete_qr_code` | Delete a QR code | | `bulk_create_qr_codes` | Create up to 100 at once | | `get_qr_analytics` | Per-code scan analytics | | `get_analytics_overview` | Dashboard summary | | `get_analytics_geographic` | Geographic distribution | | `export_analytics` | Export as JSON or CSV | | `create_campaign` | Group QR codes into a campaign | | `list_campaigns` | List campaigns | | `get_campaign_analytics` | Campaign-level analytics | | `get_usage` | API usage and quota status | | `get_api_info` | Rate limits and permissions | --- ## Scan Data Collected Every QR code scan automatically captures: - Device type (mobile, desktop, tablet) - Browser name and version - Operating system name and version - Country, city, region, timezone - Referrer URL - UTM parameters (source, medium, campaign) - Session ID and returning visitor flag - Session duration - Language and connection type ## Response Format All responses follow this structure: ```json { "success": true, "data": { ... }, "meta": { "page": 1, "limit": 50, "total": 123, "totalPages": 3 }, "rateLimit": { "remaining": 58, "reset": 1715700000000, "limit": 60 } } ``` Error responses: ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Required field 'name' is missing" } } ```