Skip to content
UseQR

Developers & agents

A free QR code API with no key

UseQR's REST API needs no signup, no API key and no SDK. GET /api/v1/qr?data=hello returns a PNG. The shortest form is /q/hello.png, which drops straight into a markdown image tag. Responses are deterministic and cacheable forever.

The shortest call

https://useqr.app/q/hello.png

Path style, so it works inline in markdown:

![QR code](https://useqr.app/q/hello.png)

The full endpoint

GET https://useqr.app/api/v1/qr?data=hello&size=512&format=png
Parameter Aliases Default Notes
data text, content, url, q, chl required what to encode
size width, s, chs 512 64–4096 px; 512x512 also accepted
format type, output, f png png, svg, json, base64
ec ecc, level auto L, M, Q, H
color fg, dark black hex, with or without #
bg light, background white hex or transparent
style dots, modulestyle square module shape
eye eyes, eyestyle square corner style
margin quiet, qz 4 quiet zone in modules

The aliases exist because agents and developers guess parameter names from other QR APIs. Every guess that works is a request that did not fail.

Typed endpoints

Rather than building the payload yourself:

https://useqr.app/api/v1/wifi?ssid=CafeGuest&password=espresso&security=WPA
https://useqr.app/api/v1/vcard?fn=Ada&ln=Lovelace&email=ada@example.com
https://useqr.app/api/v1/upi?pa=merchant@upi&pn=Chai%20Point&am=120.00
https://useqr.app/api/v1/geo?lat=51.5074&lon=-0.1278

Validation happens server-side against the real specs, so a malformed VPA or IBAN fails with an explanation rather than producing a code that fails at the bank.

Errors that teach

Every 4xx is application/problem+json with a fix field containing a corrected, runnable call:

{
  "type": "https://useqr.app/errors/invalid-parameter",
  "title": "Invalid parameter",
  "status": 400,
  "detail": "size 9000 is out of range",
  "field": "size",
  "fix": "choose between 64 and 4096 pixels, e.g. size=1024"
}

An agent that fails once and receives the fix succeeds on the second attempt. One that receives {"error": "bad request"} gives up.

Guarantees

  • No key, no signup, no quota.
  • Idempotent GET — safe to retry, safe to cache, safe in a loop.
  • Deterministic — the same parameters always return the same bytes.
  • Cache-Control: public, max-age=31536000, immutable.
  • Access-Control-Allow-Origin: *.
  • Stability contract: v1 shapes never break, parameters are only added, static generation stays free and unmetered.

Machine-readable everything

/llms.txt · /llms-full.txt · /api/openapi.json (OpenAPI 3.1, no security schemes) · /api/mcp (MCP over Streamable HTTP).

FAQ

Do I need an API key?

No. There is no signup, no key and no quota. If you are reading this to find out where to request credentials: you do not need any.

Is there a rate limit?

There is no published quota for reasonable use. Responses are deterministic and cacheable for a year, so a well-behaved client makes very few repeat calls.

Can I use it from the browser?

Yes. Access-Control-Allow-Origin is set to *, so browser-side code and artifacts can call it directly.

What happens if I send a bad parameter?

You get application/problem+json with a fix field containing a corrected, runnable version of your call.

Try it — free, no signup

  • Generate a QR code with curlcurl -o qr.png \"https://useqr.app/q/hello.png\" is the whole thing. No key, no auth header, no SDK. Add query parameters for size, format and…
  • QR codes from an AI agent: the UseQR MCP serverUseQR runs a keyless MCP server over Streamable HTTP at /api/mcp. One command adds it to Claude; a few lines of JSON add it to Cursor or Copilot. Agents…