APIs Built for
Speed and Scale
Simple REST API. Signed webhooks. No SDK required. Your first sandbox payout is two calls away.
Quick start
The same two calls in cURL and plain Node.js — no client library needed. Phone, currency, and network values below are placeholders. The codes for a licensed market are shared during onboarding.
cURL
# 1. Get a quote
curl -X POST https://api.settlra.com/v1/quotes \
-H "Authorization: Bearer pk_test_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quote_001" \
-d '{
"source_amount_usdc": 25.50,
"target_currency": "LOCAL",
"idempotency_key": "quote_001"
}'
# 2. Execute the payout
curl -X POST https://api.settlra.com/v1/payouts \
-H "Authorization: Bearer pk_test_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_8821" \
-d '{
"quote_id": "qt_01HXYZ9ABCDEF",
"recipient_phone": "+00000000000",
"network": "MOBILE_MONEY",
"recipient_name": "Grace Nakamura",
"idempotency_key": "order_8821"
}'Node.js (fetch)
const BASE = 'https://api.settlra.com/v1';
const headers = (key) => ({
Authorization: `Bearer ${process.env.SETTLRA_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': key,
});
// Get a quote (valid for 45 seconds)
const quote = await fetch(`${BASE}/quotes`, {
method: 'POST',
headers: headers('quote_001'),
body: JSON.stringify({
source_amount_usdc: 25.5,
target_currency: 'LOCAL',
idempotency_key: 'quote_001',
}),
}).then((r) => r.json());
// Create the payout
const payout = await fetch(`${BASE}/payouts`, {
method: 'POST',
headers: headers('order_8821'),
body: JSON.stringify({
quote_id: quote.quote_id,
recipient_phone: '+00000000000',
network: 'MOBILE_MONEY',
recipient_name: 'Grace Nakamura',
idempotency_key: 'order_8821',
}),
}).then((r) => r.json());
console.log(payout.status); // 'AWAITING_FUNDS'
console.log(payout.deposit_address); // send exactly the quoted USDC hereEverything you need
REST API
Clean, predictable REST endpoints. JSON request/response with consistent error codes and detailed messages.
Webhooks
Real-time event notifications for every payout state change. Signed payloads with HMAC-SHA256 verification.
No SDK required
Official SDKs are not published yet. The API is small enough to call directly — the docs show every example in plain fetch and Python requests.
Sandbox Environment
Same host, pk_test_ keys. No real money moves; wallet deposits can be simulated. Sandbox and production are bound to the key, not a header.
Idempotency
Safe retries with idempotency keys. Duplicate requests return the original response — no double payouts.
Status Page
Live operational status for the API and each payment provider at settlra.com/status.
API endpoints
Base URL: https://api.settlra.com
Webhooks
Receive real-time notifications when payout status changes. All webhook payloads are signed with HMAC-SHA256 so you can verify authenticity.
Event types
payout.funds_receivedUSDC confirmed on-chainpayout.initiatedSent to the mobile money providerpayout.compliance_holdPaused for manual reviewpayout.settledMobile money deliveredpayout.failedPayout could not be completedpayout.reversedFailed payout reversed, USDC returned
import crypto from 'crypto';
// Your webhook handler (Express.js, raw body parser)
app.post('/webhooks/settlra', (req, res) => {
const signature = req.headers['x-settlra-signature']; // hex HMAC-SHA256, no prefix
const expected = crypto
.createHmac('sha256', process.env.SETTLRA_WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
const a = Buffer.from(signature ?? '');
const b = Buffer.from(expected);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body.toString());
switch (event.type) {
case 'payout.settled':
console.log('Payout delivered:', event.data.payout_id);
break;
case 'payout.failed':
console.log('Payout failed:', event.data.payout_id);
break;
}
res.json({ received: true });
});Ready to build?
Sign up, complete KYC review with our team, and start in the sandbox — no credit card required.