Skip to content

Wallet

Wallet balance, transactions and top-ups.

POST /billing/topup-quote

Prices a wallet top-up before checkout: the exact subtotal, processing fee, tax and total the card will be charged, and the USD that will land in the wallet. Returns a signed quote valid for 10 minutes that POST /payments/create-order requires. The key’s owner must be OWNER or ADMIN, and a billing country must be set first. Pay-as-you-go organisations only: an organisation on plan billing (billingModel WALLET) gets 409 and adds money with POST /billing/topups instead.

Scope: wallet:write

Body (application/json)

Field Type Required Description
organisationId string yes Your organisation ID. Must be the key’s own organisation.
amount number yes Wallet credit wanted, in major units of the organisation’s checkout currency (for example 5000 means INR 5,000 for an India-billed organisation, 100 means USD 100 for a US one).
currency string no Optional. If sent it must equal the checkout currency for the billing country, otherwise 400.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/billing/topup-quote" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"organisationId":"cmf3k2j9x0001abcd1234efgh","amount":5000,"currency":"INR"}'

Response 200

{
"success": true,
"data": {
"gateway": "razorpay",
"walletCredit": {
"amount": 5000,
"currency": "INR"
},
"walletCreditUsd": 56.74,
"subtotal": {
"amount": 5000,
"currency": "INR"
},
"platformFee": {
"amount": 100,
"currency": "INR"
},
"platformFeeLabel": "Payment processing fee",
"tax": {
"amount": 918,
"currency": "INR"
},
"taxLabel": "GST 18%",
"total": {
"amount": 6018,
"currency": "INR"
},
"chargeCurrency": "INR",
"fx": null,
"rate": 1,
"quoteId": "<opaque signed quote token>",
"expiresAt": "2026-09-20T10:25:30.000Z",
"minimumTopUp": {
"amountUsd": 50,
"meetsMinimum": true
}
}
}

Errors

Code When
400 organisationId missing, amount not a positive number, billing country not set, or currency does not match the billing country
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:write scope, foreign organisation, or the key’s owner is not OWNER/ADMIN
404 Organisation not found
409 The organisation is on plan billing; use POST /billing/topups
429 Rate limited
502 A live exchange rate or processor price preview could not be obtained
503 Card payments are unavailable or misconfigured for this organisation

GET /wallet/{organisationId}

Returns the organisation’s pay-as-you-go wallet balance in USD. For local-currency display use displayCurrency and fxRate from GET /billing/status. For an organisation on plan billing (billingModel WALLET) this balance is not the money it spends and currency reports the plan wallet’s currency; read GET /billing/balance instead. An organisation whose AI calls are paid from a Muncho restaurant wallet gets that wallet (rupees, walletProvider muncho). Any member role may read it.

Scope: wallet:read

Parameters

Name In Type Required Description
organisationId path string yes Your organisation ID. Must be the API key’s own organisation.

Example request

Terminal window
curl -X GET "https://api.foan.ai/api/v1/wallet/{organisationId}" \
-H "Authorization: Bearer $FOAN_API_KEY"

Response 200

{
"success": true,
"data": {
"balance": 42.5,
"currency": "USD",
"hasPaid": true
}
}

Errors

Code When
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:read scope, foreign organisation, or the key’s owner is not a member
404 No wallet exists for this organisation yet
429 Rate limited
503 Only for an organisation whose AI calls are paid from a Muncho restaurant wallet: that wallet could not be reached, or is being switched over; retry in a minute

GET /wallet/{organisationId}/transactions

Lists wallet ledger entries (top-ups, call and message charges, number rental, plan allowances, adjustments), newest first, with filters and pagination. Pay-as-you-go entries are in USD (amount, balanceAfter). Plan-billing entries carry unit MINOR with the real money in amountMinor and balanceMinorAfter (minor units of currency: paise for INR, cents for USD) and show 0 in the USD fields. For an organisation whose AI calls are paid from a Muncho restaurant wallet, the last 50 lines of that wallet are listed instead, in rupees. Any member role may read it.

Scope: wallet:read

Parameters

