Enqre

QR code API

Create codes from your own backend, read their scans, and receive a webhook the moment somebody scans one. This page needs no account.

The API is part of the Business plan. Keys are created in the dashboard under API & webhooks, and are shown once — a lost key is revoked and replaced, never recovered.

Base URL

https://enqre.com/api/v1

Authentication

Every request carries the key as a bearer token. A request without a valid key gets 401; a valid key on a plan without the API gets 403.

curl https://enqre.com/api/v1/qrcodes \
  -H "Authorization: Bearer $ENQRE_API_KEY"

Endpoints

GET/api/v1/qrcodes?limit=50&cursor=<id>

List your codes, newest first. Cursor pagination: pass the returned nextCursor to get the next page.

{
  "data": [
    {
      "id": "clx…", "name": "Table tent", "type": "URL",
      "slug": "a1b2c3", "destinationUrl": "https://example.com/menu",
      "scanCount": 128, "active": true, "createdAt": "2026-09-01T10:00:00.000Z",
      "shortUrl": "https://enqre.com/r/a1b2c3"
    }
  ],
  "nextCursor": "clx…"
}

POST/api/v1/qrcodes

Create a dynamic URL code. The response carries the short URL to print.

{ "name": "Table tent", "url": "https://example.com/menu" }
201 Created
{
  "data": {
    "id": "clx…", "name": "Table tent", "slug": "a1b2c3",
    "destinationUrl": "https://example.com/menu",
    "shortUrl": "https://enqre.com/r/a1b2c3"
  }
}

GET/api/v1/qrcodes/{id}

Read one code.

PATCH/api/v1/qrcodes/{id}

Change a code — including its destination. This is the whole point of a dynamic code: the printed copy keeps working and starts pointing somewhere else.

{ "url": "https://example.com/autumn-menu", "name": "Autumn menu", "active": true }

DELETE/api/v1/qrcodes/{id}

Delete a code. Printed copies stop resolving, so this is not the way to pause a campaign — set active to false instead.

GET/api/v1/qrcodes/{id}/scans

The last 1,000 scans of one code, newest first, plus the lifetime total.

{
  "total": 128,
  "data": [
    { "createdAt": "2026-09-06T18:12:03.000Z", "device": "mobile", "os": "iOS", "browser": "Safari" }
  ]
}

Errors

Errors are JSON with a stable machine-readable code. Branch on the code, not on the message — messages may be reworded, codes will not.

401invalid_api_keyNo key, a revoked key, or one that does not exist.
403api_not_available_on_planThe key is valid; the account is not on Business.
400invalid_bodyThe JSON body failed validation.
402plan_limit_reachedThe account is at its dynamic-code limit.
404not_foundNo code with that id on this account.
429rate_limitedMore than 60 writes in a minute.

Rate limit

60 writes per minute per account, answered with 429 when exceeded. Reads are not limited today; that is not a promise to build on.

Webhooks

Register a URL under API & webhooks and every scan is posted to it as it happens, so your own system hears about a scan without polling for it.

POST your-endpoint
X-Enqre-Event: scan.created
X-Enqre-Signature: <hex hmac-sha256 of the raw body>
Content-Type: application/json

{
  "event": "scan.created",
  "qrCodeId": "clx…",
  "slug": "a1b2c3",
  "name": "Table tent",
  "device": "mobile",
  "os": "iOS",
  "browser": "Safari"
}

Verify the signature

Compute HMAC-SHA256 of the raw request body with your webhook secret and compare it to the header. Reject anything that does not match — and compare in constant time.

import crypto from "node:crypto";

const raw = await req.text(); // the raw body, before JSON.parse
const expected = crypto
  .createHmac("sha256", process.env.ENQRE_WEBHOOK_SECRET)
  .update(raw)
  .digest("hex");

const given = req.headers.get("x-enqre-signature") ?? "";
const ok =
  given.length === expected.length &&
  crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));

Postman collection

Every endpoint on this page, ready to run: import the collection, set the apiKey variable, send.

Download the collection

What the API does not do yet

Codes created through the API are URL codes with the default design. The other sixteen types, the design fields and bulk import are dashboard-only for now. Everything the API does create is a normal code: editable, measurable and printable like any other.

Get a key

The API, webhooks, GS1 Digital Link, white-label and your own domain are on Business, €39 a month.

See the plans