API Documentation
Generate EMVCo-compliant Singapore PayNow QR codes via REST API.
Only need a few codes? Use the free PayNow QR generator or create them in bulk with Excel to PayNow QR.
Quick Start
1. Create a free account and generate an API key from the dashboard.
2. Include your key in the X-API-Key header.
curl -X POST https://developers.sgpaynowqr.com/api/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: sgpn_your_key_here" \
-d '{
"payment_type": "uen",
"uen": "201234567A",
"merchant_name": "My Company",
"amount": 25.00
}'Or use the TypeScript SDK:
npm install @alexhalfborg/sgpaynowqr
import { createClient } from "@alexhalfborg/sgpaynowqr";
const client = createClient("sgpn_your_key_here");
const { data } = await client.generate({
payment_type: "uen",
uen: "201234567A",
merchant_name: "My Company",
amount: 25.00,
});Or let your AI assistant call it. Connect our MCP server to Claude, ChatGPT, Cursor or VS Code:
claude mcp add --transport http sgpaynowqr https://developers.sgpaynowqr.com/api/mcp --header "X-API-Key: sgpn_your_key_here"
Plans and Rate Limits
| Plan | Price | Limit per billing period |
|---|---|---|
| Free | S$0, no card needed | 50 codes, then requests stop until the next period |
| Pay as you go | S$5 for the first 200 codes; 0.7¢ per code from 201 to 2,000; 0.35¢ per code from 2,001 to 10,000; 0.25¢ per code above 10,000 | Up to your maximum monthly bill: S$50 by default (11,760 codes), settable from S$10 (914) to S$500 (191,760) |
Guides
- Choosing a Payment Type: UEN vs Mobile vs VPA — When to use UEN, mobile number, or VPA when generating a Singapore PayNow QR code, with a complete request example for each.
- Handling Errors and Rate Limits — Every SGPayNowQR error code, recommended retry/backoff handling, and how to read the X-RateLimit-* response headers.
- TypeScript SDK Quickstart — Install the @alexhalfborg/sgpaynowqr SDK and generate your first PayNow QR code end to end with createClient.
- Connect SGPayNowQR to Claude, ChatGPT, Cursor & VS Code (MCP) — Step-by-step setup for Claude Code, Claude, ChatGPT, Cursor, VS Code, Windsurf, Codex and Gemini CLI, so your AI assistant can generate PayNow QR codes with the generate_qr tool.
- Generate PayNow QR Codes in n8n — Use the SGPayNowQR community node, the HTTP Request node, or the MCP Client Tool to generate Singapore PayNow QR codes in n8n workflows and AI agents.
API Reference
Authentication
All requests (except /health) require an API key in the X-API-Key header.
X-API-Key: sgpn_<32 hex characters>Base URL: https://developers.sgpaynowqr.com/api/v1
Get a free API key at developers.sgpaynowqr.com/register
/generateGenerate an EMVCo-compliant PayNow QR code for Singapore payments. Supports UEN, mobile number, and VPA payment types.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| payment_type | string | Required | Type of PayNow paymentValues: uen, mobile, vpa |
| uen | string | Conditional | UEN number (required if payment_type is "uen")Max length: 25 |
| merchant_name | string | Conditional | Merchant name (required if payment_type is "uen")Max length: 25 |
| mobile_number | string | Conditional | Singapore mobile number (required if payment_type is "mobile")Pattern: ^(\+65)?[89]\d{7}$ |
| vpa | string | Conditional | Virtual Payment Address (required if payment_type is "vpa") |
| amount | number | Required | Payment amount in SGDMin: 0.01 · Max: 999999.99 |
| reference | string | Optional | Optional alphanumeric referenceMax length: 25 · Pattern: ^[a-zA-Z0-9]*$ |
| expiry | string | Optional | QR code expiry durationValues: 1h, 2h, 6h, 12h, 24h, none · Default: 24h |
| qr_color | string | Optional | QR code color as 6-digit hex (without #)Pattern: ^[0-9a-fA-F]{6}$ · Default: 7d1979 |
| qr_size | integer | Optional | QR code image size in pixelsValues: 200, 300, 400 · Default: 300 |
| include_image | boolean | Optional | Whether to include base64-encoded PNG image in responseDefault: true |
Conditional Requirements
uen— UEN number (required if payment_type is "uen")merchant_name— Merchant name (required if payment_type is "uen")mobile_number— Singapore mobile number (required if payment_type is "mobile")vpa— Virtual Payment Address (required if payment_type is "vpa")
Examples
UEN payment
curl -X POST https://developers.sgpaynowqr.com/api/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: sgpn_your_key_here" \
-d '{
"payment_type": "uen",
"uen": "201234567A",
"merchant_name": "My Company",
"amount": 25,
"reference": "INV001"
}'Mobile payment
curl -X POST https://developers.sgpaynowqr.com/api/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: sgpn_your_key_here" \
-d '{
"payment_type": "mobile",
"mobile_number": "+6591234567",
"amount": 10.5
}'VPA payment
curl -X POST https://developers.sgpaynowqr.com/api/v1/generate \
-H "Content-Type: application/json" \
-H "X-API-Key: sgpn_your_key_here" \
-d '{
"payment_type": "vpa",
"vpa": "+6591234567#OCBC",
"amount": 5,
"reference": "DONATION"
}'Success Response
Response Headers
| Header | Type | Description |
|---|---|---|
| X-RateLimit-Limit | integer | Request limit for this account's billing period (shared across all its API keys). On pay as you go, the codes its maximum monthly bill covers |
| X-RateLimit-Remaining | integer | Remaining requests this billing period |
| X-RateLimit-Reset | string | When the quota resets (end of the account's billing period, Singapore time) |
| X-Request-Id | string | Unique request identifier |
Error Codes
| HTTP | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Missing required fields for the selected payment_type |
| 400 | INVALID_JSON | Malformed JSON body |
| 401 | UNAUTHORIZED | Invalid API key |
| 429 | RATE_LIMIT_EXCEEDED | Quota used up: 50 of 50 requests on the "free" tier this billing period. Resets 2026-11-12T00:00:00+08:00. Upgrade to pay as you go at https://developers.sgpaynowqr.com/billing. |
| 500 | — | Internal server error |
/healthNo auth requiredReturns API health status. No authentication required.
Success Response
/usageReturns the tier and quota usage for the account that owns the API key. Does not count toward the monthly quota, so it is safe to call to check that a key is valid.
Success Response
Error Codes
| HTTP | Code | Description |
|---|---|---|
| 401 | — | Missing or invalid API key |
CORS
All endpoints return CORS headers allowing cross-origin requests:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: POST, GET, OPTIONS Access-Control-Allow-Headers: Content-Type, X-API-Key, Accept Access-Control-Max-Age: 86400
Machine-readable specs: OpenAPI YAML · OpenAPI JSON · LLM Reference
API Playground
Use the interactive explorer below to test API requests directly.
Loading API reference...