SGPayNowQR

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"

Setup for every client

Plans and Rate Limits

PlanPriceLimit per billing period
FreeS$0, no card needed50 codes, then requests stop until the next period
Pay as you goS$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,000Up to your maximum monthly bill: S$50 by default (11,760 codes), settable from S$10 (914) to S$500 (191,760)

Guides

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

POST/generate

Generate an EMVCo-compliant PayNow QR code for Singapore payments. Supports UEN, mobile number, and VPA payment types.

Request Body

FieldTypeRequiredDescription
payment_typestringRequiredType of PayNow paymentValues: uen, mobile, vpa
uenstringConditionalUEN number (required if payment_type is "uen")Max length: 25
merchant_namestringConditionalMerchant name (required if payment_type is "uen")Max length: 25
mobile_numberstringConditionalSingapore mobile number (required if payment_type is "mobile")Pattern: ^(\+65)?[89]\d{7}$
vpastringConditionalVirtual Payment Address (required if payment_type is "vpa")
amountnumberRequiredPayment amount in SGDMin: 0.01 · Max: 999999.99
referencestringOptionalOptional alphanumeric referenceMax length: 25 · Pattern: ^[a-zA-Z0-9]*$
expirystringOptionalQR code expiry durationValues: 1h, 2h, 6h, 12h, 24h, none · Default: 24h
qr_colorstringOptionalQR code color as 6-digit hex (without #)Pattern: ^[0-9a-fA-F]{6}$ · Default: 7d1979
qr_sizeintegerOptionalQR code image size in pixelsValues: 200, 300, 400 · Default: 300
include_imagebooleanOptionalWhether 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

200QR code generated successfully
Response Headers
HeaderTypeDescription
X-RateLimit-LimitintegerRequest 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-RemainingintegerRemaining requests this billing period
X-RateLimit-ResetstringWhen the quota resets (end of the account's billing period, Singapore time)
X-Request-IdstringUnique request identifier

Error Codes

HTTPCodeDescription
400VALIDATION_ERRORMissing required fields for the selected payment_type
400INVALID_JSONMalformed JSON body
401UNAUTHORIZEDInvalid API key
429RATE_LIMIT_EXCEEDEDQuota 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
GET/healthNo auth required

Returns API health status. No authentication required.

Success Response

200Health status
GET/usage

Returns 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

200Usage for the current period

Error Codes

HTTPCodeDescription
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...