Business plan

QRForever API

A REST API to create, manage, and track dynamic QR codes from your own apps and scripts. It mirrors what the dashboard does, so anything you can build by hand you can automate. API access is included with the Business plan. Generate a key from your dashboard.

Base URL

https://api.qrforever.com/api/v1

Auth

API key in a request header

Format

JSON requests and responses

Authentication

Every request must include your API key, either as a bearer token or in theX-API-Key header. Both forms are accepted.

Authorization: Bearer YOUR_API_KEY
# or, equivalently:
X-API-Key: YOUR_API_KEY
  • Keys look like qrf_live_... in production and qrf_test_... in development.
  • The full key is shown only once, at creation. Store it somewhere safe. If you lose it, rotate to issue a new one.
  • A key grants full access to your account, so keep it server-side. Never ship it in client code, mobile apps, or a public repo.
  • Rotating or revoking a key in your dashboard takes effect immediately.
Generate an API key

Rate limits

Requests are limited to 120 requests per minute per API key. The limit is tied to your key rather than your IP, so it follows you across servers. StandardRateLimit-* headers are returned on every response, showing your remaining budget and reset time.

When you exceed the limit you get a 429 with code API_RATE_LIMIT. Back off and retry after the window resets.

Quickstart

cURL

curl https://api.qrforever.com/api/v1/qr \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"qrType":"url","destinationUrl":"https://example.com"}'

JavaScript (fetch)

const res = await fetch("https://api.qrforever.com/api/v1/qr", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    qrType: "url",
    destinationUrl: "https://example.com",
    name: "Spring promo",
  }),
});

const json = await res.json();
console.log(json.data.shortUrl); // https://qrforever.com/qr/ab12cd

Endpoints

GET/meReturn the authenticated account. Use it to verify a key.
GET/qrList your QR codes with pagination, search, tag, and sort filters.
POST/qrCreate a QR code.
GET/qr/:shortIdFetch a single QR code by its short ID.
PUT/qr/:shortIdUpdate a QR code (destination, name, tags, active state, styling).
DELETE/qr/:shortIdDelete a QR code.
GET/qr/:shortId/analyticsScan totals for a QR code.

All paths are relative to the base URL. Successful responses use the envelope { success: true, message, data }.

Reference

GEThttps://api.qrforever.com/api/v1/me

Returns the account that owns the key. Useful as a connectivity and key-validity check.

Example response

{
  "success": true,
  "message": "Success",
  "data": {
    "id": "665f1a2b9c4e7d0012ab34cd",
    "name": "Jane Doe",
    "email": "[email protected]",
    "plan": "Business"
  }
}
GEThttps://api.qrforever.com/api/v1/qr

Lists your QR codes, newest first by default. Large media fields are omitted from list items for speed; fetch a single QR for the full record.

Query parameters

pagenumberPage number, starting at 1. Default 1.
limitnumberItems per page, 1 to 100. Default 20.
searchstringCase-insensitive match on name or destination URL.
tagsstringComma-separated tag list; returns QRs with any of these tags.
sortstringOne of name_asc, name_desc, scans_asc, scans_desc, date_asc, date_desc.

Example response

{
  "success": true,
  "message": "QR codes retrieved successfully",
  "data": {
    "qrCodes": [
      {
        "_id": "665f1a2b9c4e7d0012ab34cd",
        "shortId": "ab12cd",
        "qrType": "url",
        "destinationUrl": "https://example.com",
        "name": "Landing page",
        "tags": ["campaign"],
        "isActive": true,
        "scanCount": 42,
        "lastScanned": "2026-06-20T09:15:00.000Z",
        "shortUrl": "https://qrforever.com/qr/ab12cd",
        "createdAt": "2026-06-01T12:00:00.000Z"
      }
    ],
    "pagination": { "total": 1, "page": 1, "pages": 1, "limit": 20 }
  }
}
POSThttps://api.qrforever.com/api/v1/qr

Creates a permanent dynamic QR code. The example below creates a URL QR. Other types are supported (vCard, WhatsApp, menu, and more) by sending their type-specific data object; see your dashboard for the exact fields per type.

Body fields

qrTypestringQR type. Defaults to "url" if omitted.
destinationUrlstringRequired for url type. Must start with http:// or https://.
namestringOptional label for the QR.
tagsstring[]Optional tags for organizing and filtering.

Example request body

{
  "qrType": "url",
  "destinationUrl": "https://example.com",
  "name": "Spring promo",
  "tags": ["campaign", "spring"]
}

Example response

