API Documentation
Generate EMVCo-compliant Singapore PayNow QR codes via REST API.
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"
Rate Limits
| Tier | Monthly Limit |
|---|---|
| Free | 50 |
| Starter | 200 |
| Pro | 2,000 |
| Enterprise | 10,000 |
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 | Monthly request limit for this account (shared across all its API keys) |
| X-RateLimit-Remaining | integer | Remaining requests this month |
| X-RateLimit-Reset | string | When the rate limit resets (1st of next month, SGT) |
| 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 | Monthly usage limit exceeded |
| 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...