> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paycrest.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> API Reference for Paycrest. Explore endpoints, request/response formats, and integration details.

Welcome to the Paycrest API Reference. Here you'll find detailed documentation for all available endpoints, including request/response formats, authentication, and integration tips.

* For a quick start, see the [Quickstart](/quickstart) guide.
* For the interactive API explorer, use the individual endpoint pages in the sidebar.

The Paycrest Aggregator API provides a comprehensive interface for interacting with the Paycrest protocol. This API enables senders to create payment orders, providers to fulfill orders, and general access to protocol information.

## Base URL

```bash theme={null}
# Production (use this base for all new integrations)
https://api.paycrest.io/v2
```

<Note>
  Existing **v1** integrations use the same path names with base URL `https://api.paycrest.io/v1`. See the **Legacy (v1)** tab in the API Reference.
</Note>

## Authentication

All API requests require authentication using an API key. Include your API key in the request header:

```bash theme={null}
API-Key: YOUR_API_KEY
```

### Getting Your API Key

1. **Register** at [app.paycrest.io](https://app.paycrest.io)
2. **Complete KYB verification** (required for compliance)
3. **Access your API key** in your dashboard

<Note>
  Your API key should be kept secure and never shared publicly. It's used to authenticate all API requests and identify your account.
</Note>

## API Endpoints

The Paycrest API is organized into three main categories:

### Sender Endpoints

For entities that create payment orders:

* **`POST /sender/orders`** - Create a new payment order (offramp or onramp)
* **`GET /sender/orders`** - List payment orders with filtering
* **`GET /sender/orders/{id}`** - Get a specific payment order
* **`GET /sender/stats`** - Get sender statistics

### Provider Endpoints

For liquidity providers that fulfill orders:

* **`GET /provider/orders`** - List orders available for fulfillment
* **`GET /provider/orders/{id}`** - Get a specific order
* **`GET /provider/rates/{token}/{fiat}`** - Get market rate bands (`buy` / `sell` sides)
* **`GET /provider/stats`** - Get provider statistics
* **`GET /provider/node-info`** - Get provision node information

### General Endpoints

For protocol information and utilities:

* **`GET /currencies`** - List supported fiat currencies
* **`GET /institutions/{currency_code}`** - List supported institutions
* **`GET /tokens`** - List supported tokens and contract addresses
* **`GET /rates/{network}/{from}/{amount}/{to}`** - Get public buy/sell rate quotes (token+fiat or fiat+fiat via USDC on a network; no API key)
* **`GET /pubkey`** - Get aggregator public key
* **`POST /verify-account`** - Verify bank or mobile money account details before creating an order (mobile MSISDN normalized server-side; see [Verify Account](/api-reference/general/verify-account))
* **`GET /orders/{chain_id}/{id}`** - Get order status by onchain Gateway ID
* **`GET /reindex/{network}/{tx_hash_or_address}`** - Reindex a transaction or address

## Request Format

All requests should include the following headers:

```bash theme={null}
Content-Type: application/json
API-Key: YOUR_API_KEY
```

### Example Request

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.paycrest.io/v2/sender/orders" \
      -H "Content-Type: application/json" \
      -H "API-Key: YOUR_API_KEY" \
      -d '{
        "amount": "100",
        "source": {
          "type": "crypto",
          "currency": "USDT",
          "network": "base",
          "refundAddress": "0xYourWalletAddress"
        },
        "destination": {
          "type": "fiat",
          "currency": "NGN",
          "recipient": {
            "institution": "GTBINGLA",
            "accountIdentifier": "1234567890",
            "accountName": "John Doe",
            "memo": "Salary payment"
          }
        },
        "reference": "payment-123"
      }'
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const axios = require('axios');

    const API_KEY = 'YOUR_API_KEY';
    const BASE_URL = 'https://api.paycrest.io/v2';

    const orderData = {
      amount: '100',
      source: {
        type: 'crypto',
        currency: 'USDT',
        network: 'base',
        refundAddress: '0xYourWalletAddress'
      },
      destination: {
        type: 'fiat',
        currency: 'NGN',
        recipient: {
          institution: 'GTBINGLA',
          accountIdentifier: '1234567890',
          accountName: 'John Doe',
          memo: 'Salary payment'
        }
      },
      reference: 'payment-123'
    };

    const response = await axios.post(`${BASE_URL}/sender/orders`, orderData, {
      headers: {
        'API-Key': API_KEY,
        'Content-Type': 'application/json'
      }
    });

    console.log(response.data);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    API_KEY = 'YOUR_API_KEY'
    BASE_URL = 'https://api.paycrest.io/v2'

    order_data = {
        "amount": "100",
        "source": {
            "type": "crypto",
            "currency": "USDT",
            "network": "base",
            "refundAddress": "0xYourWalletAddress"
        },
        "destination": {
            "type": "fiat",
            "currency": "NGN",
            "recipient": {
                "institution": "GTBINGLA",
                "accountIdentifier": "1234567890",
                "accountName": "John Doe",
                "memo": "Salary payment"
            }
        },
        "reference": "payment-123"
    }

    response = requests.post(
        f'{BASE_URL}/sender/orders',
        headers={
            'API-Key': API_KEY,
            'Content-Type': 'application/json'
        },
        json=order_data
    )

    print(response.json())
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
        "bytes"
        "encoding/json"
        "fmt"
        "io"
        "net/http"
    )

    func main() {
        orderData := map[string]interface{}{
            "amount": "100",
            "source": map[string]interface{}{
                "type":          "crypto",
                "currency":      "USDT",
                "network":       "base",
                "refundAddress": "0xYourWalletAddress",
            },
            "destination": map[string]interface{}{
                "type":     "fiat",
                "currency": "NGN",
                "recipient": map[string]interface{}{
                    "institution":       "GTBINGLA",
                    "accountIdentifier": "1234567890",
                    "accountName":       "John Doe",
                    "memo":              "Salary payment",
                },
            },
            "reference": "payment-123",
        }

        jsonData, _ := json.Marshal(orderData)
        req, _ := http.NewRequest("POST", "https://api.paycrest.io/v2/sender/orders", bytes.NewBuffer(jsonData))
        req.Header.Set("API-Key", "YOUR_API_KEY")
        req.Header.Set("Content-Type", "application/json")

        client := &http.Client{}
        resp, _ := client.Do(req)
        defer resp.Body.Close()

        body, _ := io.ReadAll(resp.Body)
        fmt.Println(string(body))
    }
    ```
  </Tab>
</Tabs>

## Response Format

All API responses follow a consistent format:

```json theme={null}
{
  "status": "success",
  "message": "Operation completed successfully",
  "data": {
    // Response data here
  }
}
```

### Error Responses

Error responses include detailed information:

```json theme={null}
{
  "status": "error",
  "message": "Validation failed",
  "data": [
    {
      "field": "amount",
      "message": "Amount must be greater than 0"
    }
  ]
}
```

## Rate Limiting

API requests are rate-limited to ensure fair usage. Authenticated requests have a significantly higher limit than unauthenticated ones. If you hit the limit, the API returns `429 Too Many Requests` — back off and retry after a short delay.

## Pagination

List endpoints support pagination with the following parameters:

* **`page`** - Page number (default: 1)
* **`pageSize`** - Items per page (default: 20, max: 100)

### Example

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X GET "https://api.paycrest.io/v2/sender/orders?page=2&pageSize=10" \
      -H "API-Key: YOUR_API_KEY"
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const axios = require('axios');

    const API_KEY = 'YOUR_API_KEY';
    const BASE_URL = 'https://api.paycrest.io/v2';

    async function getOrders(page = 2, pageSize = 10) {
      const response = await axios.get(`${BASE_URL}/sender/orders`, {
        headers: { 'API-Key': API_KEY },
        params: { page, pageSize }
      });
      console.log(response.data);
    }
    getOrders();
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    API_KEY = 'YOUR_API_KEY'
    BASE_URL = 'https://api.paycrest.io/v2'

    response = requests.get(
        f'{BASE_URL}/sender/orders',
        headers={'API-Key': API_KEY},
        params={'page': 2, 'pageSize': 10}
    )
    print(response.json())
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    package main

    import (
        "fmt"
        "io"
        "net/http"
        "net/url"
    )

    func main() {
        baseURL := "https://api.paycrest.io/v2/sender/orders"
        params := url.Values{}
        params.Add("page", "2")
        params.Add("pageSize", "10")
        
        req, _ := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil)
        req.Header.Set("API-Key", "YOUR_API_KEY")
        
        client := &http.Client{}
        resp, _ := client.Do(req)
        defer resp.Body.Close()
        
        body, _ := io.ReadAll(resp.Body)
        fmt.Println(string(body))
    }
    ```
  </Tab>
