Developer API · v1

A clean REST API for crypto payment infrastructure.

Create invoices and payment links, accept crypto, reconcile via webhooks, and pay out — all through a small REST surface with scoped keys, IP allow-listing, idempotency and rate limits.

Base URL
https://api.xynex.app/v1
Auth
Bearer <api_key>
Versioning
URL-pinned, /v1
Step 1

Create your first invoice in 60 seconds.

Generate a test key in Merchant → Developers → API Keys, then create an invoice. The response contains a hosted checkout URL you can redirect customers to.

curl
curl -X POST https://api.xynex.app/v1/invoices \ -H "Authorization: Bearer cp_test_xxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "reference": "order-1042", "amount": 49.00, "currency": "usd", "customer": { "email": "buyer@example.com" } }'
response
{ "data": { "id": "inv_01HX…", "public_id": "in_01HX…", "reference": "order-1042", "amount": 49, "currency": "usd", "status": "pending", "checkout_url": "https://xynex.app/checkout/abc123", "expires_at": "2026-06-06T12:00:00Z", "created_at": "2026-06-06T11:00:00Z" } }
Step 2

Authentication, scopes and limits.

Every request must include a Bearer token. Test keys are prefixed cp_test_ and live keys cp_live_. Keys never leave the browser on creation — the plaintext is shown once.

Scopes

Each key carries an explicit list of scopes — e.g. invoices.write, payouts.read. Requests outside a key's scopes return 403 insufficient_scope. Use * only for trusted server keys.

IP allow-list

Optionally restrict a key to specific IPs or CIDR ranges. Requests from outside the allow-list return 403 ip_not_whitelisted and are recorded in your access denial log.

Rate limits

Configurable per key (1–600 / min, default 60). Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. 429s include Retry-After.

Idempotency

Pass an Idempotency-Key header on POSTs. The first response is cached for 24h; replays return the original body with Idempotent-Replayed: true.

Reference

Endpoint reference.

All endpoints are JSON, all writes accept an optional idempotency key, all responses include X-Request-Id for support correlation.

Invoices

  • POST
    /invoices
    Create an invoice + hosted checkout URL
  • GET
    /invoices/{id}
    Retrieve an invoice and its payment state

Payments

  • GET
    /payments
    List payments, filtered by status / date
  • GET
    /payments/{id}
    Retrieve a single payment

Payment links

  • POST
    /payment-links
    Create a shareable payment link

Payouts

  • POST
    /payouts
    Create a single crypto payout
  • POST
    /payouts/batch
    Submit a mass payout batch
  • GET
    /payouts/{id}
    Retrieve a payout

Refunds

  • POST
    /refunds
    Issue a refund against a settled payment

Balances

  • GET
    /balances
    List available + held balances per coin

Beneficiaries

  • GET
    /beneficiaries
    List saved payout beneficiaries
  • POST
    /beneficiaries
    Create a beneficiary
  • DELETE
    /beneficiaries/{id}
    Delete a beneficiary

Subscriptions

  • POST
    /subscription-plans
    Create a plan
  • POST
    /subscriptions
    Create a subscription
  • GET
    /subscriptions/{id}
    Retrieve a subscription

Reference

  • GET
    /coins
    Supported coins / networks
  • POST
    /fees/preview
    Preview fees for a payout or invoice
Errors

Error envelope and status codes.

Errors share a single envelope. request_id is also returned as the X-Request-Id header.

json
{ "error": "validation_failed", "message": "amount must be greater than 0", "issues": [{ "path": ["amount"], "message": "Number must be > 0" }], "request_id": "f47ac10b-58cc-…" }
StatusCodeWhen
400invalid_requestMalformed body or query parameters
401unauthorizedMissing or invalid bearer token
403insufficient_scope / ip_not_whitelisted / plan_feature_disabledKey lacks scope, caller IP not in allow-list, or plan does not include this endpoint
404not_foundResource does not exist or is not visible to this merchant
422validation_failedSchema-level rejection (Zod issues array included)
429rate_limitedPer-minute quota exhausted; see X-RateLimit-Reset / Retry-After
500internal_errorUnexpected server error; include request_id in support tickets
Events

Webhooks and signature verification.

Configure HTTPS endpoints under Merchant → Developers → Webhooks. Every delivery is HMAC-SHA256 signed using your endpoint secret. Always verify the signature with a constant-time compare before trusting the payload.

node
import { createHmac, timingSafeEqual } from "node:crypto"; export function verifyXynexSignature(rawBody: string, header: string, secret: string) { const expected = createHmac("sha256", secret).update(rawBody).digest("hex"); const a = Buffer.from(header); const b = Buffer.from(expected); return a.length === b.length && timingSafeEqual(a, b); }

Common events: invoice.created, payment.confirming, payment.finished, payout.completed, refund.completed.

Changelog

API changelog.

  • 2026-06-06
    Per-key IP allow-listing and rate-limit headers.
    API keys can now be restricted to specific IPs / CIDRs. Every response carries X-RateLimit-Limit / Remaining / Reset and X-Request-Id.
  • 2026-05-20
    v1 stable.
    Invoices, payments, payouts, refunds, balances, beneficiaries, subscriptions, payment-links.

Build with Xynex.

Spin up sandbox keys in a minute. Move to live when you're ready — same API, same payloads.