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,
});

Rate Limits

TierMonthly Limit
Free50
Starter200
Pro2,000
Enterprise10,000

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 (withoutPattern: ^[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

  • uenUEN number (required if payment_type is "uen")
  • merchant_nameMerchant name (required if payment_type is "uen")
  • mobile_numberSingapore mobile number (required if payment_type is "mobile")
  • vpaVirtual 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 API key
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
500Internal server error
GET/healthNo auth required

Returns API health status. No authentication required.

Success Response

200Health status

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