Base URL: https://api.marblepay.io/v1
Test URL: https://api-test.marblepay.io/v1
All API requests require authentication using API keys in the Authorization header:
Authorization: Bearer mp_live_your_api_key_here- Live mode:
mp_live_... - Test mode:
mp_test_...
- Live: 1000 requests/min per merchant
- Test: 100 requests/min per merchant
POST /v1/checkout/sessionsRequest Body:
{
"amount": 250000,
"currency": "NGN",
"settleCurrency": "USDC",
"chain": "base",
"description": "Order #1234",
"customerEmail": "customer@example.com",
"metadata": {
"orderId": "1234",
"customField": "value"
},
"webhookUrl": "https://yourdomain.com/webhooks/marblepay",
"redirectUrl": "https://yourdomain.com/payment/success",
"expiryMinutes": 15
}Response (201 Created):
{
"id": "cs_abc123",
"object": "checkout_session",
"status": "pending",
"amount": 250000,
"currency": "NGN",
"settleCurrency": "USDC",
"chain": "base",
"description": "Order #1234",
"payTo": {
"chain": "base",
"asset": "USDC",
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"amount": "234.56",
"qrCode": "data:image/png;base64,iVBORw0KG...",
"networkFee": "0.05"
},
"expiresAt": "2025-11-05T15:30:00Z",
"hostedCheckoutUrl": "https://checkout.marblepay.io/cs_abc123",
"metadata": {
"orderId": "1234",
"customField": "value"
},
"createdAt": "2025-11-05T15:15:00Z"
}Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
amount |
integer | Yes | Amount in smallest currency unit (e.g., kobo for NGN) |
currency |
string | Yes | Fiat currency code (NGN, USD) |
settleCurrency |
string | No | Settlement currency (USDC, USDT, NGN) - default: USDC |
chain |
string | Yes | Blockchain network (ethereum, base, solana) |
description |
string | Yes | Payment description |
customerEmail |
string | No | Customer email for receipt |
metadata |
object | No | Custom key-value data (max 50 keys) |
webhookUrl |
string | No | Override default webhook URL |
redirectUrl |
string | No | Redirect after payment success |
expiryMinutes |
integer | No | Quote expiry time (default: 15, max: 60) |
GET /v1/checkout/sessions/:idResponse (200 OK):
{
"id": "cs_abc123",
"object": "checkout_session",
"status": "confirmed",
"payment": {
"id": "pay_xyz789",
"txHash": "0x8f3b7c...",
"confirmations": 12,
"confirmedAt": "2025-11-05T15:20:00Z"
},
"settlement": {
"id": "stl_def456",
"status": "completed",
"amount": "234.56",
"currency": "USDC"
},
// ... other fields
}Status Values:
pending- Awaiting paymentpaid- Payment detected, pending confirmationsconfirmed- Payment confirmedexpired- Quote expiredrefunded- Payment refundedcancelled- Session cancelled
GET /v1/paymentsQuery Parameters:
?limit=20
&startingAfter=pay_xyz789
&status=confirmed
&chain=base
&createdGte=2025-11-01
&createdLte=2025-11-05
Response (200 OK):
{
"object": "list",
"data": [
{
"id": "pay_xyz789",
"object": "payment",
"sessionId": "cs_abc123",
"txHash": "0x8f3b7c...",
"chain": "base",
"asset": "USDC",
"amount": "234.56",
"status": "confirmed",
"confirmations": 12,
"requiredConfirmations": 2,
"detectedAt": "2025-11-05T15:17:00Z",
"confirmedAt": "2025-11-05T15:20:00Z",
"metadata": {}
}
],
"hasMore": true,
"nextCursor": "pay_xyz789"
}GET /v1/payments/:idResponse (200 OK):
{
"id": "pay_xyz789",
"object": "payment",
"sessionId": "cs_abc123",
"txHash": "0x8f3b7c...",
"chain": "base",
"asset": "USDC",
"amount": "234.56",
"status": "confirmed",
"confirmations": 12,
"requiredConfirmations": 2,
"fromAddress": "0x1234...",
"toAddress": "0x742d...",
"blockNumber": 12345678,
"blockHash": "0xabc...",
"detectedAt": "2025-11-05T15:17:00Z",
"confirmedAt": "2025-11-05T15:20:00Z",
"explorerUrl": "https://basescan.org/tx/0x8f3b7c...",
"metadata": {}
}POST /v1/refundsRequest Body:
{
"paymentId": "pay_xyz789",
"amount": "234.56",
"reason": "Customer requested refund",
"refundAddress": "0x1234...",
"metadata": {}
}Response (201 Created):
{
"id": "ref_ghi012",
"object": "refund",
"paymentId": "pay_xyz789",
"amount": "234.56",
"chain": "base",
"asset": "USDC",
"status": "pending",
"refundAddress": "0x1234...",
"txHash": null,
"reason": "Customer requested refund",
"createdAt": "2025-11-05T16:00:00Z",
"metadata": {}
}Refund Status:
pending- Awaiting processingprocessing- Transaction submitted to blockchaincompleted- Refund confirmed on-chainfailed- Refund failed (insufficient funds, invalid address, etc.)
GET /v1/refunds/:idGET /v1/refunds?paymentId=pay_xyz789&limit=20GET /v1/settlementsQuery Parameters:
?limit=20
&startingAfter=stl_def456
&status=completed
¤cy=USDC
&createdGte=2025-11-01
Response (200 OK):
{
"object": "list",
"data": [
{
"id": "stl_def456",
"object": "settlement",
"paymentId": "pay_xyz789",
"amount": "234.56",
"currency": "USDC",
"method": "crypto",
"destination": "0x9876...",
"status": "completed",
"txHash": "0xdef...",
"fee": "0.10",
"netAmount": "234.46",
"initiatedAt": "2025-11-05T15:25:00Z",
"completedAt": "2025-11-05T15:27:00Z"
}
],
"hasMore": false
}GET /v1/settlements/:idPOST /v1/payoutsRequest Body:
{
"amount": "1000.00",
"currency": "USDC",
"destination": "0x9876...",
"chain": "base",
"description": "Weekly payout",
"metadata": {}
}Response (201 Created):
{
"id": "po_jkl345",
"object": "payout",
"amount": "1000.00",
"currency": "USDC",
"chain": "base",
"destination": "0x9876...",
"status": "pending",
"fee": "1.00",
"netAmount": "999.00",
"description": "Weekly payout",
"txHash": null,
"createdAt": "2025-11-05T17:00:00Z",
"metadata": {}
}Payout Status:
pending- Awaiting processingprocessing- Transaction submittedcompleted- Payout confirmedfailed- Payout failed
GET /v1/payouts/:idGET /v1/payouts?limit=20&status=completedGET /v1/balanceResponse (200 OK):
{
"object": "balance",
"available": {
"USDC": "5430.20",
"USDT": "1200.00",
"NGN": "250000.00"
},
"pending": {
"USDC": "234.56",
"USDT": "0.00",
"NGN": "0.00"
},
"reserved": {
"USDC": "100.00",
"USDT": "0.00",
"NGN": "0.00"
}
}GET /v1/webhook_eventsQuery Parameters:
?limit=20
&type=payment.confirmed
&deliveryStatus=delivered
&createdGte=2025-11-01
Response (200 OK):
{
"object": "list",
"data": [
{
"id": "evt_mno678",
"object": "webhook_event",
"type": "payment.confirmed",
"data": {
"id": "pay_xyz789",
"sessionId": "cs_abc123",
// ... payment object
},
"deliveryAttempts": 1,
"deliveryStatus": "delivered",
"deliveredAt": "2025-11-05T15:20:05Z",
"createdAt": "2025-11-05T15:20:00Z"
}
],
"hasMore": false
}GET /v1/webhook_events/:idGET /v1/assetsResponse (200 OK):
{
"object": "list",
"data": [
{
"asset": "USDC",
"name": "USD Coin",
"chains": [
{
"chain": "ethereum",
"contractAddress": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"minAmount": "1.00",
"maxAmount": "100000.00",
"requiredConfirmations": 12,
"avgConfirmationTime": "3 minutes"
},
{
"chain": "base",
"contractAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"minAmount": "1.00",
"maxAmount": "100000.00",
"requiredConfirmations": 2,
"avgConfirmationTime": "5 seconds"
}
]
},
{
"asset": "USDT",
"name": "Tether USD",
"chains": [
{
"chain": "ethereum",
"contractAddress": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"minAmount": "10.00",
"maxAmount": "50000.00",
"requiredConfirmations": 12,
"avgConfirmationTime": "3 minutes"
}
]
}
]
}{
"error": {
"type": "invalid_request_error",
"code": "amount_too_small",
"message": "Amount must be at least 100 NGN",
"param": "amount",
"docUrl": "https://docs.marblepay.io/errors#amount_too_small"
}
}| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid API key |
| 403 | Forbidden - API key lacks permissions |
| 404 | Not Found - Resource doesn't exist |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
| 503 | Service Unavailable |
authentication_error- API key invalid or missinginvalid_request_error- Request parameters invalidrate_limit_error- Too many requestsresource_not_found- Resource doesn't existinsufficient_funds- Merchant balance too lowblockchain_error- Blockchain RPC failurecompliance_error- Transaction blocked by compliance checks
Prevent duplicate requests using the Idempotency-Key header:
curl https://api.marblepay.io/v1/checkout/sessions \
-H "Authorization: Bearer mp_live_..." \
-H "Idempotency-Key: unique-key-123" \
-d amount=250000 \
-d currency=NGNKeys expire after 24 hours. Use UUID v4 for uniqueness.
List endpoints use cursor-based pagination:
{
"object": "list",
"data": [...],
"hasMore": true,
"nextCursor": "pay_xyz789"
}Query Parameters:
limit- Number of items (default: 20, max: 100)startingAfter- Cursor for next pageendingBefore- Cursor for previous page
API version is in the URL path: /v1/...
Breaking changes will increment the version. Non-breaking changes are deployed without version changes.
npm install @marblepay/nodeimport MarblePay from '@marblepay/node';
const marblepay = new MarblePay('mp_live_...');
const session = await marblepay.checkout.sessions.create({
amount: 250000,
currency: 'NGN',
chain: 'base'
});pip install marblepayimport marblepay
marblepay.api_key = 'mp_live_...'
session = marblepay.CheckoutSession.create(
amount=250000,
currency='NGN',
chain='base'
)composer require marblepay/marblepay-php<?php
require_once('vendor/autoload.php');
\MarblePay\MarblePay::setApiKey('mp_live_...');
$session = \MarblePay\CheckoutSession::create([
'amount' => 250000,
'currency' => 'NGN',
'chain' => 'base'
]);Next: Webhooks Guide | Compliance Guide