QR API

QR code generation as a simple API call

Encode structured data into scannable QR codes without image libraries or client-side rendering. Supports WiFi, vCard, URL, email, SMS, and geo presets with customisable size, colours, and error correction.

7 Preset Types

Encode WiFi credentials, vCard contacts, URLs, email compose links, SMS messages, geo coordinates, or arbitrary text — each preset handles the correct encoding format automatically.

Multiple Output Formats

Get your QR code as a PNG raster image, SVG vector, or inline base64 data URI. PNG and SVG are uploaded to S3 with a pre-signed download URL; base64 returns the image inline with no storage needed.

Custom Styling

Control image size (100–2000 px), foreground and background colours, quiet-zone margin, and error correction level (L/M/Q/H) on every request.

Pre-signed Download URLs

PNG and SVG images are stored on S3 and returned as pre-signed URLs with a configurable TTL (60 s to 30 days). No need to manage object storage yourself.

Use Cases

Built for real-world scenarios

Quick Start

Start using this API in seconds

Quick Start

# Generate a text QR code as a base64 data URI
$ curl -X POST https://api.apicrate.io/api/v1/qr/text \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello from ApiCrate!", "format": "base64"}'

# Response
{
  "status": "ok",
  "data": {
    "data_uri": "data:image/png;base64,iVBORw0KGgo...",
    "format": "base64",
    "preset": "text"
  },
  "error": null
}
import requests

response = requests.post(
    "https://api.apicrate.io/api/v1/qr/text",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"text": "Hello from ApiCrate!", "format": "base64"},
)

data = response.json()["data"]
print(data["data_uri"][:40])  # "data:image/png;base64,iVBORw0KGgo..."
const res = await fetch("https://api.apicrate.io/api/v1/qr/text", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ text: "Hello from ApiCrate!", format: "base64" }),
});

const { data } = await res.json();
// Use directly in an <img> tag: <img src={data.data_uri} />
console.log(data.preset);  // "text"

WiFi Network QR

# Generate a WiFi QR code as PNG (uploaded to S3)
$ curl -X POST https://api.apicrate.io/api/v1/qr/wifi \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ssid": "GuestNetwork",
    "password": "welcome2025",
    "encryption": "WPA",
    "format": "png"
  }'

# Response
{
  "status": "ok",
  "data": {
    "url": "https://s3.example.com/qr/abc123.png?X-Amz-...",
    "format": "png",
    "expires": 1744732800,
    "preset": "wifi"
  },
  "error": null
}
import requests

response = requests.post(
    "https://api.apicrate.io/api/v1/qr/wifi",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "ssid": "GuestNetwork",
        "password": "welcome2025",
        "encryption": "WPA",
        "format": "png",
        "ttl": 3600,  # URL valid for 1 hour
    },
)

data = response.json()["data"]
print(data["url"])      # Pre-signed S3 download URL
print(data["expires"])  # Unix timestamp when URL expires
const res = await fetch("https://api.apicrate.io/api/v1/qr/wifi", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    ssid: "GuestNetwork",
    password: "welcome2025",
    encryption: "WPA",
    format: "png",
    ttl: 3600,
  }),
});

const { data } = await res.json();
// Download the image from the pre-signed URL
console.log(data.url);      // "https://s3.example.com/qr/..."
console.log(data.expires);  // 1744732800

Contact Card (vCard)

# Generate a vCard QR with custom styling
$ curl -X POST https://api.apicrate.io/api/v1/qr/vcard \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "phone": "+1-555-0123",
    "email": "jane@example.com",
    "org": "Acme Inc",
    "url": "https://jane.dev",
    "format": "base64",
    "size": 600,
    "fg_color": "#1A1A2E",
    "bg_color": "#EAEAEA",
    "error_correction": "H"
  }'

# Response
{
  "status": "ok",
  "data": {
    "data_uri": "data:image/png;base64,iVBORw0KGgo...",
    "format": "base64",
    "preset": "vcard"
  },
  "error": null
}
import requests

