Funding & Reconciliation
End-to-end walkthrough for funding a client and reconciling orders against your own records — create a deposit, check the balance, create a withdrawal, and look up orders by your own reference.
This guide walks you through funding a client with fiat, checking their balance, debiting them with a withdrawal, and reconciling those orders against your own records using partner_order_ref. By the end, you will have a client with a balance you can trade against and a reconciliation pattern you can apply in bulk.
For the concepts behind deposits, withdrawals, balances, and partner_order_ref, see the Funding guide.
What You Will Have at the End
- A client with a funded fiat balance
- Two orders on record — one
deposit, onewithdrawal— each tagged with your ownpartner_order_ref - A working reconciliation pattern: look up any order using your own reference, not CoinMENA's internal ID
Core Rules
Four rules to keep in mind before you run anything.
The balance endpoint and order responses are the source of truthAlways rely on values returned by
GET /v1/partner/balancesand by the order endpoints for reconciliation. Do not recalculate amounts manually from your own system and assume they match — fetch CoinMENA's state and compare.
Funding is synchronous, and balances update on the responseA successful deposit or withdrawal response means the order is
completedand the client'savailable_balancehas already been updated. No polling, no settlement window. Every successful funding operation is fully applied before the response returns.
If a request fails, no balance changes are appliedAny error response (
4xxor5xx) means the operation did not take effect. The client's balance is unchanged and no order was created. Safe to retry — with a newpartner_order_refif the original attempt produced a2020on its second try.
Everypartner_order_refmust be uniqueAcross your entire partner account — deposits, withdrawals, and trades share the same uniqueness namespace. Reusing a value returns
2020(HTTP 409) and the API does not return the existing order. Always generate a fresh reference per order.
Before You Start
You need the following in place before running any of the calls below.
Prerequisites checklist
- You have a verified, active client (
status: verified,active: true). If not, complete the Onboarding a Client walkthrough first - You have your Partner ID and can generate request signatures — see the Authentication guide
- You know the
asset_idof the fiat asset you will deposit and withdraw — fetch fromGET /v1/public/assetsand check thatpublished,depositable, andwithdrawableare alltrue - You have a way to generate unique
partner_order_refvalues per order — use your own internal order IDs or a UUID
Environment and signing
| Item | Details |
|---|---|
| Environment | Production: https://external-api.coinmena.comSandbox: contact [email protected] for credentials |
| Signed headers | All signed requests need X-Partner-ID, X-Timestamp, and X-Signature. See the Authentication guide to generate them |
Placeholders in the cURL examplesReplace
your_partner_idwith your actual Partner ID, and<your_generated_signature>with the Base64 signature you compute per the Authentication guide. Every request below needs its own fresh timestamp and signature.
The Flow at a Glance
- Deposit fiat → client's
available_balanceincreases - Check the balance → confirm the balance reflects the deposit
- Withdraw fiat → client's
available_balancedecreases - Look up an order by your own reference → single-order reconciliation using
partner_order_ref - List orders in a date range → bulk reconciliation and audit pattern
Step 1 — Deposit Fiat
Credit a fiat balance to the client. The amount is a string decimal, greater than zero, with up to 8 decimal places.
curl -X POST "https://external-api.coinmena.com/v1/partner/deposits" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654321000" \
-H "X-Signature: <your_generated_signature>" \
-H "Content-Type: application/json" \
-d '{
"partner_client_id": "user_12345",
"asset_id": "USD",
"amount": "1000.00",
"partner_order_ref": "deposit-abc-123"
}'Response — 200 OK
200 OK{
"result": {
"id": 67890,
"order_no": "MND0000067890",
"partner_client_id": "user_12345",
"type": "deposit",
"source": "bank",
"status": "completed",
"credit": null,
"credit_asset_id": null,
"debit": "1000.00",
"debit_asset_id": "USD",
"fee": "0",
"fee_asset_id": "USD",
"vat": "0",
"partner_order_ref": "deposit-abc-123",
"price": null,
"created_at": "2024-06-01T10:00:00Z",
"transitioned_at": "2024-06-01T10:00:00Z",
"updated_at": "2024-06-01T10:00:00Z"
}
}What to Persist
| Field | Why You Need It |
|---|---|
id | CoinMENA's order ID. Useful as a secondary reference |
partner_order_ref | Your own reference. Primary lookup key for reconciliation |
status | Should be completed. If anything else, log and investigate |
debit | On a deposit, this is the deposited amount. See Reading debit vs credit |
created_at | For audit trails and time-range reconciliation later |
Whydebitholds the deposit amountOn deposits and withdrawals, the
debitandcreditfields reflect CoinMENA's accounting convention, not the client's perspective. Read thetypefield first, then apply the mapping in the Funding guide. For deposits:debitis populated,creditisnull.
Step 2 — Check the Client's Balance
Confirm the deposit updated the client's available_balance. Pass the client's ID as a query parameter to get client-scoped balances.
curl -X GET "https://external-api.coinmena.com/v1/partner/balances?partner_client_id=user_12345" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654322000" \
-H "X-Signature: <your_generated_signature>"Response — 200 OK
200 OK{
"items": [
{
"asset_id": "USD",
"balance": "1000.00",
"available_balance": "1000.00",
"balance_usd": "1000.00",
"available_balance_usd": "1000.00"
}
]
}Check that available_balance on the USD record equals the deposit amount (plus any prior balance). This is the balance you check before calling any trading or withdrawal endpoint.
How Balance Changes Map to Operations
After any successful funding operation, the effect on available_balance is direct:
- After a deposit —
available_balanceincreases by theamountyou submitted - After a withdrawal —
available_balancedecreases by theamountyou submitted - After a
buytrade — quote asset balance decreases, base asset balance increases (see the Trading guide) - After a
selltrade — base asset balance decreases, quote asset balance increases (see the Trading guide)
Parse decimals with a decimal-aware typeBalance and amount fields are strings and may use scientific notation (e.g.
"0E-8"). Never parse them as JavaScriptNumberor Pythonfloat— useDecimalin Python,decimal.jsin JavaScript, or equivalent. Do not apply your own rounding to returned amounts; preserve the precision the API returns.
Do not cache balances for longBalances can change between calls — through your own operations, platform-side adjustments, or other activity on the account. Always fetch a fresh balance immediately before making a financial decision (e.g. before calculating a quote or submitting a withdrawal), rather than relying on a cached value from minutes earlier.
Retrieving a Single Asset Balance
If you only care about one asset, use the per-asset endpoint instead:
curl -X GET "https://external-api.coinmena.com/v1/partner/balances/USD?partner_client_id=user_12345" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654323000" \
-H "X-Signature: <your_generated_signature>"Returns a single balance object in result (not a list).
Step 3 — Withdraw Fiat
Debit fiat from the client. The withdrawal is rejected if available_balance is less than amount.
curl -X POST "https://external-api.coinmena.com/v1/partner/withdrawals" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654324000" \
-H "X-Signature: <your_generated_signature>" \
-H "Content-Type: application/json" \
-d '{
"partner_client_id": "user_12345",
"asset_id": "USD",
"amount": "500.00",
"partner_order_ref": "withdrawal-abc-456"
}'Response — 200 OK
200 OK{
"result": {
"id": 67891,
"order_no": "MNW0000067891",
"partner_client_id": "user_12345",
"type": "withdrawal",
"source": "bank",
"status": "completed",
"credit": "500.00",
"credit_asset_id": "USD",
"debit": null,
"debit_asset_id": null,
"fee": "0",
"fee_asset_id": "USD",
"vat": "0",
"partner_order_ref": "withdrawal-abc-456",
"price": null,
"created_at": "2024-06-01T10:05:00Z",
"transitioned_at": "2024-06-01T10:05:00Z",
"updated_at": "2024-06-01T10:05:00Z"
}
}Reading debit vs credit
On funding orders, the debit / credit semantics are opposite between deposits and withdrawals:
Order type | debit holds | credit holds | Effect on client |
|---|---|---|---|
deposit | The deposited amount | null | Balance increases by debit |
withdrawal | null | The withdrawn amount | Balance decreases by credit |
Always check type first, then read the correct field. See the Orders guide for the full 4-way mapping (including trades).
Running Multiple Operations in Sequence
Funding operations are applied in the order you call them. If you run multiple deposits and withdrawals back to back, each one is fully applied before the response returns. If your logic depends on the current balance (for example, to decide whether a second withdrawal is safe), fetch a fresh balance between operations rather than computing it locally.
Step 4 — Look Up an Order by Your Reference
This is the reconciliation-friendly lookup path. Use the partner_order_ref you tagged at creation — no need to map CoinMENA's internal ID.
curl -X GET "https://external-api.coinmena.com/v1/partner/orders/ref/deposit-abc-123" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654325000" \
-H "X-Signature: <your_generated_signature>"Response — 200 OK
200 OK{
"result": {
"id": 67890,
"order_no": "MND0000067890",
"partner_client_id": "user_12345",
"type": "deposit",
"status": "completed",
"debit": "1000.00",
"debit_asset_id": "USD",
"partner_order_ref": "deposit-abc-123",
"created_at": "2024-06-01T10:00:00Z"
}
}Match the returned fields against your internal record:
status— should becompletedfor a successful funding orderdebit/credit— match against your expected amount (based ontype)partner_order_ref— confirms the echo of your reference
Handling a 409 on creationIf Step 1 or Step 3 returned
2020with HTTP 409 (duplicatepartner_order_ref), the original order already exists. Do not retry with the same reference — callGET /v1/partner/orders/ref/{partner_order_ref}(this step) to fetch the existing order. If itsstatusiscompleted, the original succeeded; iffailedorrejected, retry with a newpartner_order_ref.
Looking Up by CoinMENA's Order ID
If you need to look up an order using CoinMENA's numeric id instead, use:
curl -X GET "https://external-api.coinmena.com/v1/partner/orders/67890" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654326000" \
-H "X-Signature: <your_generated_signature>"Returns the same order object.
Step 5 — Audit Orders in a Date Range
Use order listing to audit every funding operation in a time window and verify that each one matches your expected results. Filter aggressively before paginating — combine partner_client_id, from_datetime, and status to keep result sets small.
curl -X GET "https://external-api.coinmena.com/v1/partner/orders?partner_client_id=user_12345&from_datetime=2024-06-01T00:00:00Z&to_datetime=2024-06-01T23:59:59Z&status=completed&page=1&page_size=100" \
-H "X-Partner-ID: your_partner_id" \
-H "X-Timestamp: 1737654327000" \
-H "X-Signature: <your_generated_signature>"Response — 200 OK
200 OK{
"items": [
{
"id": 67890,
"partner_client_id": "user_12345",
"type": "deposit",
"status": "completed",
"debit": "1000.00",
"debit_asset_id": "USD",
"partner_order_ref": "deposit-abc-123",
"created_at": "2024-06-01T10:00:00Z"
},
{
"id": 67891,
"partner_client_id": "user_12345",
"type": "withdrawal",
"status": "completed",
"credit": "500.00",
"credit_asset_id": "USD",
"partner_order_ref": "withdrawal-abc-456",
"created_at": "2024-06-01T10:05:00Z"
}
],
"total": 2,
"page": 1,
"page_size": 100
}Iterate pages until page >= ceil(total / page_size) or the current page returns fewer than page_size items. See the Pagination guide for the full pattern.
Reconciliation Checklist
For each order in the response:
- Match
partner_order_refagainst your internal record - Confirm
status: completed(or flagfailed/rejectedfor investigation) - Confirm the amount field (
debitorcreditbased ontype) matches your expected value - Flag any orders in CoinMENA's response that are not in your system
- Flag any orders in your system that are not in CoinMENA's response
What Can Go Wrong
The most common errors during funding and reconciliation. A failed funding request never applies any balance change — retry logic can assume the client's state is unchanged on any error response.
| Error | Code | Likely Cause | Fix |
|---|---|---|---|
| Invalid client ID | 2008 | partner_client_id not found under your partner account | Verify the client was onboarded and the reference ID matches |
| Client not yet verified | 2009 | Client status is not verified | Complete onboarding — see the Onboarding a Client guide |
| Client is deactivated | 2010 | Client active is false | Reactivate via PUT /v1/partner/clients/{partner_client_id}/activation |
| Invalid asset | 2012 | Asset is not published, not depositable (for deposits), or not withdrawable (for withdrawals) | Fetch GET /v1/public/assets and pick an asset with all required flags |
Duplicate partner_order_ref | 2020 | You reused a reference value | Fetch the existing order via the ref lookup. Retry with a new reference only if needed |
| Insufficient funds | 3005 | available_balance is less than the withdrawal amount | Check the balance before withdrawing. Deposit more first if needed |
| Order not found | 404 | Wrong order ID or reference, or the order belongs to a different partner | Double-check the reference. A partner cannot retrieve another partner's orders |
| Unauthorized | 401 | Bad signature, expired timestamp, or IP not whitelisted | Work through the Authentication troubleshooting checklist |
For the complete list, see the Error Codes guide.
Updated 1 day ago
| Next Step | Description |
|---|---|
| Executing a Trade | Use the funded balance to run a trade end-to-end |
| Funding | Concept reference for deposits, withdrawals, and balances |
| Orders | Full reference for the order object, statuses, and retrieval |
| Pagination | How to iterate through paginated lists like GET /v1/partner/orders |
