Skip to content
tutorial

Generate QR codes with a REST API: one POST, instant SVG

| 5 min read
QR code displayed on a phone screen
Photo by Markus Winkler on Unsplash

Your e-commerce checkout needs to display a QR code for each order's tracking URL. You could install a client-side QR library, configure a canvas element, handle the rendering lifecycle, and add 30-40 KB to your bundle. Or you could send one POST request and get back an SVG.

The botoi /v1/qr/generate endpoint turns any string or URL into a scannable QR code. It returns raw SVG you can embed in HTML, save to a file, or stream to a PDF. No npm package, no canvas dependency, no build step.

The API call

Send a POST request with the text you want to encode:

curl -X POST https://api.botoi.com/v1/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "https://example.com/order/12345",
    "size": 300
  }'

The response is a raw SVG image (Content-Type: image/svg+xml):

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37 37"
  shape-rendering="crispEdges">
  <path fill="#ffffff" d="M0 0h37v37H0z"/>
  <path fill="#000000" d="M4 4h7v1H4z ... "/>
</svg>

That SVG renders sharp at any size because it's vector-based. Drop it into an <img> tag, inline it in your HTML, or pipe it to a file. No JSON parsing needed; the response body is the SVG itself.

QR code displayed on a smartphone screen
Photo by Markus Winkler on Unsplash

Parameters

The endpoint accepts six parameters. Only text is required:

  • text (string, required): The URL or text to encode. Supports up to ~4,296 alphanumeric characters.
  • size (number, default 300): Width and height in pixels. Range: 50 to 2000.
  • darkColor (hex string, default #000000): Foreground color of the QR modules.
  • lightColor (hex string, default #ffffff): Background color.
  • errorCorrectionLevel (string, default M): One of L (7%), M (15%), Q (25%), or H (30%). Higher levels tolerate more damage but produce denser codes.
  • margin (number, default 4): Quiet zone around the QR code in modules. Range: 0 to 20.

Here's a request using all six parameters:

curl -X POST https://api.botoi.com/v1/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "https://example.com/order/12345",
    "size": 400,
    "darkColor": "#1a1a2e",
    "lightColor": "#ffffff",
    "errorCorrectionLevel": "H",
    "margin": 2
  }'

Practical examples

Restaurant menu QR code

Print a QR code on table tents so diners can pull up the full menu on their phone. Error correction H handles scuffs and coffee stains.

curl -X POST https://api.botoi.com/v1/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "https://thecornergrille.com/menu",
    "size": 400,
    "errorCorrectionLevel": "H",
    "margin": 3
  }' --output menu-qr.svg

Event ticket QR code

Encode a unique ticket ID in each QR code. Staff scan it at the door with any smartphone camera. Error correction Q provides a good balance between density and damage tolerance for printed badges.

curl -X POST https://api.botoi.com/v1/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "https://tickets.devconf.io/check-in/TKT-8291-XKCD",
    "size": 250,
    "errorCorrectionLevel": "Q"
  }' --output ticket-8291.svg

Payment link QR code

Generate a scannable payment link for invoices, receipts, or point-of-sale displays. The customer scans it and lands on a Stripe checkout page.

curl -X POST https://api.botoi.com/v1/qr/generate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "https://pay.stripe.com/b/live_abc123def456",
    "size": 300,
    "errorCorrectionLevel": "M"
  }' --output payment-qr.svg

Batch generation in a loop

Need QR codes for a product catalog? Loop through a list of URLs and save each SVG to disk. This bash script generates four QR codes in under a second:

#!/bin/bash
set -euo pipefail

URLS=(
  "https://shop.example.com/product/wireless-earbuds"
  "https://shop.example.com/product/usb-c-hub"
  "https://shop.example.com/product/mechanical-keyboard"
  "https://shop.example.com/product/webcam-1080p"
)

mkdir -p qr-codes

for URL in "${URLS[@]}"; do
  SLUG=$(echo "$URL" | sed 's|.*/||')
  curl -s -X POST https://api.botoi.com/v1/qr/generate \
    -H "Content-Type: application/json" \
    -d "{
      \"text\": \"$URL\",
      \"size\": 400,
      \"errorCorrectionLevel\": \"M\"
    }" > "qr-codes/$SLUG.svg"

  echo "Generated: qr-codes/$SLUG.svg"
done

echo "Done. $(ls qr-codes/*.svg | wc -l) QR codes generated."

Output:

