Developers

Paste QR API v1

Build products on Paste QR: create codes and landing pages, read scans, issue one-time links and get signed webhooks on every scan. Available on Pro. Spec: openapi.json.

Auth

Create a key in the dashboard (shown once). Send Authorization: Bearer sqr_…. Limit: 60 requests/minute per key (see X-RateLimit-* headers; 429 with Retry-After).

Errors are always {"error":{"code":"…","message":"…"}} with codes such as unauthorized, plan_required, rate_limited, not_found, invalid_data, plan_limit.

Endpoints

curl -X POST https://pasteqr.com/api/v1/codes \
  -H "Authorization: Bearer $SQR_KEY" -H "Content-Type: application/json" \
  -d '{"type":"page","template":"menu","title":"Cafe","data":{"business":"Cafe Swanky","items":[{"name":"Masala chai","price":"₹40"}]}}'

Types: url {payload:{url}}, whatsapp, upi, app {routing:{ios,android,web}}, page {template,data}. Optional settings: ends_at, max_scans (1 = one-time), require_token.

Scan webhooks (IoT / access)

Each scan POSTs JSON {id,type:"scan",created,data:{code_id,slug,country,device,os,token_used}} with headers X-SwankyQR-Timestamp and X-SwankyQR-Signature: v1=hex(HMAC_SHA256(secret, timestamp + "." + rawBody)). Reject if the timestamp is older than 5 minutes, and ignore repeated ids.

const ok = crypto.timingSafeEqual(
  Buffer.from(sig.replace("v1=", "")),
  Buffer.from(crypto.createHmac("sha256", secret).update(ts + "." + raw).digest("hex")))
  && Math.abs(Date.now()/1000 - Number(ts)) < 300;

Templates (28)