How to batch svg qr code generation: the runner and loop approach
- Step 1Pair a runner — Install and pair @jadapps/runner from /docs/runner. The runner listens on http://127.0.0.1:9789 and executes tools locally. This is the only place file content is processed — JAD's cloud endpoints never accept uploads.
- Step 2Fetch the live schema — Call GET /api/v1/tools/svg-qr-code with your API key to see the exact option contract (isGenerative, options, runnerMode: engine). Build your payloads against this rather than hardcoding assumptions.
- Step 3Prepare your data source — Make a CSV or JSON list with one row per code: an id (for the output filename) and the content to encode, e.g. id=PROD-001, content=https://example.com/p/001. The tool encodes content literally, so pre-format any structured payloads (WiFi/vCard) in this list.
- Step 4Loop over rows, one call each — For each row, POST to the runner endpoint http://127.0.0.1:9789/v1/tools/svg-qr-code/run with { qrData, qrEcc, qrSize, qrFg, qrBg }. There is no multi-row call — you iterate. Reuse the same colour/ECC/size across the batch for visual consistency.
- Step 5Write each SVG with your own naming — Save each returned SVG using the row's id, e.g. PROD-001.svg. The tool's own default filename is qr-code.svg; rename per row in your script so the batch is addressable.
- Step 6Spot-check then place into your pipeline — Scan a random sample with a real phone, then import the SVGs into InDesign/Illustrator or a print-on-demand service. SVG is directly importable and resolution-independent, so no DPI step is needed.
The real execution model
How a JAD API/MCP client actually runs this tool. There is no hosted batch service.
| Layer | Endpoint / behaviour | Notes |
|---|---|---|
| Cloud /run | POST /api/v1/tools/svg-qr-code/run | Upload-free; returns 400 with pairing instructions |
| Schema | GET /api/v1/tools/svg-qr-code | Returns options + runnerMode (engine) |
| Local runner | POST http://127.0.0.1:9789/v1/tools/svg-qr-code/run | Executes svg-engine.ts in-process locally |
| Batch | client-side loop, one call per item | No /qr/batch endpoint, no ZIP, no CSV upload |
Per-call payload options (the complete set)
These five keys are everything the engine reads. No includeLabel, no logoUrl, no font options — those are not implemented.
| Key | Type | Default | Range / values |
|---|---|---|---|
| qrData | string | https://jadapps.com | any text, encoded literally; empty is rejected |
| qrEcc | enum | M | L, M, Q, H |
| qrSize | number | 320 | clamped 64–1024 |
| qrFg | color | #000000 | solid hex |
| qrBg | color | #ffffff | solid hex |
What you must build yourself vs what the tool gives you
Setting expectations against the implementation so a batch job does not assume features that do not exist.
| Capability | Provided by tool? | Your responsibility |
|---|---|---|
| Per-row unique content | No iteration built in | Loop rows, one call each |
| Output filenames / ids | Default qr-code.svg only | Rename per row in your script |
| Caption / label text under code | Not supported | Add text in your layout/design step |
| Embedded logo | Not supported | Composite after, or use level H + overlay |
| ZIP packaging | Not produced | Zip the output files yourself |
| Scan tracking | Not in the code | Encode a redirect URL you log server-side |
Cookbook
Real automation patterns. The runner accepts the same five options on localhost; everything else is glue you write. Examples show the request shape and the loop, not a fictional batch API.
Inspect the schema before coding
Confirm the option contract and engine mode from the live endpoint.
GET /api/v1/tools/svg-qr-code
Authorization: Bearer <api_key>
→ { input: { isGenerative: true, options: [qrData, qrFg, qrBg, qrEcc, qrSize] },
execution: { runnerMode: "engine" }, minTier: "free" }One code via the local runner
The cloud /run is upload-free; the runner on localhost does the work.
POST http://127.0.0.1:9789/v1/tools/svg-qr-code/run
Content-Type: application/json
{ "qrData": "https://example.com/p/001",
"qrEcc": "Q", "qrSize": 512,
"qrFg": "#000000", "qrBg": "#ffffff" }
→ returns one SVG documentBatch from a CSV (loop, one call per row)
Pseudocode: there is no multi-row endpoint, so you iterate.
rows = readCsv("products.csv") # id, content
for r in rows:
svg = POST runner /svg-qr-code/run { qrData: r.content, qrEcc: "Q", qrSize: 512 }
write(`out/${r.id}.svg`, svg)
# package out/ into a zip yourself if you need one fileScannable tracking codes for a print run
Encode a redirect URL you control; log the scan server-side.
for r in rows:
url = `https://track.example.com/qr/${r.id}` # your server logs + redirects
svg = POST runner { qrData: url, qrEcc: "H", qrSize: 600 }
write(`out/${r.id}.svg`, svg)
# never encode personal data directly in the QRConsistent brand styling across the batch
Reuse the same colours/ECC for every item so the set looks uniform.
STYLE = { qrEcc: "M", qrSize: 480, qrFg: "#0b1f3a", qrBg: "#ffffff" }
for r in rows:
svg = POST runner /svg-qr-code/run { qrData: r.content, ...STYLE }
write(`labels/${r.id}.svg`, svg)Edge cases and what actually happens
POST content to the cloud /run endpoint
400JAD's cloud API never accepts uploads. /api/v1/tools/svg-qr-code/run returns 400 with pairing instructions and the runner endpoint. Send your payload to the paired local runner instead.
Looking for a /qr/batch endpoint
Not foundNo batch endpoint exists. Batching is a client-side loop calling the single-code runner endpoint once per row. There is also no ZIP response — package files yourself.
Setting includeLabel or logoUrl
IgnoredThese parameters are not implemented. The engine reads only qrData, qrFg, qrBg, qrEcc, qrSize. Add captions in your layout and composite logos after generation.
Empty qrData in a row
RejectedThe engine throws "QR data cannot be empty." for blank/whitespace content. Validate rows before the loop and skip or fix empties.
Rate limit hit during a large loop
429The cloud schema/run endpoints enforce your API key's per-hour rate limit and return 429 with a reset time. Throttle your loop or back off on 429; local runner execution itself is not metered per code.
Expecting parallel server-side processing
By designThere is no server-side batch worker. Concurrency is whatever your script does against the local runner. Engine mode is fast (no headless browser), so a simple sequential loop handles large sets.
All files named qr-code.svg
ExpectedThe tool's default filename is qr-code.svg. In a batch you must rename each output using your row id, or every file collides.
qrSize set beyond 64–1024
ClampedThe engine clamps qrSize to the 64–1024 range. Vector output rescales freely afterward, so clamping does not limit final print dimensions.
Encoding personal data for tracking
AvoidDo not put names, emails, or IDs that map to a person directly into the QR. Encode an opaque redirect URL and log the scan server-side, then redirect to the destination.
Frequently asked questions
Is there a hosted batch API for QR codes?
No. JAD's cloud /api/v1/tools/{slug}/run is upload-free and returns 400 with pairing instructions. Execution happens on your paired @jadapps/runner, and batching is a loop you write that calls the runner once per item.
Why does the cloud endpoint refuse my payload?
By design — JAD never receives file content. The /run endpoint hands back the runner endpoint (http://127.0.0.1:9789/v1/tools/svg-qr-code/run) and a link to install the runner. Send your request there.
How does the runner execute this tool?
In engine mode. Because svg-qr-code is server-safe, the runner imports svg-engine.ts and generates the SVG in-process — no headless browser. That makes high-volume loops fast and local.
What options can I send per code?
Exactly five: qrData (string), qrEcc (L/M/Q/H), qrSize (64–1024), qrFg (solid hex), qrBg (solid hex). includeLabel, logoUrl, font, and ZIP options do not exist.
What is the maximum batch size?
There is no per-batch limit because there is no batch endpoint — you loop. The only ceiling is your API key's per-hour rate limit on the schema/run calls, which returns 429 with a reset time when exceeded.
How do I add a label under each code?
The tool does not draw text. Add the caption in your layout or design step (InDesign/Illustrator), or programmatically wrap each SVG with your own <text> element after generation.
Can I embed the same logo in every code?
Not via a parameter. Generate at level H for redundancy headroom, then composite your logo over each SVG's centre in your own pipeline, keeping it under ~30% area and retesting a sample.
How do I name the output files?
The default filename is qr-code.svg, so in a batch you must rename each result with your row id (e.g. PROD-001.svg) in your script. Then zip the folder yourself if you want a single download.
How do I track scans across a print run?
Encode a redirect URL you own, like https://track.example.com/qr/{id}. Your server logs the scan (timestamp, user agent) and redirects to the real destination. Never put personal data directly in the QR.
How do I discover the exact contract programmatically?
GET /api/v1/tools/svg-qr-code returns the live input.options array, isGenerative, the engine runnerMode, and minTier. Build payloads against that response so you stay in sync with the implementation.
Is QR generation free at the API level?
The tool's minTier is free. The practical limiter is your API key's rate limit on cloud calls, not a feature gate. Runner-side execution is local.
Can I generate raster codes for the batch?
Not from this tool — it outputs SVG. If a print or web pipeline needs PNG, rasterise each SVG with /svg-tools/svg-canvas-exporter, or inline them with /svg-tools/svg-to-base64.
Privacy first
Every JAD SVG tool runs entirely in your browser using the DOM API and Canvas. Your SVG files never leave your device — verified by zero outbound network requests during processing.