Handling Errors and Rate Limits

Every SGPayNowQR error code, recommended retry/backoff handling, and how to read the X-RateLimit-* response headers.

Every error response uses the same envelope, so you can handle them uniformly. Inspect error.code for a stable, machine-readable identifier and log meta.request_id for support.

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Monthly usage limit exceeded"
  },
  "meta": {
    "api_version": "v1",
    "request_id": "req_abc123def456"
  }
}

Error codes

HTTPCodeMeaning
400VALIDATION_ERRORInvalid parameters or missing required fields
400INVALID_JSONRequest body is not valid JSON
400INVALID_CONTENT_TYPEContent-Type must be application/json
401UNAUTHORIZEDMissing or invalid API key
429RATE_LIMIT_EXCEEDEDMonthly usage limit exceeded
500INTERNAL_ERRORServer error during QR generation

Retry guidance

4xx errors are caused by the request — fix the input rather than retrying. VALIDATION_ERROR, INVALID_JSON, and UNAUTHORIZED will keep failing identically. For 429 RATE_LIMIT_EXCEEDED, stop until the quota resets (see below). For 500 INTERNAL_ERROR, retry with exponential backoff (e.g. 1s, 2s, 4s) and cap the attempts.

Rate limits

Limits are per API key, per calendar month (Singapore timezone). Only successful (2xx) responses count toward the quota, and it resets on the 1st of each month at 00:00:00+08:00.

TierMonthly limit
Free50
Starter200
Pro2,000
Enterprise10,000

Reading the rate-limit headers

Every response carries your current quota state. Track these to avoid hitting the limit:

X-RateLimit-Limit: 200
X-RateLimit-Remaining: 158
X-RateLimit-Reset: 2026-04-01T00:00:00+08:00
X-Request-Id: req_abc123def456
  • X-RateLimit-Remaining — requests left this month; throttle as it approaches 0.
  • X-RateLimit-Reset — when the quota refills (ISO 8601, SGT).

Next, see TypeScript SDK Quickstart or the full API reference.