{
  "success": true,
  "message": "QR code created successfully",
  "data": {
    "id": "665f1a2b9c4e7d0012ab34cd",
    "shortId": "ab12cd",
    "qrType": "url",
    "destinationUrl": "https://example.com",
    "shortUrl": "https://qrforever.com/qr/ab12cd",
    "qrCodeImage": "data:image/png;base64,iVBORw0KGgoAAA...",
    "scanCount": 0,
    "isActive": true,
    "name": "Spring promo",
    "tags": ["campaign", "spring"],
    "createdAt": "2026-06-28T12:00:00.000Z"
  }
}
GEThttps://api.qrforever.com/api/v1/qr/:shortId

Fetches the full record for one QR code, including its rendered image as a base64 data URL.

Path parameters

shortIdstringThe short ID of the QR code (the part after /qr/ in its short URL).

Example response

{
  "success": true,
  "message": "QR code details retrieved",
  "data": {
    "qr": {
      "_id": "665f1a2b9c4e7d0012ab34cd",
      "shortId": "ab12cd",
      "qrType": "url",
      "destinationUrl": "https://example.com",
      "shortUrl": "https://qrforever.com/qr/ab12cd",
      "qrCodeImage": "data:image/png;base64,iVBORw0KGgoAAA...",
      "scanCount": 42,
      "lastScanned": "2026-06-20T09:15:00.000Z",
      "isActive": true,
      "name": "Landing page",
      "tags": ["campaign"],
      "createdAt": "2026-06-01T12:00:00.000Z",
      "updatedAt": "2026-06-20T09:15:00.000Z"
    }
  }
}
PUThttps://api.qrforever.com/api/v1/qr/:shortId

Updates an existing QR code. Send only the fields you want to change. For a url QR you can change its destination at any time without reprinting the code.

Body fields (all optional)

destinationUrlstringNew destination for url QRs. Must be a valid http(s) URL.
namestringNew label.
tagsstring[]Replacement tag list.
isActivebooleanPause (false) or resume (true) the QR.

Example request body

{
  "destinationUrl": "https://example.com/new",
  "name": "Updated name",
  "isActive": true
}

Example response

{
  "success": true,
  "message": "QR code updated successfully",
  "data": {
    "qr": {
      "id": "665f1a2b9c4e7d0012ab34cd",
      "shortId": "ab12cd",
      "qrType": "url",
      "destinationUrl": "https://example.com/new",
      "shortUrl": "https://qrforever.com/qr/ab12cd",
      "scanCount": 42,
      "lastScanned": "2026-06-20T09:15:00.000Z",
      "isActive": true,
      "name": "Updated name",
      "tags": ["campaign"],
      "createdAt": "2026-06-01T12:00:00.000Z"
    }
  }
}
DELETEhttps://api.qrforever.com/api/v1/qr/:shortId

Deletes a QR code. After deletion the short URL stops resolving.

Path parameters

shortIdstringThe short ID of the QR code to delete.

Example response

{
  "success": true,
  "message": "QR code deleted successfully"
}
GEThttps://api.qrforever.com/api/v1/qr/:shortId/analytics

Returns scan totals for one QR code. Analytics require an active paid subscription on the account.

Path parameters

shortIdstringThe short ID of the QR code.

Example response

{
  "success": true,
  "message": "QR code analytics retrieved",
  "data": {
    "analytics": {
      "shortId": "ab12cd",
      "totalScans": 42,
      "lastScanned": "2026-06-20T09:15:00.000Z",
      "createdAt": "2026-06-01T12:00:00.000Z",
      "isActive": true
    }
  }
}

Errors

Errors use the envelope below. Authentication and rate-limit errors also include a stable code field you can switch on.

{
  "success": false,
  "code": "API_KEY_INVALID",
  "message": "Invalid API key."
}
400Bad request. A required field is missing or invalid (for example an invalid destination URL).
401 API_KEY_MISSINGNo key. No key was sent in the Authorization or X-API-Key header.
401 API_KEY_INVALIDInvalid key. The key is wrong, or it was rotated/revoked.
403 API_NOT_IN_PLANOff plan. The account is no longer on a plan that includes API access.
403Limit reached. The account has hit its QR limit. Free up a slot or upgrade.
404Not found. No QR code matches that short ID under your account.
429 API_RATE_LIMITRate limited. Per-key rate limit exceeded. Back off and retry.
500Server error. Something went wrong on our side. Retry with backoff.

Ready to build?

Generate your API key, or upgrade to Business to unlock API access.