Skip to content
API key

Getting started

Authentication and API keys

The REST API authenticates with an API key and nothing else. This page covers creating a key, sending it, limiting what it can do, and replacing it safely.

Authentication at a glance
QuestionAnswer
What authenticates a request?An API key. Not a dashboard session, not OAuth.
Which header?Authorization: Bearer YOUR_API_KEY, or X-API-Key: YOUR_API_KEY.
What does a key look like?qrb_live_ followed by 43 characters.
Where do I get one?Dashboard → Settings → Developer API
Can I see a key again later?No. It is shown once, when you create it.
Can a key be limited?Yes: by scope, by expiry, and to a single campaign.

Create an API key

  1. Open Settings → Developer API in the dashboard.
  2. Click New API key and name it after the system that will use it.
  3. Select the scopes it needs, and an expiry if you want one.
  4. Copy the key from the confirmation screen and store it in your secrets manager.

QRBold keeps only a SHA-256 hash of the key, so the full value exists only on that confirmation screen. If it is lost, create another and revoke the old one. The dashboard afterwards shows just the first characters and the last four, enough to tell keys apart.

How many keys an account may hold at once depends on its plan; see plans and access. Creating keys is limited to people who may manage API keys on the account.

Send the key

Add one header to every request:

Preferred
Authorization: Bearer YOUR_API_KEY

Some tools (Zapier, Make, n8n and similar) only let you set a header name and a value. For those, this is equivalent:

Alternative
X-API-Key: YOUR_API_KEY

If a request carries both headers, X-API-Key is the one that is read. A key in the query string or in the request body is ignored.

Keep the key out of your source code. The samples read it from the QRBOLD_API_KEY environment variable:

curl "https://api.qrbold.com/api/public/v1/me" \
  -H "Authorization: Bearer $QRBOLD_API_KEY"

Scopes

A scope is one permission. A key holds only the scopes you ticked when you created it, and an endpoint refuses a key that lacks its scope with 403 forbidden.

API key scopes
ScopeLets the key
cards:readList and retrieve digital business cards, their wallet links and campaigns.
cards:writeCreate, update and delete digital business cards, including through a campaign.
templates:readList and retrieve card templates.
qr:readList and retrieve QR codes and their images.
qr:writeCreate, update and delete QR codes.
analytics:readRead scan statistics.
cards:shareShare cards with other people. Used by the AI assistant tools only; no REST endpoint needs it.
cards:sendEmail a card to somebody. Used by the AI assistant tools only; no REST endpoint needs it.
  • Read is not implied by write. A key with only cards:write can create a card but cannot list cards. Tick both if you need both.
  • Scopes are fixed at creation. To change them, create a new key.
  • The QR image is the one shared permission. Either qr:read or cards:read can download an image, so a cards-only key can fetch the QR code for a card it just created.
  • GET /me needs no scope.
  • In the key dialog, the AI assistant preset selects every scope and the Read only preset selects only the read scopes.

Each endpoint’s required scope is listed in the API reference.

Plans and access

QRBold has two plan lines, one for QR codes and one for digital business cards. The REST API is included in the top plan of each. Either one is enough.

REST API access, key allowance and rate limit by plan
PlanLineREST APIActive keysRequests per minute, per key
FreeQR plansNot included130
LaunchQR plansNot included260
GrowthQR plansNot included360
ProQR plansIncluded10120
Free CardCard plansNot included130
TeamCard plansNot included360
BusinessCard plansIncluded10120
  • Every plan can create keys, because the same keys also connect AI assistants, which every plan includes. On a plan without REST access those keys work with assistants and answer 403 upgrade_required_api on REST.
  • The plan is checked on every request, not just when the key is made. If an account downgrades, its keys stop working on REST at once and start again if it upgrades.
  • When an account holds both lines, it gets the more generous of the two limits.

Campaign-scoped keys

A key can be restricted to one campaign. Such a key can create cards through that campaign’s endpoints and read that campaign, and nothing else: every account-wide endpoint answers 403 key_scoped_to_campaign.

It is the right key to hand to an outside vendor, such as an HR system integrator. They can create the cards they were hired to create and cannot list your account. You create one from the campaign’s API tab in the dashboard (Bulk → the group → API).

Rotate and revoke

Revoke

Click Revoke next to a key on the Developer API page. It stops working on the next request; there is no delay and no undo. A revoked key stays in the list as a record until you delete it.

Rotate without downtime

There is no “regenerate” button, on purpose. Rotation is create, switch, then revoke:

  1. Create a new key with the same scopes.
  2. Deploy it to your application.
  3. Watch Last used on the old key in the dashboard. It updates about once a minute.
  4. When the old key has gone quiet, revoke it.

Revoking first means your integration is down until the new key is deployed.

Expiry

A key created with an expiry stops working at that time and answers 401 invalid_api_key, the same as a revoked one. Put a reminder in your calendar a week before, and rotate.

If a key leaks

Revoke it immediately, then create a replacement. Because every key starts with qrb_live_, secret scanners in GitHub and similar tools can be given that one pattern to watch for.

What an authentication failure looks like

A missing, mistyped, revoked or expired key all answer the same way:

401 response
{
  "error": {
    "type": "authentication_error",
    "code": "invalid_api_key",
    "message": "Invalid API key"
  }
}

The response is deliberately identical for all four, so it does not confirm to a stranger which guesses were once real keys. When the header is absent altogether, the message names both accepted header forms.

A valid key without the needed scope answers 403 instead, and the message names the scope:

403 response
{
  "error": {
    "type": "permission_error",
    "code": "forbidden",
    "message": "This API key is missing the \"cards:write\" scope. Create a new key with that scope to call this endpoint."
  }
}

Two things that surprise people: a request with no key at all answers 401 even for a path that does not exist, so an anonymous caller cannot map the API; and a signed-in dashboard session does not authenticate REST requests, only a key does.

Next: core concepts and URLs.