Get started

Authentication

Every request to the Baynoy API must carry an Authorization: Bearer sk_… header. Optionally, you can pin requests to a list of source IPs, sign the body with HMAC-SHA256 for tamper evidence, and lock to a specific API version.

Response envelope

Every API response wraps its payload in an envelope. Branch on the top-levelok boolean before consuming the body:

{
  "ok": true,
  "data": { /* endpoint-specific payload */ }
}

// or on failure:
{
  "ok": false,
  "error": { "code": "...", "message": "...", "details": { /* optional */ } }
}

Every example on the API reference pages shows the full envelope. SDK wrappers (Node, Python, PHP) unwrap automatically so client code readsdata directly.

Secret keys

Generate keys from /dashboard/developers. There are two modes:

  • sk_test_… — sandbox. No real charges, free limits, available immediately.
  • sk_live_…— production. Requires Tier 1 KYC. Charges hit your customers' cards for real money.

The plain secret is shown once on creation; only its SHA256 hash is stored. You also get a publishable key (pk_test_… / pk_live_…) that's safe to embed in client code.

curl https://baynoy.com/api/v1/balance \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

Scopes

Each key declares a permission list at creation. The wildcard "*" grants every scope; otherwise pick a subset:

payments:readpayments:writecustomers:readcustomers:writeproducts:readproducts:writeinvoices:readinvoices:writerefunds:readrefunds:writepayment_links:readpayment_links:writesubscriptions:readsubscriptions:writepayouts:readbalance:readevents:read

Requests lacking the scope required by an endpoint return 403 insufficient_scope with the required scope echoed in the error body.

IP allowlist

Lock a key to a list of source IPs or CIDR blocks. Empty allowlist means any IP is allowed (handy for local dev / mobile). Populated means strict — non-matching IPs return 403 ip_not_allowed.

203.0.113.42
198.51.100.0/24
192.0.2.7

IPv4 supports full CIDR. IPv6 entries are exact-string match only.

HMAC request signing (optional)

For high-value endpoints, enable signed requests by sending aBaynoy-Signature header alongside every Bearer call. Verification is enforced on every Bearer-authenticated route — if the header is present, it must validate, or the request returns401 signature_invalid. Absent header is allowed (signing is opt-in). The partner computes:

signature = HMAC_SHA256(secret_key, "<unix_ms>." + raw_body)
Baynoy-Signature: t=<unix_ms>,v1=<hex_signature>

The server recomputes and constant-time compares. Stale timestamps (>5 min) reject. Same format as our outbound webhook signing so partners only learn one pattern.

API version

Pin a specific date-stamped version via the Baynoy-Version header. The server resolves the version on every Bearer call (validation, deprecation warnings) and echoesBaynoy-Version back on every Bearer response across every /v1/* endpoint. POST writes additionally honour Idempotency-Key for 24h retry safety.

curl https://baynoy.com/api/v1/balance \
  -H "Authorization: Bearer sk_test_…" \
  -H "Baynoy-Version: 2026-05-27"

The current stable version is 2026-05-27. Old versions stay supported for 12 months after a newer one ships. Deprecated versions emit a Baynoy-Version-Deprecated: yes warning header.