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

{% hint style="info" %}
**API positioning:** PayChain is SDK-first for speed, but API-complete for teams that need direct HTTP access or non-TypeScript environments.
{% endhint %}

For exact schemas, query parameters, and endpoint paths, use OpenAPI reference.

### Base URLs

| Environment | Base URL                                                                    |
| ----------- | --------------------------------------------------------------------------- |
| Live        | `https://api.paychainhq.io/api/v1`                                          |
| Sandbox     | Use the sandbox API URL provided in your dashboard or onboarding materials. |

{% hint style="warning" %}
**Environment note:** Keep sandbox and live API keys, webhook secrets, and webhook URLs separate.
{% endhint %}

### Required headers

```http
x-api-key: $PAYCHAIN_API_KEY
content-type: application/json
Idempotency-Key: order_123_invoice
```

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

### API key types

| Key type         | Use it for                                                                      | Do not use it for                                                                    |
| ---------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Standard API key | Customers, invoices, reads, balances, transactions, networks, tokens, webhooks. | Programmatic withdrawals or fund movement.                                           |
| Payout API key   | Programmatic withdrawals and approved payout automation.                        | Admin actions, dashboard-session actions, route-template mutation, billing controls. |

{% hint style="danger" %}
**Security note:** API keys must stay on your backend. Never expose them in frontend JavaScript, mobile apps, public repositories, browser extensions, or analytics logs.
{% endhint %}

### Common REST request pattern

```bash
curl -X POST "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/invoices" \
  -H "x-api-key: $PAYCHAIN_API_KEY" \
  -H "content-type: application/json" \
  -H "Idempotency-Key: order_123_invoice" \
  -d '{
    "amount": "100.00",
    "token": "USDC",
    "chain": "evm",
    "networkId": "base-mainnet",
    "metadata": {
      "orderId": "order_123"
    }
  }'
```

### Core REST examples

#### Create a customer

```bash
curl -X POST "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/customers" \
  -H "x-api-key: $PAYCHAIN_API_KEY" \
  -H "content-type: application/json" \
  -H "Idempotency-Key: customer_123_create" \
  -d '{
    "externalRef": "customer_123"
  }'
```

#### Get an invoice after a webhook

```bash
curl "$PAYCHAIN_API_URL/businesses/invoices/inv_123" \
  -H "x-api-key: $PAYCHAIN_API_KEY"
```

#### List invoices for reconciliation

```bash
curl "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/invoices?status=paid&limit=50" \
  -H "x-api-key: $PAYCHAIN_API_KEY"
```

#### Quote and create a withdrawal

```bash
curl -X POST "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/withdrawals/quote" \
  -H "x-api-key: $PAYCHAIN_PAYOUT_API_KEY" \
  -H "content-type: application/json" \
  -H "Idempotency-Key: payout_123_quote" \
  -d '{
    "amount": "25.00",
    "token": "USDC",
    "chain": "evm",
    "networkId": "base-mainnet",
    "destinationAddress": "0x0000000000000000000000000000000000000000"
  }'

curl -X POST "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/withdrawals" \
  -H "x-api-key: $PAYCHAIN_PAYOUT_API_KEY" \
  -H "content-type: application/json" \
  -H "Idempotency-Key: payout_123_create" \
  -d '{
    "quoteId": "quote_123",
    "clientReference": "payout_123"
  }'
```

#### Read balances and transactions

```bash
curl "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/balances" \
  -H "x-api-key: $PAYCHAIN_API_KEY"

curl "$PAYCHAIN_API_URL/businesses/$PAYCHAIN_BUSINESS_ID/transactions?limit=50" \
  -H "x-api-key: $PAYCHAIN_API_KEY"
```

#### Discover networks and tokens

```bash
curl "$PAYCHAIN_API_URL/networks" \
  -H "x-api-key: $PAYCHAIN_API_KEY"

curl "$PAYCHAIN_API_URL/tokens?networkId=base-mainnet" \
  -H "x-api-key: $PAYCHAIN_API_KEY"
```

#### Read billing and gas usage

```bash
curl "$PAYCHAIN_API_URL/billing/me" \
  -H "x-api-key: $PAYCHAIN_API_KEY"

curl "$PAYCHAIN_API_URL/billing/usage" \
  -H "x-api-key: $PAYCHAIN_API_KEY"
```

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

{% hint style="warning" %}
**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.
{% endhint %}

### Webhooks

REST integrations should still use signed webhooks for real-time lifecycle changes.

```http
X-Webhook-Signature: ...
X-Webhook-Timestamp: ...
X-Webhook-ID: ...
```

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

| SDK method                      | REST concept                     |
| ------------------------------- | -------------------------------- |
| `paychain.customers.create()`   | Create customer endpoint         |
| `paychain.invoices.create()`    | Create invoice endpoint          |
| `paychain.invoices.get()`       | Get invoice endpoint             |
| `paychain.withdrawals.quote()`  | Quote withdrawal endpoint        |
| `paychain.withdrawals.create()` | Create withdrawal endpoint       |
| `paychain.balances.list()`      | List balances endpoint           |
| `paychain.transactions.list()`  | List transactions endpoint       |
| `paychain.networks.list()`      | List supported networks endpoint |
| `paychain.tokens.list()`        | List supported tokens endpoint   |

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

### Production checklist

* API keys stored in secret manager.
* 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paychainhq.io/paychainhq-documentation-page/developer-quickstart/rest-api-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
