MonCash API and NatCash API documentation
Everything you need to integrate payouts to MonCash and NatCash wallets from your platform: authentication, endpoints, statuses, errors and copy-ready examples.
Quick start
- Create a free account and generate an API user and a TEST
PRIVATE_KEYin the dashboard. - Use the TEST base URL:
https://api.levapay.dev/test/v1 - Check your balance, quote, send with a unique
idempotency_keyand check the status. - Once your business is verified, repeat with your PROD keys and the PROD base URL:
https://api.levapay.dev/prod/v1
A TEST key does not work in PROD and vice versa. Transfers are made by your platform through the API.
TEST mode
- TEST balance is not real money and is assigned by LevaPay. If your TEST balance is 0, transfers return 402: ask your LevaPay contact for TEST balance.
- NatCash: use the test wallet
50940885084. The transfer iscompletedinstantly. - MonCash: in TEST, transfers stay
pendingand the amount is reserved from your TEST balance. Use it to test how you handle statuses.
Authentication
Send these headers with every request:
Content-Type: application/json
X-Api-User: YOUR_USER
X-Api-Key: YOUR_PRIVATE_KEYEvery response is JSON with ok. If ok is false, the message field explains why.
Balance
GEThttps://api.levapay.dev/test/v1/balance
Returns the available prepaid balance in HTG for the mode in the URL.
{ "ok": true, "data": { "mode": "test", "balance_htg": 2000.00, "currency": "HTG" } }Quote
POSThttps://api.levapay.dev/test/v1/transfers/quote
{
"network": "natcash",
"wallet": "50940885084",
"amount_htg": 100,
"note": "Order payment 123"
}network: natcash or moncash. wallet: 8 digits or 509 + 8. amount_htg: whole number, 1 or more. The quote lasts about 120 seconds and total_htg is what will be debited from your balance if you confirm.
note (optional, up to 64 characters): text the recipient sees on the deposit. If omitted, LEVAPAY is used.
Response:
{
"ok": true,
"data": {
"quote_id": "qt_df63eb09ceba25c5be99",
"network": "natcash",
"wallet_masked": "509****5084",
"amount_htg": 100,
"fee_htg": 3.5,
"total_htg": 103.5,
"expires_at": "2026-10-04T12:00:05-04:00",
"beneficiary": "Test account"
}
}fee_htg is the fee and total_htg = amount_htg + fee_htg. beneficiary (account holder name) is only returned for NatCash.
Send
POSThttps://api.levapay.dev/test/v1/transfers
{ "quote_id": "qt_...", "idempotency_key": "order-123" }You can also omit quote_id and send network, wallet and amount_htg together with idempotency_key.
Idempotency: repeating the request with the same idempotency_key and the same body returns the same transfer with no second debit; the same key with a different body returns 409. A quote can only be sent once.
Response:
{
"ok": true,
"data": {
"id": "tr_2d3c076092bbff0f59e3",
"status": "completed",
"network": "natcash",
"wallet": "509****5084",
"amount_htg": 100,
"fee_htg": 3.5,
"total_htg": 103.5,
"created_at": "2026-10-04T11:58:05-04:00",
"completed_at": "2026-10-04T11:58:06-04:00",
"message": null
}
}Dates use ISO 8601 with a time zone. message contains the reason when a transfer ends up failed.
History and status
GEThttps://api.levapay.dev/test/v1/transfers
Optional parameters: page, per_page (up to 100), status and network. Newest first.
{
"ok": true,
"data": {
"items": [
{
"id": "tr_37092e06026a4f7cc967",
"status": "pending",
"network": "moncash",
"wallet": "509****5084",
"amount_htg": 10,
"fee_htg": 0.35,
"total_htg": 10.35,
"created_at": "2026-10-04T11:58:08-04:00",
"completed_at": null,
"message": null
}
],
"page": 1,
"per_page": 20,
"total": 6
}
}GEThttps://api.levapay.dev/test/v1/transfers/{id}
Returns the same object as the transfer. If the status is pending (MonCash), check again until completed or failed.
NatCash account holder
GEThttps://api.levapay.dev/test/v1/wallets/50940885084?network=natcash
Returns the account holder name of a NatCash wallet and creates a 100 HTG verification quote: confirm it with POST /transfers only if you want to send it. Not available for MonCash.
{
"ok": true,
"data": {
"network": "natcash",
"wallet_masked": "509****5084",
"beneficiary": "Test account",
"quote_id": "qt_028c3443d910b8ed7db3",
"note": "Cotización de verificación (100 HTG). Confirme con POST /transfers si desea enviarla."
}
}Errors and statuses
| HTTP | Meaning |
|---|---|
| 401 | Invalid user or key, or a key from the other mode |
| 402 | Insufficient prepaid balance |
| 403 | Account not yet approved for production (PROD only) |
| 404 | Transfer or endpoint not found |
| 409 | Quote already used, or idempotency_key reused with a different body |
| 422 | Invalid data or expired quote |
| 429 | More than 60 requests per minute with the same key |
| 503 | Payout service temporarily unavailable |
{ "ok": false, "message": "Saldo prepago insuficiente." }Transfer statuses: pending, completed and failed. Your balance is debited only when the transfer is accepted; if it fails later, the amount goes back to your balance.
API error messages are returned in Spanish.
Examples
cURL: quote a NatCash transfer (TEST)
curl -s -X POST https://api.levapay.dev/test/v1/transfers/quote \
-H "Content-Type: application/json" \
-H "X-Api-User: YOUR_USER" \
-H "X-Api-Key: YOUR_PRIVATE_KEY" \
-d '{"network":"natcash","wallet":"50940885084","amount_htg":100}'cURL: confirm the transfer
curl -s -X POST https://api.levapay.dev/test/v1/transfers \
-H "Content-Type: application/json" \
-H "X-Api-User: YOUR_USER" \
-H "X-Api-Key: YOUR_PRIVATE_KEY" \
-d '{"quote_id":"qt_...","idempotency_key":"send-001"}'PHP
<?php
$base = 'https://api.levapay.dev/test/v1';
$headers = [
'Content-Type: application/json',
'X-Api-User: YOUR_USER',
'X-Api-Key: YOUR_PRIVATE_KEY',
];
function post(string $url, array $body, array $headers): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => json_encode($body),
]);
return json_decode((string) curl_exec($ch), true);
}
$quote = post("$base/transfers/quote", [
'network' => 'natcash', // or moncash
'wallet' => '50940885084',
'amount_htg' => 100,
], $headers);
$transfer = post("$base/transfers", [
'quote_id' => $quote['data']['quote_id'] ?? '',
'idempotency_key' => 'send-' . uniqid(),
], $headers);
echo $transfer['data']['status'] ?? $transfer['message'];Node.js
const base = 'https://api.levapay.dev/test/v1';
const headers = {
'Content-Type': 'application/json',
'X-Api-User': 'YOUR_USER',
'X-Api-Key': process.env.LEVAPAY_KEY, // YOUR_PRIVATE_KEY
};
const post = (path, body) =>
fetch(base + path, { method: 'POST', headers, body: JSON.stringify(body) })
.then((r) => r.json());
const quote = await post('/transfers/quote', {
network: 'natcash', // or moncash
wallet: '50940885084',
amount_htg: 100,
});
const transfer = await post('/transfers', {
quote_id: quote.data.quote_id,
idempotency_key: `send-${Date.now()}`,
});
console.log(transfer.data?.status ?? transfer.message);Ready to integrate?
Create a free account and get your TEST keys in minutes.