response = requests.post(
    "https://api.apicrate.io/api/v1/qr/vcard",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "name": "Jane Smith",
        "phone": "+1-555-0123",
        "email": "jane@example.com",
        "org": "Acme Inc",
        "url": "https://jane.dev",
        "format": "base64",
        "size": 600,
        "fg_color": "#1A1A2E",
        "bg_color": "#EAEAEA",
        "error_correction": "H",
    },
)

data = response.json()["data"]
print(data["preset"])  # "vcard"
# Embed in HTML: <img src="{data['data_uri']}" alt="Contact QR" />
const res = await fetch("https://api.apicrate.io/api/v1/qr/vcard", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Jane Smith",
    phone: "+1-555-0123",
    email: "jane@example.com",
    org: "Acme Inc",
    url: "https://jane.dev",
    format: "base64",
    size: 600,
    fg_color: "#1A1A2E",
    bg_color: "#EAEAEA",
    error_correction: "H",
  }),
});

const { data } = await res.json();
// Render inline: document.querySelector("img").src = data.data_uri;
console.log(data.preset);  // "vcard"

URL as SVG

# Generate a URL QR code as SVG (vector — scales to any size)
$ curl -X POST https://api.apicrate.io/api/v1/qr/url \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://apicrate.io",
    "format": "svg",
    "margin": 2
  }'

# Response
{
  "status": "ok",
  "data": {
    "url": "https://s3.example.com/qr/def456.svg?X-Amz-...",
    "format": "svg",
    "expires": 1744819200,
    "preset": "url"
  },
  "error": null
}
import requests

response = requests.post(
    "https://api.apicrate.io/api/v1/qr/url",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://apicrate.io",
        "format": "svg",
        "margin": 2,
    },
)

data = response.json()["data"]
print(data["format"])  # "svg"
print(data["url"])     # Pre-signed URL to SVG file
const res = await fetch("https://api.apicrate.io/api/v1/qr/url", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://apicrate.io",
    format: "svg",
    margin: 2,
  }),
});

const { data } = await res.json();
console.log(data.format);  // "svg"
// Fetch the SVG and embed: <img src={data.url} />
Endpoints

Available endpoints

POST /api/v1/qr/text QR from text
POST /api/v1/qr/url QR from URL
POST /api/v1/qr/wifi QR from WiFi credentials
POST /api/v1/qr/vcard QR from vCard
POST /api/v1/qr/email QR from email
POST /api/v1/qr/sms QR from SMS
POST /api/v1/qr/geo QR from geo coordinates
FAQ

Frequently asked questions

What output formats are supported?

Three formats: png (raster image, default), svg (vector image), and base64 (inline PNG data URI). PNG and SVG are uploaded to S3 and returned as pre-signed download URLs. Base64 returns the image directly in the response body — no S3 required.

What is the maximum QR code size?

Image size ranges from 100 to 2,000 pixels (width = height) and applies to both PNG and base64 formats. The size parameter is ignored for SVG output since vectors scale to any resolution. The maximum text payload is 4,296 characters.

Do I need S3 for base64 format?

No. When you set format to base64, the QR image is encoded as a data URI and returned inline. No S3 upload or pre-signed URL is involved. This is useful for embedding QR codes directly in HTML or rendering them client-side.

What error correction levels are available?

Four levels following the QR standard: L (recovers ~7% of data), M (15%, default), Q (25%), and H (30%). Higher levels make the QR code more resilient to damage but increase its density. Use H if the code will be printed on physical media.

Can I customise colours for SVG output?

Currently, custom fg_color and bg_color are applied to PNG and base64 output. SVG output uses the default black-and-white palette. If you need custom colours, use PNG or base64 format.

Ready to start building?

Create a free account and start making requests in under a minute.

Sign Up Free → View Documentation