</Tabs>

Response includes pagination metadata:

```json theme={null}
{
  "status": "success",
  "message": "Orders retrieved successfully",
  "data": {
    "total": 150,
    "page": 2,
    "pageSize": 10,
    "orders": [...]
  }
}
```

## Webhooks

Set up webhooks to receive real-time updates:

### Webhook Events

* **`payment_order.deposited`** - Deposit detected on the receive address
* **`payment_order.pending`** - Order matched and awaiting provider fulfillment
* **`payment_order.validated`** - Provider confirmed fiat delivery
* **`payment_order.settling`** - Settlement transaction broadcast onchain
* **`payment_order.settled`** - Settlement confirmed onchain
* **`payment_order.refunding`** - Refund transaction initiated
* **`payment_order.refunded`** - Deposit refunded to sender (fulfillment failed)
* **`payment_order.expired`** - Order expired with no deposit received

### Webhook Payload

Webhook signatures use HMAC-SHA256 over the **exact raw request body**. Do not re-serialize parsed JSON (key ordering differs). The `X-Paycrest-Signature` header is a **hex string** — compare using timing-safe equality on the **UTF-8 bytes of the hex strings** (see the [Sender API integration guide](/implementation-guides/sender-api-integration#verify-webhook-signatures)).

```json theme={null}
{
  "event": "payment_order.settled",
  "webhookVersion": "2",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "direction": "offramp",
    "status": "settled",
    "amount": "100",
    "amountInUsd": "100",
    "amountPaid": "100",
    "amountReturned": "0",
    "percentSettled": "100",
    "senderFee": "1",
    "transactionFee": "0.01",
    "rate": "1580.5",
    "gatewayId": "0xabc...",
    "senderId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "source": {
      "type": "crypto",
      "currency": "USDT",
      "network": "base",
      "refundAddress": "0xSenderWallet..."
    },
    "destination": {
      "type": "fiat",
      "currency": "NGN",
      "recipient": {
        "institution": "ACCESS",
        "accountIdentifier": "0123456789",
        "accountName": "Jane Doe",
        "memo": ""
      }
    },
    "fromAddress": "0xReceiverAddress...",
    "reference": "ref-001",
    "txHash": "0x1234567890abcdef...",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}
```

### Delivery logs & retry

Every webhook send is recorded as a **delivery**. Failed deliveries — transport errors **and** non-2xx responses — are retried automatically with exponential backoff for a 24-hour window, then marked `expired`. You can audit and replay deliveries yourself:

* [List Webhook Deliveries](/api-reference/sender/list-webhook-deliveries) — newest first, filter by `status`, `event`, `event_id`, `order_id`, or date range.
* [Get Webhook Delivery](/api-reference/sender/get-webhook-delivery-by-id) — full record including request payload and response body.
* [Retry Webhook Delivery](/api-reference/sender/retry-webhook-delivery) — replay a delivery (`?sync=true` for an inline result, otherwise queued).

<Note>
  For detailed webhook implementation guide including signature verification, retry logic, and best practices, see the [Sender API Integration Guide](/implementation-guides/sender-api-integration#webhooks).
</Note>

## Testing

Paycrest supports very low minimum orders (as little as \$0.50) and uses cost-effective EVM L2s, making it perfect for testing with real transactions. Start small and scale up as you gain confidence.

<Note>
  There is no sandbox environment at the moment. All testing should be done on production using small amounts.
</Note>

## Support

Need help with the API?

* **Documentation**: Browse our comprehensive guides
* **Telegram**: Join our developer community at [t.me/+Stx-wLOdj49iNDM0](https://t.me/+Stx-wLOdj49iNDM0)
* **GitHub**: Report issues at [github.com/paycrest](https://github.com/paycrest)
* **Email**: Contact support at [support@paycrest.io](mailto:support@paycrest.io)

## Fee Model

Protocol fees are paid by providers. Senders experience zero fees, maximizing their payout.
