Public REST API

Build with QRNFC Global

Read your QR code data into your BI tools, sync scans into your CRM, automate campaign reporting. JSON over HTTPS, Bearer-authenticated, simple.

Auth

Bearer token

Format

JSON over HTTPS

Base URL

qrnfcglobal.com/api/v1

Quickstart

Generate a key at /account/api-keys, then verify it works:

curl https://qrnfcglobal.com/api/v1/me \
  -H "Authorization: Bearer qrnfc_live_YOUR_KEY_HERE"

Authentication

Every request must include an Authorization: Bearer ... header. Keys start with qrnfc_live_. Treat them like passwords.

  • Keys remain valid until you revoke them — there is no automatic expiry. Revoke them individually when no longer needed.
  • The full secret is shown once on creation.
  • Each key updates a last_used_at timestamp so you can spot stale keys.
  • If your plan downgrades below Enterprise, all keys stop working until you re-upgrade. Existing keys aren't deleted.

Endpoints

GET/api/v1/me

Authenticated user info

Returns the caller identity + plan summary. Use this to verify a key works after rotation.

Response

{
  "id": "69ecec758a1734fb962b798c",
  "email": "you@example.com",
  "name": "Acme Studios",
  "plan_tier": "business_enterprise",
  "credits": 0
}
GET/api/v1/tags

List your QR codes

Cursor-paginated list of QR codes you own. Filter by status; sort is created_at descending.

Query params

limit1–500. Default 50.
cursorcreated_at of the last item from the previous page.
statusactive | inactive | deleted

Response

{
  "data": [
    {
      "tag_code": "TPH5BLVH",
      "title": "Sarah & Michael's Wedding",
      "message": "Thank you for celebrating with us.",
      "template_id": "wedding",
      "status": "active",
      "scan_count": 187,
      "created_at": "2026-01-12T14:09:00Z",
      "last_scanned_at": "2026-04-26T09:32:01Z",
      "public_url": "https://qrnfcglobal.com/t/TPH5BLVH",
      "media": {
        "video_url": "/api/storage/videos/qrnfc/...",
        "thumbnail_url": "/api/storage/videos/qrnfc/...",
        "files": [{"url": "...", "filename": "wedding_photo.jpg", "size": 462794}]
      }
    }
  ],
  "next_cursor": "2026-01-12T14:09:00Z",
  "has_more": true
}
GET/api/v1/tags/{tag_code}

Get one QR code

Full details for a single tag you own. 404 if not found OR not owned by the caller.

Response

{
  "tag_code": "TPH5BLVH",
  "title": "...",
  "scan_count": 187,
  "media": {...}
  // same shape as items in /tags response
}
GET/api/v1/tags/{tag_code}/analytics

Tag analytics

Daily scan timeline + device + country breakdown for one tag.

Query params

daysWindow size, 1–365. Default 30.

Response

{
  "tag_code": "TPH5BLVH",
  "window_days": 30,
  "total_scans_in_window": 142,
  "lifetime_scans": 187,
  "scans_by_day": [
    {"date": "2026-04-01", "count": 4},
    {"date": "2026-04-02", "count": 7}
  ],
  "devices": [
    {"device_type": "mobile", "count": 121},
    {"device_type": "desktop", "count": 21}
  ],
  "top_countries": [
    {"country": "United Kingdom", "count": 95},
    {"country": "United States", "count": 28}
  ]
}

Errors

Standard HTTP status codes. Body is always JSON with a detail field.

401

Unauthorized

Missing, invalid or revoked token. Check your Authorization header.

403

Forbidden

Plan downgraded below Enterprise — re-upgrade to restore API access.

404

Not Found

The resource doesn't exist OR isn't owned by you. We don't distinguish these to prevent enumeration.

429

Too Many Requests

Rate limit exceeded. Back off + retry. Generous defaults; contact sales for higher limits.

500

Server Error

Something broke on our side. We're alerted automatically; retry.

Need write endpoints, higher limits, or a webhook receiver?

v1 is read-only by design. We add write endpoints when real customers ask for them. Tell us what you'd integrate with QRNFC and we'll fast-track it.