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 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
# Production (use this base for all new integrations)
https://api.paycrest.io/v2
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.
Authentication
All API requests require authentication using an API key. Include your API key in the request header:
Getting Your API Key
- Register at app.paycrest.io
- Complete KYB verification (required for compliance)
- Access your API key in your dashboard
Your API key should be kept secure and never shared publicly. It’s used to authenticate all API requests and identify your account.
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}/{token}/{amount}/{fiat} - Get public buy/sell rate quotes for a token/fiat pair on a network (no API key)
GET /pubkey - Get aggregator public key
POST /verify-account - Verify bank account details before creating an order
GET /orders/{chain_id}/{id} - Get order status by onchain Gateway ID
GET /reindex/{network}/{tx_hash_or_address} - Reindex a transaction or address
All requests should include the following headers:
Content-Type: application/json
API-Key: YOUR_API_KEY
Example Request
cURL
JavaScript
Python
Go
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"
}'
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);
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())
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))
}
All API responses follow a consistent format:
{
"status": "success",
"message": "Operation completed successfully",
"data": {
// Response data here
}
}
Error Responses
Error responses include detailed information:
{
"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.
List endpoints support pagination with the following parameters:
page - Page number (default: 1)
pageSize - Items per page (default: 20, max: 100)
Example
cURL
JavaScript
Python
Go
curl -X GET "https://api.paycrest.io/v2/sender/orders?page=2&pageSize=10" \
-H "API-Key: YOUR_API_KEY"
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();
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())
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))
}
Response includes pagination metadata:
{
"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. Verify against the raw request body, not re-serialized JSON.
{
"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"
}
}
For detailed webhook implementation guide including signature verification, retry logic, and best practices, see the Sender API Integration Guide.
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.
There is no sandbox environment at the moment. All testing should be done on production using small amounts.
Support
Need help with the API?
Fee Model
Protocol fees are paid by providers. Senders experience zero fees, maximizing their payout.