Name In Type Required Description
organisationId path string yes Your organisation ID. Must be the API key’s own organisation.
type query string: CREDIT, DEBIT, REFUND, ADJUSTMENT no Filter by transaction type.
startDate query string no Only entries created at or after this time.
endDate query string no Only entries created at or before this time.
page query integer no Page number.
limit query integer no Page size (clamped to 1..100).

Example request

Terminal window
curl -X GET "https://api.foan.ai/api/v1/wallet/{organisationId}/transactions" \
-H "Authorization: Bearer $FOAN_API_KEY"

Response 200

{
"success": true,
"data": {
"transactions": [
{
"id": "cmf3k2j9x0009abcd1234efgh",
"type": "DEBIT",
"amount": 0.095,
"balanceAfter": 42.5,
"referenceType": "VOICE_CALL",
"referenceId": "cmf3k2j9x0010abcd1234efgh",
"description": "Call cost for call-7f3a9c2e",
"createdAt": "2026-09-20T09:01:36.000Z"
},
{
"id": "cmf3k2j9x0012abcd1234efgh",
"type": "CREDIT",
"amount": 56.74,
"balanceAfter": 42.595,
"referenceType": "TOP_UP",
"referenceId": "cmf3k2j9x0008abcd1234efgh",
"description": "Wallet top-up",
"createdAt": "2026-09-18T12:00:00.000Z"
},
{
"id": "cmg2txn0000a1b2c3d4e5f6g7",
"type": "DEBIT",
"amount": 0,
"balanceAfter": 0,
"unit": "MINOR",
"currency": "INR",
"amountMinor": -750,
"balanceMinorAfter": 411600.5,
"referenceType": "VOICE_CALL",
"referenceId": "cmg2use0000a1b2c3d4e5f6g7",
"description": "Call call-9b1d4f7a",
"createdAt": "2026-10-04T11:20:05.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 3,
"totalPages": 1
}
}
}

Errors

Code When
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:read scope, foreign organisation, or the key’s owner is not a member
429 Rate limited
500 An invalid type value or unparseable date is not validated and fails as a server error
503 Only for an organisation whose AI calls are paid from a Muncho restaurant wallet: that wallet could not be reached, or is being switched over; retry in a minute

GET /wallet/{organisationId}/check-balance

Answers whether the pay-as-you-go USD wallet balance is at least the given amount. It does not look at the plan wallet: for an organisation on plan billing use GET /billing/balance. For an organisation whose AI calls are paid from a Muncho restaurant wallet the amount is compared with that wallet in rupees. Returns hasEnoughBalance false when no wallet exists. Any member role may call it.

Scope: wallet:read

Parameters

Name In Type Required Description
organisationId path string yes Your organisation ID. Must be the API key’s own organisation.
amount query number yes Amount to compare against the balance, in USD (rupees for a Muncho wallet).

Example request

Terminal window
curl -X GET "https://api.foan.ai/api/v1/wallet/{organisationId}/check-balance" \
-H "Authorization: Bearer $FOAN_API_KEY"

Response 200

{
"success": true,
"data": {
"hasEnoughBalance": true,
"requiredAmount": 10
}
}

Errors

Code When
400 amount missing
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:read scope, foreign organisation, or the key’s owner is not a member
429 Rate limited
503 Only for an organisation whose AI calls are paid from a Muncho restaurant wallet: that wallet could not be reached, or is being switched over; retry in a minute

POST /payments/create-order

Creates a pending top-up payment from a quote obtained from POST /billing/topup-quote and returns a hosted checkout URL to hand to a person to pay. The wallet is credited in USD only after our payment processor confirms the payment. The key’s owner must be OWNER or ADMIN. Each quote can be used once. Rate limited (30 requests per minute by default). Pay-as-you-go organisations only: an organisation on plan billing (billingModel WALLET) gets 409 and adds money with POST /billing/topups instead.

Scope: wallet:write

Body (application/json)

Field Type Required Description
organisationId string yes Your organisation ID. Must be the key’s own organisation and the organisation the quote was issued for.
amount number yes Must equal walletCredit.amount from the quote exactly.
currency string no Optional. If sent must equal the organisation’s checkout currency.
expectedTotal object yes Echo of the quote the payer was shown. Every value must match the signed quote.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/payments/create-order" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"organisationId":"cmf3k2j9x0001abcd1234efgh","amount":5000,"currency":"INR","expectedTotal":{"amount":6018,"currency":"INR","walletCreditUsd":56.74,"quoteId":"<opaque signed quote token>"}}'

Response 201

{
"success": true,
"message": "Order created successfully",
"data": {
"paymentId": "cmf3k2j9x0008abcd1234efgh",
"gateway": "razorpay",
"checkoutUrl": "https://api.foan.ai/pay/cmf3k2j9x0008abcd1234efgh?t=<signed pay token>",
"razorpayOrderId": "<processor order id>",
"razorpayKeyId": "<publishable checkout key>",
"razorpayAmount": 601800,
"razorpayCurrency": "INR",
"razorpayCustomerId": "<processor customer id>",
"razorpayPrefillContact": "+919876543210"
}
}

Errors

Code When
400 organisationId or amount missing, missing or malformed expectedTotal, quote invalid/expired/edited or issued to another organisation, amount below the minimum top-up, currency mismatch, billing country not set, or invalid GSTIN on file
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:write scope, foreign organisation, or the key’s owner is not OWNER/ADMIN
404 Organisation or user not found
409 The organisation is on plan billing (use POST /billing/topups), the total changed since the quote (re-quote), the quote was already used, or the billing country changed during pricing
429 Rate limited
502 Could not price the checkout (exchange rate or processor preview unavailable)
503 Card payments unavailable or misconfigured for this organisation

POST /billing/topups

Creates a one-off payment link that adds money to the plan wallet (organisations on plan billing, billingModel WALLET; pay-as-you-go organisations use POST /billing/topup-quote and POST /payments/create-order instead). amountMinor is the money to add, in minor units of the wallet currency: paise in India, US cents elsewhere. India: the payer is charged amountMinor plus 18% GST (chargeMinor), and the organisation’s invoice details must be on file (set on the dashboard Billing page). Elsewhere: chargeMinor equals amountMinor in USD cents and the processor adds any local tax at checkout, possibly in the payer’s local currency. Nothing is charged by this call; the money is added when the payment reaches us and stays spendable for 365 days. With a paid plan it is spent at the plan’s prices; without one at Starter prices. The minimum is the smallest of the plan’s topUpPresets (Rs 1,000 or USD 10 on the current plans). The key’s owner must be OWNER or ADMIN.

Scope: wallet:write

Body (application/json)

Field Type Required Description
organisationId string no Optional. Defaults to the API key’s own organisation; if sent it must be that organisation, otherwise 403.
amountMinor integer yes Money to add before tax, whole minor units (paise or cents).
returnUrl string no Outside India only. Where the payer is sent after paying. Must be on the Foan dashboard; any other address is replaced with the dashboard Billing page.

Example request

Terminal window
curl -X POST "https://api.foan.ai/api/v1/billing/topups" \
-H "Authorization: Bearer $FOAN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amountMinor":500000}'

Response 201

{
"success": true,
"data": {
"rail": "RAZORPAY",
"amountMinor": 500000,
"currency": "INR",
"chargeMinor": 590000,
"checkoutUrl": "https://rzp.io/rzp/YzAbCd90",
"reference": "plink_Qw2eR3tY4uI5o6"
}
}

Errors

Code When
400 amountMinor missing, not a positive whole number, or below the minimum top-up; no billing country; the billing country is not one we can bill in; or the processor rejected the details (outside India)
401 Missing, invalid or revoked API key, or the key’s owner is deactivated or no longer in the organisation
403 Missing wallet:write scope, organisationId is not the key’s own organisation, or the key’s owner is not OWNER/ADMIN
404 Organisation not found
409 The organisation is on the earlier pay-as-you-go billing, top-ups are not on sale in its currency, or (India) invoice details are missing or invalid
429 Rate limited
500 Top-ups are not configured on this server
502 Our payment processor refused the request or did not respond. Nothing was charged.