qr-api
REST API integration for qr-code-generator. TypeScript request helpers, batch pipeline patterns, and server-side code examples for embedding QR generation into other applications.
Best use case
qr-api is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
REST API integration for qr-code-generator. TypeScript request helpers, batch pipeline patterns, and server-side code examples for embedding QR generation into other applications.
Teams using qr-api should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/qr-api/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How qr-api Compares
| Feature / Agent | qr-api | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
REST API integration for qr-code-generator. TypeScript request helpers, batch pipeline patterns, and server-side code examples for embedding QR generation into other applications.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# qr-api Skill
## When to use
Use this skill when you need to call the qr-code-generator API from another service, script, or CI pipeline. This skill covers the TypeScript client, Node.js usage, and piping output.
## Prerequisites
qr-code-generator server running. The `QR_API_URL` environment variable should point to it (e.g., `http://localhost:3000`).
## TypeScript API client
```typescript
// lib/qr-client.ts
import { z } from 'zod';
const QR_API = process.env.QR_API_URL ?? 'http://localhost:3000';
export type QRType = 'url' | 'text' | 'wifi' | 'vcard';
export type ErrorCorrection = 'L' | 'M' | 'Q' | 'H';
export type QRFormat = 'svg' | 'png';
export interface QRStyle {
fgColor?: string;
bgColor?: string;
errorCorrection?: ErrorCorrection;
margin?: number;
width?: number;
}
export interface QRRequest {
type: QRType;
data: Record<string, string | boolean | number>;
style?: QRStyle;
logo?: string | null;
format?: QRFormat;
}
export interface QRResponse {
svg: string;
dataUrl: string;
size: number;
}
export async function generateQR(req: QRRequest): Promise<QRResponse> {
const res = await fetch(`${QR_API}/api/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(req),
});
if (!res.ok) {
const body = await res.text();
throw new Error(`QR generation failed ${res.status}: ${body}`);
}
return res.json() as Promise<QRResponse>;
}
```
## URL QR code
```typescript
import { generateQR } from './lib/qr-client.ts';
import { writeFile } from 'node:fs/promises';
const result = await generateQR({
type: 'url',
data: { url: 'https://example.com' },
style: { width: 512, errorCorrection: 'M' },
format: 'svg',
});
await writeFile('qrcode.svg', result.svg, 'utf8');
```
## WiFi QR code
```typescript
const result = await generateQR({
type: 'wifi',
data: {
ssid: 'OfficeNetwork',
password: 'supersecret',
security: 'WPA',
hidden: false,
},
format: 'svg',
});
```
## vCard QR code
```typescript
const result = await generateQR({
type: 'vcard',
data: {
firstName: 'Jane',
lastName: 'Smith',
org: 'Acme Corp',
title: 'Product Manager',
phone: '+1-555-0100',
email: 'jane@acme.com',
url: 'https://acme.com',
},
style: { errorCorrection: 'Q' },
format: 'svg',
});
```
## PNG output to buffer
```typescript
import { generateQR } from './lib/qr-client.ts';
import { writeFile } from 'node:fs/promises';
const result = await generateQR({
type: 'url',
data: { url: 'https://example.com' },
style: { width: 1024 },
format: 'png',
});
// result.dataUrl is "data:image/png;base64,..."
const base64 = result.dataUrl.split(',')[1];
const buffer = Buffer.from(base64, 'base64');
await writeFile('qrcode.png', buffer);
```
## Bulk generation from JSON
```typescript
import FormData from 'form-data';
import { createReadStream } from 'node:fs';
import { writeFile } from 'node:fs/promises';
const QR_API = process.env.QR_API_URL ?? 'http://localhost:3000';
async function bulkFromJSON(codes: Array<{ data: string; filename: string; fgColor?: string }>) {
const res = await fetch(`${QR_API}/api/bulk`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ codes, format: 'svg' }),
});
if (!res.ok) throw new Error(`Bulk failed: ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await writeFile('qrcodes.zip', buffer);
}
```
## Bulk generation from CSV file
```typescript
import { readFile, writeFile } from 'node:fs/promises';
async function bulkFromCSV(csvPath: string) {
const csvBuffer = await readFile(csvPath);
const form = new FormData();
form.append('csv', csvBuffer, { filename: 'codes.csv', contentType: 'text/csv' });
const res = await fetch(`${QR_API}/api/bulk`, {
method: 'POST',
headers: form.getHeaders(),
body: form.getBuffer(),
});
if (!res.ok) throw new Error(`Bulk failed: ${res.status}`);
await writeFile('qrcodes.zip', Buffer.from(await res.arrayBuffer()));
}
```
## Express middleware: generate QR on the fly
```typescript
import { Router } from 'express';
import { generateQR } from './lib/qr-client.ts';
const router = Router();
// GET /qr?url=https://example.com&format=svg
router.get('/qr', async (req, res) => {
const url = String(req.query.url ?? '');
const format = req.query.format === 'png' ? 'png' : 'svg';
if (!url.startsWith('http')) {
return res.status(400).json({ error: 'Invalid url parameter' });
}
const result = await generateQR({ type: 'url', data: { url }, format });
if (format === 'png') {
const base64 = result.dataUrl.split(',')[1];
res.setHeader('Content-Type', 'image/png');
return res.send(Buffer.from(base64, 'base64'));
}
res.setHeader('Content-Type', 'image/svg+xml');
res.send(result.svg);
});
export { router };
```
## CI pipeline: generate QR codes for releases
```bash
#!/usr/bin/env bash
# generate-release-qr.sh
set -euo pipefail
VERSION="${1:-latest}"
BASE_URL="https://releases.example.com/$VERSION"
QR_API="${QR_API_URL:-http://localhost:3000}"
for PLATFORM in linux macos windows; do
URL="$BASE_URL/download/$PLATFORM"
FILENAME="release-${VERSION}-${PLATFORM}"
curl -s -X POST "$QR_API/api/generate" \
-H 'Content-Type: application/json' \
-d "{\"type\":\"url\",\"data\":{\"url\":\"$URL\"},\"style\":{\"width\":512},\"format\":\"svg\"}" \
| jq -r '.svg' > "dist/qr/${FILENAME}.svg"
echo "Generated $FILENAME.svg"
done
```
## Environment variables
| Variable | Default | Description |
|---|---|---|
| QR_API_URL | http://localhost:3000 | Base URL for the qr-code-generator server |
## Error handling
```typescript
import { generateQR } from './lib/qr-client.ts';
async function safeGenerate(url: string) {
try {
const result = await generateQR({
type: 'url',
data: { url },
format: 'svg',
});
return result.svg;
} catch (err) {
if (err instanceof Error && err.message.includes('400')) {
console.error('Invalid request:', err.message);
} else if (err instanceof Error && err.message.includes('429')) {
console.error('Rate limited. Retry after 60 seconds.');
} else {
throw err;
}
return null;
}
}
```
## Rate limits
The server enforces `RATE_LIMIT_RPM` requests per minute per IP (default 60). For bulk jobs, the single `/api/bulk` call counts as one request regardless of how many codes are generated.Related Skills
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose
Skill: Pastebin Core
## Purpose