OpenQR

Developers

Generating and re-pointing QR codes in Make.com

By Sam Moreton · updated 28 June 2026

Make (formerly Integromat) is a visual automation platform built around modules and scenarios. There's no dedicated OpenQR app in Make's catalogue — but the OpenQR API is plain HTTP with a Bearer header, which is exactly what Make's built-in HTTP modules speak. This guide builds a complete no-code scenario with them: mint a re-pointable dynamic QR code, render its image, re-point it later without a reprint, and pull scan analytics — module by module, with the exact configuration for each.

10 min read · Updated 28 June 2026

This is the Make path. If you use a different tool, OpenQR ships a dedicated node for n8n and integrates with Zapier; to call the API from your own backend instead, see getting started with the OpenQR API. Make just wraps those same endpoints in visual modules.

Why HTTP modules, not a dedicated app

Make's catalogue doesn't include an OpenQR app, but it doesn't need one: every OpenQR operation is a single HTTP request with an Authorization header and a JSON body. Make's "HTTP → Make a request" module handles JSON endpoints, and "HTTP → Get a file" handles the binary QR image. That covers the entire API.

Get an API key

Everything authenticates with one key. Create a free one at openqr.uk/api — sign in with a magic link, then mint a key (it starts with oqr_). It's shown once and stored only as a SHA-256 hash, so copy it when you see it.

Store the key in a Make connection or data store

An OpenQR key can create, edit and delete every dynamic code on your account. In Make, keep it in a reusable connection/keychain or a Data store — never paste it raw into each module where it ends up in scenario history. To rotate, mint a new key and update the one place it lives.

The building block: an authenticated HTTP request

Every JSON call in this scenario uses HTTP → Make a request configured the same way. Set it once and you can reproduce any endpoint:

FieldValue
MethodPOST / GET / PATCH / DELETE (per endpoint below)
HeadersAuthorization: Bearer oqr_yourkey · Content-Type: application/json
Body typeRaw
Content typeJSON (application/json)
Parse responseYes — so Make maps the JSON fields for downstream modules

Step 1: create a dynamic code

An HTTP module pointed at POST https://openqr.uk/v1/dynamic. The body is JSON with a public http(s) destination (private/internal hosts and oqr.to self-loops are rejected). With Parse response on, Make exposes id, slug, short_url and destination to later modules.

// POST https://openqr.uk/v1/dynamic  — request body
{
  "destination": "https://example.com/launch-soon",
  "label": "Summer poster"
}

// Parsed response Make hands you:
{
  "id": "b1c2…",
  "slug": "k7Pm2qR",
  "short_url": "https://oqr.to/k7Pm2qR",
  "destination": "https://example.com/launch-soon"
}

Persist id and short_url

Pipe the parsed output into a Data store, Google Sheets row or Airtable record. Store id (your handle for re-pointing and analytics) and short_url (the link you print). The printed QR encodes the short_url, so it never changes — id is what every later step needs.

Step 2: render the QR image

The image endpoint returns binary, not JSON, so use HTTP → Get a file against the GET /v1/qr endpoint with the short_url as the data query parameter. Add the same Authorization header. The module outputs a file you can attach to an email, upload to Drive, or send to a label printer.

# HTTP → Get a file
# URL (data = the short_url from step 1, size to taste):
https://openqr.uk/v1/qr?data=https://oqr.to/k7Pm2qR&format=png&size=1024
# Header: Authorization: Bearer oqr_yourkey

URL-encode the data value

Because data is itself a URL, wrap it with Make's encodeURL() function in the mapping so query characters don't break the request — encodeURL(short_url). For a static one-off code, put any text or URL in data and skip step 1 entirely.

Step 3: re-point the code later

The payoff of a dynamic code: a second scenario swaps the destination when the real page is live — no reprint. Use an HTTP module with PATCH https://openqr.uk/v1/dynamic/{id}, substituting the stored id, and a JSON body containing only what changes.

// PATCH https://openqr.uk/v1/dynamic/b1c2…
{ "destination": "https://example.com/launch-live" }

// 200 OK — every future scan now lands on the new URL; the printed code is untouched

Re-point on a schedule

Trigger the PATCH scenario from a scheduled run to flip destinations automatically — point a venue code at today's agenda each morning, or move a packing-slip code from order-tracking to a review request a few days after dispatch. Same physical code, different link over time.

Step 4: read scan analytics

An HTTP module on GET https://openqr.uk/v1/dynamic/{id}/scans?days=30 returns a scans summary plus a fuller analytics object with a zero-filled daily series and top country/device/referrer entries. A common pattern: a weekly scheduled scenario → Get Scans → format → post a digest to Slack or email.

{
  "scans": { "total": 1840, "last7": 263, "topCountry": "GB", "topDevice": "mobile" },
  "analytics": {
    "days_window": 30,
    "window_total": 612,
    "daily": [ { "day": "2026-06-22", "n": 31 }, … ],
    "by_country": [ { "value": "GB", "n": 421 }, … ],
    "by_referrer": [ { "value": "Direct", "n": 580 }, … ]
  }
}

No PII in the numbers

Each scan records a timestamp plus coarse country, device class and referrer host, derived from Cloudflare request headers at redirect time. No IPs, no fingerprints, no per-person identifiers. It tells you where and on what, not who.

Batch-creating codes from a list

Single-create is capped at 20 codes per hour per account (the API returns 429 over that). When a scenario needs many at once — one code per product, table or ticket — call POST https://openqr.uk/v1/dynamic/bulk with a body of { "codes": [ { destination, label }, … ] }, up to 200 per request. Build the array with an Iterator/Array aggregator from a Sheets or Data store source. For the deeper batching patterns see bulk QR code generation.

// POST https://openqr.uk/v1/dynamic/bulk
{
  "codes": [
    { "destination": "https://shop.example.com/p/1001", "label": "Mug" },
    { "destination": "https://shop.example.com/p/1002", "label": "T-shirt" }
  ]
}

Handling errors in a scenario

OpenQR returns standard HTTP status codes, which Make surfaces on the HTTP module so you can attach error handlers and routers:

  • 400 — bad body or a disallowed destination (private/internal host or an oqr.to self-loop). Fix the input.
  • 401 — missing/invalid key. Check the Authorization header.
  • 404 — code not found or not owned by your key (wrong id).
  • 409 — a custom slug you requested is already taken; try another.
  • 429 — creation rate limit hit; a Retry-After header tells you when to retry. Add a delay or break the work into smaller runs.

For the endpoint reference your HTTP modules target, the OpenAPI 3.1 spec is at https://openqr.uk/openapi.json — you can import it into tools that accept a spec. To drive the same operations from an AI agent instead of a scenario, see the OpenQR MCP server.

Get a free API keySign in with a magic link, mint a key, and wire up your first Make scenario with the HTTP module. The API and dynamic codes are free.
Not currently. But you don't need one — the OpenQR API is plain HTTP with a Bearer header, so Make's built-in HTTP modules cover the whole surface. Use "HTTP → Make a request" for the JSON endpoints (create, update, scans) and "HTTP → Get a file" for the binary QR image.

Related reading