Skip to main content

REST API Guide

PayChain exposes the same core payment, payout, balance, transaction, network, token, billing, and webhook surfaces over HTTPS. The SDK is recommended for Node.js and TypeScript, but the REST API remains the source of truth for direct integrations.
API positioning: PayChain is SDK-first for speed, but API-complete for teams that need direct HTTP access or non-TypeScript environments.
For exact schemas, query parameters, and endpoint paths, use OpenAPI reference.

Base URLs

Environment note: Keep sandbox and live API keys, webhook secrets, and webhook URLs separate.

Required headers

Use Idempotency-Key on mutating requests so retries do not create duplicate invoices, withdrawals, or payout actions.

API key types

Pricing note: A payout API key is necessary for programmatic withdrawal creation, and the request must still pass policy, balance, and destination checks. Free plan businesses have 0 included payout API withdrawals, so the Free payout API fee applies from the first programmatic withdrawal.
Security note: API keys must stay on your backend. Never expose them in frontend JavaScript, mobile apps, public repositories, browser extensions, or analytics logs.

Common REST request pattern

Core REST examples

Create a customer

Ensure a customer deposit address

Use this before displaying a reusable customer address for a specific rail. Send the exact chain and networkId, then verify the returned address.chainFamily and address.networkId before showing the address to the payer. Solana and Stellar use the same ensure pattern: call the customer address ensure endpoint for the exact rail and never fall back to an EVM 0x... address when a non-EVM address is expected. The ensure endpoint:
  • Returns the existing customer address when the customer already has one for the requested rail.
  • Provisions a missing address when the business is configured for that rail.
  • Returns created and address metadata so your backend can verify the rail before displaying payment instructions.
Call this endpoint before showing a reusable address, not only when the customer is first created. This keeps existing customers compatible when PayChain enables a new network, because older customers may not have an address for that rail until your integration asks PayChain to ensure it.
The response returns created: true when PayChain provisioned a new address, or created: false when the address already existed. Use the returned address.address only when the returned rail matches the requested rail, such as address.chainFamily: "sol" with address.networkId: "sol-mainnet" or address.chainFamily: "stellar" with address.networkId: "stellar-mainnet".
Lazy provisioning note: If networkId is omitted and only one active network matches the requested rail, PayChain may infer it. Production integrations should still send networkId explicitly so the address-selection pattern stays consistent across Solana, Stellar, and future rails.

Get an invoice after a webhook

Poll invoice confirmation progress

When a payment is waiting for finality, invoice responses can include confirmationProgress.current, confirmationProgress.required, confirmationProgress.remaining, confirmationProgress.percent, and confirmationProgress.txHash.

List invoices for reconciliation

Quote and create a withdrawal

Read balances and transactions

Balance responses separate amounts.total from amounts.totalHeld and amounts.requiresRecovery. Use amounts.total or withdrawal quotes for payout capacity.

Discover networks and tokens

Read billing and gas usage

Response handling

Store these values when available:
  • PayChain resource ID.
  • Your own clientReference or externalRef.
  • x-request-id.
  • Status.
  • Amount, token, chain, and network.
  • Webhook delivery ID.
  • Transaction hash after settlement or payout completion.

Pagination

List endpoints may paginate. Keep pagination handling server-side and do not build business-critical reconciliation from a small client-side row limit.

Errors

Expect structured errors with:
  • HTTP status.
  • Machine-readable code.
  • Message.
  • Request ID.
  • Details where available.
Error handling note: Do not retry validation errors, authentication errors, or policy rejections blindly. Retry only transient network failures, 408, 429, and 5xx responses, and only retry non-idempotent POST requests when an idempotency key is present.

Webhooks

REST integrations should still use signed webhooks for real-time lifecycle changes.
Verify the signature with the raw request body, then fetch the canonical invoice or withdrawal before fulfillment. See Webhooks for event handling, retries, replay, and common mistakes.

How REST maps to the SDK

See Supported networks and tokens before hardcoding any network or token assumptions.

Production checklist

  • API keys stored in protected server-side secret storage.
  • Idempotency keys on mutating requests.
  • Webhook signature verification uses raw body.
  • Standard and payout API keys are separated.
  • Request IDs are logged without secrets.
  • Sandbox and live credentials are separate.
  • Payout destinations are validated server-side.
  • Billing, gas credits, and payout quota behavior are understood.