SGPayNowQR

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"

Setup for every client

Rate Limits

TierMonthly Limit
Free50
Starter200
Pro2,000
Enterprise10,000

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-LimitintegerMonthly request limit for this account (shared across all its API keys)
X-RateLimit-RemainingintegerRemaining requests this month
X-RateLimit-ResetstringWhen the rate limit resets (1st of next month, SGT)
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_EXCEEDEDMonthly usage limit exceeded
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...