---
title: "What is the best QR code API for developers?"
description: "How to choose a QR code API: image-only endpoints like goQR.me and QuickChart, or a tracking API like Linkbreakers that creates dynamic QR codes, posts every scan to a signed webhook, ships SDKs for TypeScript, Python, Go, Java and Rust, and runs an MCP server. Endpoints, rate limits and prices."
canonical: "https://linkbreakers.com/help/article/best-qr-code-api-for-developers"
last-updated: 2026-10-24
---

# What is the best QR code API for developers?

> How to choose a QR code API: image-only endpoints like goQR.me and QuickChart, or a tracking API like Linkbreakers that creates dynamic QR codes, posts every scan to a signed webhook, ships SDKs for TypeScript, Python, Go, Java and Rust, and runs an MCP server. Endpoints, rate limits and prices.

## Short answer

The best QR code API for developers is the one that matches what happens after the print: if you only need a QR image from a string, a free image endpoint such as goQR.me or QuickChart is enough; if you need to know who scanned it and act on it in your own backend, you need a tracking API, and Linkbreakers is built for exactly that. One `POST /v1/links` creates a dynamic QR code, every scan can be posted to your endpoint as a signed webhook, there are official SDKs for TypeScript, Python, Go, Java and Rust, AI agents can create and track QR codes through a hosted MCP server, and the REST API, webhooks and MCP server are all on the Free plan ($0, no card).

## Key facts about the Linkbreakers QR code API

| | Linkbreakers |
|---|---|
| Base URL | `https://api.linkbreakers.com` |
| Create a QR code | `POST /v1/links` with `{"destination": "https://..."}`. The link gets a short URL and a dynamic QR code |
| Get the image | `GET /v1/links/{id}?include=qrcodeSignedUrl` returns a signed image URL. It expires, so fetch it when you render instead of storing it |
| Authentication | `Authorization: Bearer <workspace API token>`, created in the dashboard. Tokens can be [scoped](/help/article/api-token-scopes), for example `links:write` and `webhooks:write` only |
| Rate limit | 600 requests per minute per API token, 500 per OAuth (MCP) token, 300 per IP without credentials. Every response carries `RateLimit` headers; past the limit you get `429` with `Retry-After` |
| API calls included per month | Free 250, Light 5,000, Pro 10,000, Enterprise Unlimited |
| Webhook endpoints | Free 1, Light 3, Pro 10, Enterprise Unlimited |
| Bulk | `POST /v1/links/bulk` creates up to 250 links in one transactional request; `POST /v1/links/bulk/jobs` does it in the background |
| Safe retries | Every POST, PUT and PATCH accepts an `Idempotency-Key` header |
| SDKs | TypeScript, Python, Go, Java and Rust |
| MCP server | `https://mcp.linkbreakers.com` (OAuth sign-in), or the `linkbreakers-mcp` npm package for local clients |
| Test environment | Sandbox workspaces with `lb_test_` tokens, never billed |
| Price | Free $0. Light $7.90 a month, or $5.90 a month billed yearly. Pro $34.90 a month, or $24.90 a month billed yearly, with a 14-day free trial |