Generated: qr-codes/wireless-earbuds.svg
Generated: qr-codes/usb-c-hub.svg
Generated: qr-codes/mechanical-keyboard.svg
Generated: qr-codes/webcam-1080p.svg
Done. 4 QR codes generated.

Node.js example: QR codes for order tracking

This Express server exposes a /orders/:id/qr endpoint. When your checkout page or confirmation email template fetches this URL, it gets back an SVG QR code pointing to the order's tracking page.

import express from "express";

const app = express();
app.use(express.json());

app.get("/orders/:id/qr", async (req, res) => {
  const trackingUrl = `https://track.mystore.com/orders/${req.params.id}`;

  const qrResponse = await fetch("https://api.botoi.com/v1/qr/generate", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer YOUR_API_KEY",
    },
    body: JSON.stringify({
      text: trackingUrl,
      size: 300,
      errorCorrectionLevel: "M",
    }),
  });

  const svg = await qrResponse.text();
  res.setHeader("Content-Type", "image/svg+xml");
  res.setHeader("Cache-Control", "public, max-age=86400");
  res.send(svg);
});

app.listen(3000, () => console.log("Server running on port 3000"));

Usage:

# Returns an SVG QR code for order ORD-5482
curl http://localhost:3000/orders/ORD-5482/qr --output order-qr.svg

The endpoint sets a 24-hour cache header so repeat requests for the same order don't hit the API again. In production, add Redis or a CDN in front of this route for higher traffic.

Client-side QR libraries vs API: when to use which

Feature                  | QR code API                | Client-side library (qrcode.js)
─────────────────────────|────────────────────────────|────────────────────────────────
Setup                    | 0 dependencies             | npm install + bundler config
Bundle size impact       | 0 KB                       | 25-45 KB (gzipped)
Server-side rendering    | Yes (returns SVG string)    | No (needs DOM or canvas)
Custom colors            | darkColor / lightColor      | Varies by library
Error correction         | L, M, Q, H                 | Depends on library
Batch generation         | Shell script or server loop | Needs Node.js + canvas
Print-ready SVG          | Default output              | Extra config or library
Offline support          | No (needs network)          | Yes (runs in browser)
Latency                  | ~50-100ms network round trip| ~5ms local render

Use the API when you need server-side generation (emails, PDFs, receipts), when you want to keep your frontend bundle small, or when you're generating QR codes in a backend workflow like order processing or ticket issuance.

Use a client-side library when your app needs to work offline, when latency matters more than bundle size (sub-5ms renders), or when you're building a tool where users generate QR codes interactively in the browser and you don't want to depend on a network request for each keystroke.

Key points

- POST /v1/qr/generate returns an SVG QR code from any text or URL
- Six parameters: text, size, darkColor, lightColor, errorCorrectionLevel, margin
- Response is raw SVG (image/svg+xml), not JSON-wrapped; embed it directly in HTML
- Free tier: 5 requests per minute, no API key needed
- Use error correction level H when printing or overlaying logos
- The API also accepts GET requests with query parameters for quick browser testing

The free tier at 5 requests per minute covers development, prototyping, and low-volume production use. For batch generation or high-traffic apps, add your API key in the Authorization: Bearer header. Check the API docs for the full endpoint reference.

Frequently asked questions

Do I need an API key to generate QR codes?
No. The free tier allows anonymous access at 5 requests per minute with IP-based rate limiting. For production apps or batch generation, add an API key in the Authorization header to remove the rate limit.
Can I get a PNG instead of SVG?
Set the format parameter to "base64" to receive the QR code as a data URI you can embed in an img tag. The API returns SVG-based output in all cases because SVG is resolution-independent and renders sharp at any size. Convert to PNG client-side with a canvas element if you need a raster file.
What is the maximum data length for a QR code?
QR codes support up to about 4,296 alphanumeric characters or 2,953 bytes of binary data. Most URLs and short strings fall well within these limits. If you hit the ceiling, shorten your URL first using a link shortener.
Which error correction level should I use?
Use M (15% recovery) for digital screens and L (7%) when code density matters. Pick Q (25%) or H (30%) for printed materials that might get scuffed, folded, or partially covered by a logo overlay.
Can I customize the colors of the QR code?
Yes. Pass darkColor and lightColor as hex values (e.g., "#1a1a2e" and "#ffffff"). Make sure there is enough contrast between the two colors for scanners to read the code reliably.

Try this API

QR Code Generator API — interactive playground and code examples

More tutorial posts

Start building with botoi

150+ API endpoints for lookup, text processing, image generation, and developer utilities. Free tier, no credit card.