Skip to content

Withdrawals to a bank

Request, follow and cancel moving money from a Gerege Wallet account (a person's or an organisation's) to a real bank account. About 6 minutes to read. You need a person signed in to Gerege App, or an organisation's admin; enough balance on the account; and the real bank account's number.

Why a withdrawal is a «request»

Gerege Wallet's bank code 0098 is not issued by the Bank of Mongolia (it is temporary). So no other bank can send money to a Gerege Wallet IBAN, and Gerege Wallet cannot send straight to another bank. A withdrawal is a request: the amount is held on your account (so it cannot be spent twice), the operator transfers it from its own real bank account to the account you named and records the bank's transaction reference. Top-ups likewise go through the operator's real account.

How it works

  1. You send a request → the amount is held on your account → requested.
  2. The operator takes the request → processing (from this moment it cannot be canceled — the operator is paying it at the real bank).
  3. The operator pays at the real bank and enters the bank's transaction reference → paid, the hold is taken from your account, and bank_reference carries that reference. Or the operator rejects it → rejected, the hold is released back.
  4. You get a «money sent» notification (amount, bank name) or a «returned» one; the reason for a rejection is shown in the app.

Timing: withdrawals are paid out by the operator by hand (in working hours). A service-level commitment (SLA) is to be announced.

Sending a request

Who Path
A person, their own active MNT account POST /api/v1/bank/me/accounts/{id}/withdrawals
An organisation's admin POST /api/v1/bank/org/{tenant}/accounts/{id}/withdrawals
curl -sS https://geregeapp.mn/api/v1/bank/me/accounts/$ACCOUNT_ID/withdrawals \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Idempotency-Key: wd-2026-10-27-0001" \
  -H "Content-Type: application/json" \
  -d '{"amount": 250000, "bank_name": "Khan Bank", "bank_account": "5012345678", "holder_name": "Alisa Bat"}'
Field Rule
amount 1 000 – 50 000 000 ₮, whole; at most the account's available balance
bank_name 2 – 100 characters
bank_account an MN IBAN or a number of 5 – 20 digits (spaces and dashes removed). A Gerege Wallet (0098) IBAN is use_transfer — send a transfer instead
holder_name 2 – 100 characters, the holder of the receiving account
  • Idempotency-Key is required, 8 – 128 characters. The same key with the same body → that request (200); another body → 409 idempotency_conflict. If the connection drops (the request may stay pending), send it again with the same key.
  • One owner may have at most 3 open requests (waiting, up to processing) at a time.
  • Rate limit — 6 a minute.
  • SMS confirmation: above a threshold the operator sets, the first answer is 428 confirmation_required {challenge_id, phone (masked), expires_at} and a code goes to your verified phone. Send the same request (same body, same Idempotency-Key) again with the headers X-Confirmation-Id: <challenge_id> and X-Confirmation-Code: <code>. The code is bound to this account, amount, receiving account and key — it does nothing for another withdrawal. For an organisation's withdrawal the code goes to the admin's own number.

The answer 201 (new) is the withdrawal, requested.

The withdrawal object

{
  "id": "4c1f…",
  "account_id": "…",
  "account_number": "0980000017",
  "amount": 250000,
  "currency": "MNT",
  "status": "requested",
  "destination": {"bank_name": "Khan Bank", "bank_account": "5012345678", "holder_name": "Alisa Bat"},
  "bank_reference": null,
  "failure_code": null,
  "reject_reason": null,
  "cancelable": true,
  "created_at": "…", "updated_at": "…",
  "processing_at": null, "paid_at": null, "rejected_at": null, "canceled_at": null
}
status Meaning Cancel
pending the hold's outcome is not known — send again with the same Idempotency-Key; the platform looks for it after 5 minutes and, if not found within an hour, marks it failed (nothing held) yes
requested the amount is held, waiting for the operator yes
processing the operator took it and is paying it at the real bank no
paid paid; bank_reference = the bank's transaction reference —
rejected the operator rejected it (reject_reason), the hold released —
canceled you canceled it, the hold released —
failed no hold could be placed (failure_code: for example insufficient_funds, account_frozen, hold_not_placed) —

Listing, reading, canceling

Method Path (a person; for an organisation /api/v1/bank/org/{tenant}/…) Answer
GET /api/v1/bank/me/accounts/{id}/withdrawals?limit=&before= {"data": [Withdrawal], "next_before": time \| null} — newest first, limit default 50, ≤ 100; for the next page before=<next_before>
GET /api/v1/bank/me/accounts/{id}/withdrawals/{wid} Withdrawal / 404
POST /api/v1/bank/me/accounts/{id}/withdrawals/{wid}/cancel while pending / requested 200 (canceled, the hold released); already canceled 200; anything else → 409 not_cancelable {status}

An organisation's requests and cancellations are written to the organisation's audit log. In Gerege App (iOS): a person uses Wallet → «Withdraw to a bank»; an organisation's admin Settings → Wallet → «Organisation account» (open the account, balance, transactions, withdraw). Sending a request, following it and cancelling it before the operator starts are all in the app.

Errors

HTTP code When
400 — Idempotency-Key missing or not 8 – 128
400 invalid_amount not 1 000 – 50 000 000
400 invalid_bank_name · invalid_holder_name not 2 – 100 characters
400 invalid_bank_account not an MN IBAN or 5 – 20 digits
400 use_transfer a Gerege Wallet (0098) account — a transfer, not a withdrawal
403 — not an admin, on an organisation's route
404 — the account is not yours / no such withdrawal
409 idempotency_conflict the key was used for another request
409 too_many_open 3 open requests already (open)
409 not_cancelable processing or finished (status)
422 account_unavailable money cannot leave the account now (inactive, not MNT)
422 insufficient_funds the available balance is not enough (nothing is recorded)
428 confirmation_required confirm with the SMS code (above)
400 · 403 · 410 · 429 · 502 · 503 wrong_code (attempts_left), confirmation_invalid, phone_required, code_expired, too_many_codes, sms_failed, sms_unavailable SMS confirmation errors
503 withdrawals_unavailable withdrawals are not enabled on this installation
503 license_required the ledger is temporarily read-only