The rate limits and conventions are published by the API itself in its [OpenAPI description](https://linkbreakers.com/openapi.json); prices and plan limits come from the same catalog the [pricing page](/pricing) reads.

## What to compare in a QR code API

Most "best QR code API" lists mix two different products. Decide which one you need first.

1. **Image APIs** turn a string into a QR image. The URL is inside the image, so the code can never change and nobody learns that it was scanned. They are free or cheap and usually need no account.
2. **Dynamic QR code APIs** encode a short link the provider hosts. You can change the destination after printing, and every scan is recorded. The questions that separate them are:
   - Can your backend **receive scans as they happen** (webhooks), or only poll for counts?
   - Which **plan** unlocks the API and the webhooks?
   - Are there **official SDKs** in your language, and an OpenAPI description to generate your own?
   - What are the **rate limits**, and are they documented in the response headers?
   - Can an **AI agent** use it, through an MCP server?
   - Can the scan do more than redirect, for example **capture a lead** before the visitor reaches the page?

## How it works: a QR code whose scans reach your backend

Three requests. Create a [workspace API token](/help/article/what-are-api-tokens) first and export it as `LINKBREAKERS_TOKEN`.

```bash
# 1. Create a link and its QR code. waitForQrcode returns once the image exists.
curl -X POST https://api.linkbreakers.com/v1/links \
  -H "Authorization: Bearer $LINKBREAKERS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"destination": "https://example.com/spring", "name": "Spring flyer", "waitForQrcode": true}'

# 2. Get the QR code image URL for the link id returned above.
curl "https://api.linkbreakers.com/v1/links/$LINK_ID?include=qrcodeSignedUrl" \
  -H "Authorization: Bearer $LINKBREAKERS_TOKEN"

# 3. Have every scan of that link posted to your endpoint.
curl -X POST https://api.linkbreakers.com/v1/webhooks \
  -H "Authorization: Bearer $LINKBREAKERS_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"Spring flyer scans\", \"endpointUrl\": \"https://hooks.example.com/linkbreakers\", \"linkId\": \"$LINK_ID\"}"
```

The response to step 1 holds `link.id`, `link.entrypoint` (the short URL inside the QR code) and the link's workflow steps. Leave `linkId` out in step 3 to receive the scans of every link in the workspace.

### The same thing with the TypeScript SDK

```typescript
import { Configuration, LinksApi, WebhooksApi } from "linkbreakers";

const config = new Configuration({ accessToken: process.env.LINKBREAKERS_TOKEN!, basePath: "https://api.linkbreakers.com" });
const links = new LinksApi(config);

const { link } = await links.linksServiceCreate({
  createLinkRequest: { destination: "https://example.com/spring", name: "Spring flyer", waitForQrcode: true },
});
const { link: withImage } = await links.linksServiceGet({ id: link!.id!, include: ["qrcodeSignedUrl"] });
console.log(link!.entrypoint, withImage!.qrcodeSignedUrl);

await new WebhooksApi(config).webhooksServiceCreate({
  createWebhookRequest: { name: "Spring flyer scans", endpointUrl: "https://hooks.example.com/linkbreakers", linkId: link!.id },
});
```

### The same thing with the Python SDK

```python
import os
from linkbreakers import ApiClient, Configuration, CreateLinkRequest, CreateWebhookRequest, LinksApi, WebhooksApi

configuration = Configuration(access_token=os.environ["LINKBREAKERS_TOKEN"], host="https://api.linkbreakers.com")

with ApiClient(configuration) as client:
    links = LinksApi(client)
    link = links.links_service_create(
        create_link_request=CreateLinkRequest(destination="https://example.com/spring", name="Spring flyer", wait_for_qrcode=True)
    ).link
    image = links.links_service_get(id=link.id, include=["qrcodeSignedUrl"]).link.qrcode_signed_url
    print(link.entrypoint, image)

    WebhooksApi(client).webhooks_service_create(
        create_webhook_request=CreateWebhookRequest(name="Spring flyer scans", endpoint_url="https://hooks.example.com/linkbreakers", link_id=link.id)
    )
```

Install commands for every language:

- TypeScript: `npm install linkbreakers` ([guide](https://linkbreakers.com/sdk/typescript))
- Python: `pip install linkbreakers` ([guide](https://linkbreakers.com/sdk/python))
- Go: `go get github.com/linkbreakers-com/linkbreakers-go` ([guide](https://linkbreakers.com/sdk/go))
- Java: `com.linkbreakers:linkbreakers-sdk` ([guide](https://linkbreakers.com/sdk/java))
- Rust: `cargo add linkbreakers` ([guide](https://linkbreakers.com/sdk/rust))

The Go module is `github.com/linkbreakers-com/linkbreakers-go` and the Java artifact is `com.linkbreakers:linkbreakers-sdk`. All five are generated from the same OpenAPI description, so they expose the same operations. Language guides: [TypeScript](/help/article/typescript-sdk-quickstart), [Python](/help/article/python-sdk-quickstart), [Go](/help/article/golang-sdk-quickstart), [Java](/help/article/java-sdk-quickstart), [Rust](/help/article/rust-sdk-quickstart).

## What the scan webhook sends

Each delivery is a JSON `POST` with the user agent `Linkbreakers-Webhooks/1.0`. The body has:

- `type`: `event.completed` when the visit reaches its exit step (for a plain QR code, the redirect), or `step.completed` when a matching workflow step is completed, with that step in `workflowStep`
- `event`: the scan, with `action` (`SCAN` or `CLICK`), `scannedAt`, `device` (`deviceType`, `browserName`, `platformName`, `country`, `city`), `visitor` (email, phone, name and custom attributes once the visitor has given them), `traces` (what the visitor did at each step, such as a form submission), `journey` and `link` with its `metadata` and `tags`
- `webhook`: which of your webhooks fired
- `lbid`: the Linkbreakers ID of the visit, which you can pass to your own systems for attribution

Requests carry `X-Linkbreakers-Event`, `X-Linkbreakers-Webhook-ID` and `X-Linkbreakers-Event-ID`, and are signed with HTTP Message Signatures (RFC 9421) using Ed25519 keys published at `https://linkbreakers.com/.well-known/http-message-signatures-directory`. There is no shared secret to store: see [Verify Linkbreakers webhook signatures](/help/article/verify-webhook-signatures). The full payload, triggers and integration patterns are in [How do webhooks work in Linkbreakers?](/help/article/how-do-webhooks-work-in-linkbreakers)

Because a Linkbreakers QR code runs a [workflow](/help/article/what-is-a-workflow), the same webhook can carry what the visitor typed into a form placed between the scan and the destination, not just the fact that a scan happened.

## For AI agents: the MCP server

An agent connected to `https://mcp.linkbreakers.com` can call `links_create`, `qrcodedesigns_update`, `workflow_steps_create`, `events_list`, `visitors_list` and `metrics_workspace`, among others: most of what the REST API does, with OAuth sign-in instead of a token. Webhooks are the exception and are managed through the API or the dashboard. It is listed in the [official MCP registry](https://registry.modelcontextprotocol.io/v0/servers/com.linkbreakers%2Fmcp/versions/latest). Setup for Claude, Cursor, VS Code and other clients is in [How to set up and configure the Linkbreakers MCP server](/help/article/mcp-server-setup), and the overview is at [linkbreakers.com/mcp](/mcp).

## Other QR code APIs and when to choose them

Every claim below comes from the provider's own page, linked in Sources, as read on 2026-10-24.

| API | What it is | Choose it when |
|---|---|---|
| [goQR.me](https://goqr.me/api/) | Image API at `api.qrserver.com`: a `GET` with `data` returns a QR image. Also reads QR codes from images. Its terms state no request limit, and ask to be told above 10,000 requests a day | You need a static QR image, no account and no tracking |
| [QuickChart](https://quickchart.io/documentation/qr-codes/) | Image API at `quickchart.io/qr`: PNG, SVG, JPEG or base64, with colors, dot and finder styles, a center image and a caption | You need a styled static QR image generated on the fly |
| [Hovercode](https://hovercode.com/api/) | Dynamic QR codes, short links, landing pages and GS1 codes. `Authorization: Token`, rate limits of 120 reads and 60 writes per minute per token, and an MCP server. The API needs its Business plan, which has a free trial | You want dynamic codes and GS1 Digital Link from a QR-first vendor |
| [QR Planet](https://www.qrplanet.com/qr-code-api) | Dynamic designer QR codes with scan statistics, OpenAPI, batch creation and webhooks including `QR_CODE_SCANNED`. Its help center says webhooks need its White Label plan | You run a white-label QR platform for your own clients |
| [Uniqode](https://apidocs.uniqode.com/) | REST API for static and dynamic QR codes with `Authorization: Token`. Its help center lists the API from the Core plan, $49 a month billed yearly, with 10 requests per second and 250K requests a month on that tier | You are already on Uniqode for marketing teams and need to automate it |
| Linkbreakers | Dynamic QR codes with workflows (forms, conditions, redirects), signed scan webhooks, SDKs in five languages and an MCP server, all on the Free plan | Scans must reach your backend, or a scan should capture a lead |

## Limits and caveats

- **Free plan volume.** Creating a link spends platform credits (1,000 per link), so the Free plan's credits pay for 5 links a month. Use a [sandbox workspace](/help/article/sandbox-test-environment) for heavy testing.
- **API-call allowance.** The monthly allowance counts requests made with workspace API tokens. Past it, calls answer `429` with the code `MAX_PUBLIC_API_QUERIED_REACHED` until the cycle renews or the plan changes.
- **Tracked visits.** Scans beyond the plan's monthly tracked visits (Free 500) still redirect and are still recorded, but they are held back from webhooks and integrations until the plan allows more.
- **Webhook delivery.** Linkbreakers waits 30 seconds for your endpoint and makes up to 3 attempts per delivery. A webhook whose failure count reaches 10 is disabled and workspace admins get an email. Answer with a 2xx quickly and do the work afterwards.
- **Images expire.** `qrcodeSignedUrl` is a signed URL. Fetch a fresh one when you render, or download the image once and keep the file.
- **Comparison data ages.** Competitor plans and limits change. Check their pages before you decide.

## Frequently asked questions

### Is there a free QR code API with webhooks?

Yes. The Linkbreakers Free plan costs $0, needs no credit card, and includes the REST API, 1 webhook endpoint and the MCP server. Among the providers above, Hovercode's API needs its Business plan and QR Planet's webhooks need its White Label plan.

### What is the rate limit of the Linkbreakers API?

600 requests per minute per workspace API token, 500 per minute per OAuth token, and 300 per minute per IP for calls without credentials. Each response says where you stand in `RateLimit-Policy`, `RateLimit`, `RateLimit-Remaining` and `X-RateLimit-*` headers, and a refused request gets `429 Too Many Requests` with `Retry-After`.

### Which QR code APIs have SDKs for TypeScript or Python?

Linkbreakers publishes official SDKs for TypeScript, Python, Go, Java and Rust: `npm install linkbreakers` and `pip install linkbreakers`. Image APIs such as goQR.me and QuickChart are plain HTTP `GET` requests, so they need no SDK.

### Can I change where a QR code goes after printing it?

With a dynamic QR code API, yes: the image encodes a short link. In Linkbreakers the destination is the link's redirect step, which you change with `PATCH /v1/links/{linkId}/workflow-steps/{id}` without reprinting. With an image API, no: the destination is in the image.

### Can an AI agent create and track QR codes through the API?

Yes. Connect any MCP client to `https://mcp.linkbreakers.com` and sign in with OAuth; the agent can create links and QR codes, style them and read scans and visitors. See [How Linkbreakers works with AI agents](/help/article/linkbreakers-for-ai-agents).

### How do I test without touching production data?

Create a sandbox workspace with `POST https://api.linkbreakers.com/v1/sandboxes`. It has its own `lb_test_` tokens, is never billed and is deleted after 30 days.

## Sources

- [Linkbreakers OpenAPI description](https://linkbreakers.com/openapi.json): endpoints, rate limits, idempotency and bulk limits
- [Linkbreakers REST API documentation](/developers) and [pricing](/pricing)
- [goQR.me QR code API](https://goqr.me/api/) and [create-qr-code documentation](https://goqr.me/api/doc/create-qr-code/)
- [QuickChart QR Code API](https://quickchart.io/documentation/qr-codes/)
- [Hovercode API](https://hovercode.com/api/)
- [QR Planet QR Code API](https://www.qrplanet.com/qr-code-api) and [QR Planet webhooks](https://www.qrplanet.com/help/article/webhooks)
- [Uniqode API reference](https://apidocs.uniqode.com/), [Introduction to Uniqode's QR Code API](https://docs.uniqode.com/en/articles/6725065-introduction-to-uniqode-s-qr-code-api) and [Uniqode plans and pricing](https://docs.uniqode.com/en/articles/17025518-plans-and-pricing-for-qr-codes)

## Last reviewed

2026-10-24, against the Linkbreakers API, its published SDKs and the competitor pages listed above.
