Finmo partner API, sandbox for Zenith

Same shapes as api.finmo.net: one master account API for onboarding, balances, FX, payouts and webhooks across every Zenith sub account. Anything Finmo doesn't have today is marked proposed and is a working name for discussion. sandbox-only marks test helpers. confirm marks names to confirm with product.

Base URL
https://sandbox.finmotreasury.net/v1
Auth
HTTP Basic: base64(access_key:secret_key). Keys are issued by Finmo over a secure channel.
Act for a merchant
x-on-behalf-of: <sub account org_id> on wallet, VA, FX, beneficiary, payout and transaction calls.
Idempotency
X-Idempotency-Key (UUID v4) on every POST. Same key + same body replays the original response with x-cached-request-id. Same key + different body: 409 (100010). Kept 8 days.
Pagination
limit (max 100) and page on list endpoints. data is a plain array.
Envelope
{ request_id, request_time, success, status_code, status_text, data | error }. Amounts are JSON numbers; timestamps ISO 8601 UTC.

The flow (12 calls)

  1. 1POST /partner/invite-organization with ABN + city: sub account, balances, AUD account details
  2. 2PUT /partner/organization-setting/{org_id}: webhook_url
  3. 3Webhook ORGANIZATION_KYB_APPROVED (or poll GET /partner/organization/{org_id})
  4. 4Zenith settles AUD to the sub account (sandbox: PATCH /virtual-account/simulate-payin)
  5. 5GET /wallet/{wallet_id}: available balance
  6. 6GET /payout-method/all + /payout-method/param/{name}: build the supplier form
  7. 7POST /payout-beneficiary/validate, then POST /payout-beneficiary
  8. 8POST /fx-rate: quote held ~20 s, includes Zenith's plan markup
  9. 9POST /payout with fx_rate_id: funds reserved, PAYOUT_CREATED
  10. 10PAYOUT_COMPLETED / FAILED / RETURNED webhooks; GET /payout/{id}
  11. 11GET /payout/{id}/get-payout-pdf: payment confirmation
  12. 12GET /transaction: reconciliation with fees

Onboarding

POST/v1/partner/invite-organizationlive

Create sub account

Opens a sub account for one Zenith merchant. With an ABN (or ACN) and city, Finmo pulls the company record from its KYB data provider, screens it and approves it by reliance on Zenith's onboarding. The response already carries the sub account's balances and AUD account details.

FieldTypeDescription
first_name*stringMerchant contact first name
last_name*stringMerchant contact last name
org_name*stringBusiness name as Zenith holds it
org_country*stringISO 3166-1 alpha-2, e.g. AU
email*stringMerchant contact email (Finmo never contacts the merchant)
abnstring11-digit ABN. Triggers the registry pull. Spaces allowed proposed
acnstring9-digit ACN, alternative to abn proposed
address_citystringRequired with abn/acn. The KYB data provider matches on registration number + city proposed
address_statestringNSW, VIC, QLD, WA, SA, TAS, ACT, NT proposed
address_zip_codestringPostcode proposed
organization_reference_idstringZenith's own merchant id, echoed on webhooks proposed
webhook_urlstringSet the webhook URL in the same call proposed
webhook_security_tokenstringSent back in the x-security-token header proposed
gca_plan_idstringPricing plan (Zenith markup). Defaults to the partner's default plan proposed
  • Without abn/acn the call behaves exactly like api.finmo.net today: kyb.status NOT_STARTED, no balances, no account details. Use PATCH /v1/partner/kyb/save to send full KYB.
  • kyb.status keeps the live enum (NOT_STARTED, STARTED, SUBMITTED, APPROVED, REJECTED). kyb.stage and kyb.action_required are proposed.
  • The AUD account details are returned straight away and become active on approval (ORGANIZATION_KYB_APPROVED, then VA_CREATED).
Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/partner/invite-organization' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"first_name":"Priya","last_name":"Nair","org_name":"Coral Coast Getaways Pty Ltd","org_country":"AU","email":"priya@coralcoastgetaways.example","abn":"46944446235","address_city":"Cairns","address_state":"QLD","address_zip_code":"4870","organization_reference_id":"TPB2B-000417"}'
GET/v1/partner/organizationlive

List sub accounts

Every sub account under the master account with its KYB status. Poll this if you don't use webhooks.

FieldTypeDescription
kyb_statusstringNOT_STARTED, STARTED, SUBMITTED, APPROVED, REJECTED
limitnumber
pagenumber
Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/partner/organization' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
GET/v1/partner/organization/:org_idlive

Get sub account

Full profile: the company record Finmo pulled, business owners and their screening status, the KYB timeline, balances and account details.

  • kyb.checks, wallets and virtual_accounts blocks are proposed additions.
Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/partner/organization/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
PATCH/v1/partner/kyb/save/:org_idlive

Send KYB details (fallback)

Fallback path. Use it to answer kyb.action_required (a possible screening match or an incomplete registry record) with details Zenith already holds, or to submit full KYB for a non-AU merchant.

FieldTypeDescription
submitbooleantrue submits the application for review
legal_namestring
company_registration_numberstring
incorporation_datestring
address_line1string
business_owner[]arrayInclude business_owner_id to update an owner Finmo already holds (e.g. add dob + identification_document_id to clear a screening match)
Request
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/partner/kyb/save/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'content-type: application/json' \
  -d '{"business_owner":[{"business_owner_id":"{{business_owner_id}}","dob":"1979-02-21","identification_type":"PASSPORT","identification_value":"PA1234567","identification_document_id":"{{org_document_id}}"}]}'
POST/v1/partner/organization-document/:org_idlive

Request a document upload URL

Two-step upload: this returns org_document_id + upload_url (valid 30 seconds); PUT the file bytes to upload_url.

FieldTypeDescription
file_type*stringimage/png, image/jpeg, image/jpg, application/pdf
doc_type*stringKYB_DOCUMENT
Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/partner/organization-document/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"file_type":"application/pdf","doc_type":"KYB_DOCUMENT"}'

Balances

GET/v1/walletlivex-on-behalf-of

List wallets

Wallet ids for the sub account. One multi-currency wallet (category GCA) per sub account. Header x-on-behalf-of: <sub account org_id>.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/wallet' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "41d73a0f2951e1541a6552e59501db4c",
  "request_time": "2026-10-24T16:47:58.239Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
      "wallet_alias": "w_alias_7e3cdfedf91b49679100e4f2f5b7b01b",
      "org_id": "org_74092bcb151140d38f055086b60fdf62",
      "category": "GCA",
      "scope": "MASTER",
      "customer_id": null,
      "description": null,
      "metadata": null,
      "is_active": true,
      "is_deleted": false,
      "webhook_url": null,
      "created_at": "2026-10-06T06:42:25.376Z",
      "updated_at": "2026-10-06T06:42:25.376Z",
      "deleted_at": null
    }
  ]
}
GET/v1/wallet/:wallet_idlivex-on-behalf-of

Get wallet balances

wallet_account[] carries actual_balance and available_balance per currency. Available drops when a payout is created (funds reserved); actual drops when it completes.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/wallet/:wallet_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "2f202cbcefc9573a0b2cdf49d3844336",
  "request_time": "2026-10-24T16:47:59.999Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": {
    "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
    "wallet_alias": "w_alias_7e3cdfedf91b49679100e4f2f5b7b01b",
    "org_id": "org_74092bcb151140d38f055086b60fdf62",
    "category": "GCA",
    "scope": "MASTER",
    "customer_id": null,
    "description": null,
    "metadata": null,
    "is_active": true,
    "is_deleted": false,
    "webhook_url": null,
    "created_by": null,
    "created_at": "2026-10-06T06:42:25.376Z",
    "updated_at": "2026-10-06T06:42:25.376Z",
    "deleted_at": null,
    "wallet_account": [
      {
        "wallet_account_id": "w_acc_4de2b95bdbef48cba46c4359ba3bd27c",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "AED",
        "actual_balance": 3455.93,
        "available_balance": 3455.93,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.488Z",
        "updated_at": "2026-10-07T09:28:04.838Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_59365f00fd2246abbe1764e550ec2c6d",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "AUD",
        "actual_balance": 26258.77,
        "available_balance": 26258.77,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.702Z",
        "updated_at": "2026-10-07T11:49:47.288Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_ee3daf29d7684df090b628509791781f",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "EUR",
        "actual_balance": 3023.93,
        "available_balance": 3023.93,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.504Z",
        "updated_at": "2026-10-07T11:51:44.622Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_cf7ac2159516452b8dc8cd6a0545bc39",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "GBP",
        "actual_balance": 1775.97,
        "available_balance": 1775.97,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.565Z",
        "updated_at": "2026-10-07T07:20:08.060Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_2ea039509c2847e4b3a18ac2919d9f44",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "HKD",
        "actual_balance": 5837.98,
        "available_balance": 5837.98,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.604Z",
        "updated_at": "2026-10-07T09:28:18.910Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_d1ab12a08a96474d8196a171ce0a078f",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "IDR",
        "actual_balance": 3723930,
        "available_balance": 3723930,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-07T06:44:53.133Z",
        "updated_at": "2026-10-07T07:16:40.535Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_aff66a22faf5436e8b19b95d0eaca876",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "MYR",
        "actual_balance": 4027.41,
        "available_balance": 4027.41,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-07T06:45:04.059Z",
        "updated_at": "2026-10-07T07:04:55.924Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_7057f57156684e8ca5fe333ce68c19bb",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "NZD",
        "actual_balance": 4103.56,
        "available_balance": 4103.56,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.680Z",
        "updated_at": "2026-10-07T07:37:09.841Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_726b92c8711c4086b1ffea3357d9e1fe",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "PHP",
        "actual_balance": 218555,
        "available_balance": 218555,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-07T06:47:59.057Z",
        "updated_at": "2026-10-07T09:55:38.373Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_787fd687b9534704b36180c4ece3bfee",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "SGD",
        "actual_balance": 1728.763,
        "available_balance": 1648.433,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.396Z",
        "updated_at": "2026-10-07T09:56:38.607Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_4ae49c27c00f4f0b95450208c900cd61",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "THB",
        "actual_balance": 1823.58,
        "available_balance": 1823.58,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-07T06:51:55.781Z",
        "updated_at": "2026-10-07T09:28:28.973Z",
        "deleted_at": null
      },
      {
        "wallet_account_id": "w_acc_b6ed102c6ab342379b8ac78c7799ec72",
        "wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "currency": "USD",
        "actual_balance": 11000.39,
        "available_balance": 11000.39,
        "is_active": true,
        "is_settlement_allowed": true,
        "is_deleted": false,
        "created_at": "2026-10-06T06:42:25.586Z",
        "updated_at": "2026-10-07T09:28:57.495Z",
        "deleted_at": null
      }
    ],
    "total_balance_in_usd": 45086.179078378
  }
}
GET/v1/balancelivex-on-behalf-of

Balances by currency

Currency map of actual and available balance for the sub account.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/balance' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "b380020b10e4567824cb06cf49e89b66",
  "request_time": "2026-10-24T16:48:01.390Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": {
    "HKD": {
      "wallet_id": null,
      "actual_balance": 5837.98,
      "available_balance": 5837.98
    },
    "THB": {
      "wallet_id": null,
      "actual_balance": 1823.58,
      "available_balance": 1823.58
    },
    "AED": {
      "wallet_id": null,
      "actual_balance": 3455.93,
      "available_balance": 3455.93
    },
    "AUD": {
      "wallet_id": null,
      "actual_balance": 26258.77,
      "available_balance": 26258.77
    },
    "NZD": {
      "wallet_id": null,
      "actual_balance": 4103.56,
      "available_balance": 4103.56
    },
    "PHP": {
      "wallet_id": null,
      "actual_balance": 218555,
      "available_balance": 218555
    },
    "SGD": {
      "wallet_id": null,
      "actual_balance": 1728.76,
      "available_balance": 1648.43
    },
    "MYR": {
      "wallet_id": null,
      "actual_balance": 4027.41,
      "available_balance": 4027.41
    },
    "USD": {
      "wallet_id": null,
      "actual_balance": 11000.39,
      "available_balance": 11000.39
    },
    "GBP": {
      "wallet_id": null,
      "actual_balance": 1775.97,
      "available_balance": 1775.97
    },
    "IDR": {
      "wallet_id": null,
      "actual_balance": 3723930,
      "available_balance": 3723930
    },
    "EUR": {
      "wallet_id": null,
      "actual_balance": 3023.93,
      "available_balance": 3023.93
    }
  }
}
GET/v1/transactionlivex-on-behalf-of

Transactions (reconciliation)

One record per money movement with fees, net amount and settlement flags.

FieldTypeDescription
event_typestringPAYOUT, VIRTUAL_ACCOUNT
currencystring
start_timestring
end_timestring
limitnumber
pagenumber
Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/transaction' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "204c6e84b50890e17cce5bd3c7c2281c",
  "request_time": "2026-10-24T16:48:49.435Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "transaction_id": "txn_aa03c7d5f1684a668d30197d79706d36",
      "org_id": "org_74092bcb151140d38f055086b60fdf62",
      "amount": 80.88,
      "fees_currency": "AUD",
      "fees_without_tax": 43.16,
      "tax_on_fees": null,
      "fees_including_tax": 43.16,
      "net_amount": -124.04,
      "currency": "AUD",
      "event_id": "payout_25e62509ff414232a596d0a627ffd42e",
      "event_type": "PAYOUT",
      "event_name": "PAYOUT_COMPLETED",
      "event_description": "PAYOUT",
      "scope": "MASTER",
      "customer_id": null,
      "invoice_id": null,
      "is_settled": false,
      "settlement_id": null,
      "is_reconciled": true,
      "additional_data": null,
      "created_at": "2026-10-24T16:48:31.514Z",
      "updated_at": "2026-10-24T16:48:32.318Z",
      "is_splitted": false,
      "event_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
      "fees_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
      "event_wallet_id_list": null,
      "org_name": "Express Travel Group"
    }
  ]
}
GET/v1/transaction/:txn_idlivex-on-behalf-of

Get transaction

One transaction.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/transaction/:txn_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'

Funding

GET/v1/virtual-accountlivex-on-behalf-of

List AUD account details

The sub account's AUD virtual account (BSB + account number). Zenith settles AUD here.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/virtual-account' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "935c53d20eac8b3370c86ddac884fd6d",
  "request_time": "2026-10-24T16:48:02.561Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "virtual_account_id": "va_3ca51c183c2244499245590f60a4fc46",
      "org_id": "org_74092bcb151140d38f055086b60fdf62",
      "scope": "MASTER",
      "category": "GCA",
      "customer_id": null,
      "credit_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
      "description": null,
      "metadata": null,
      "is_active": true,
      "currency": "AUD",
      "payin_method_name": "crossborder_bank_acct",
      "payin_method_param": null,
      "pay_code": {},
      "transaction_id": null,
      "is_deleted": false,
      "is_expired": false,
      "is_refundable": false,
      "fees_without_tax": null,
      "tax_on_fees": null,
      "fees_including_tax": null,
      "fees_currency": null,
      "is_fees_charged": false,
      "is_chargeable": true,
      "is_cancellable": false,
      "organization_reference_id": null,
      "webhook_url": null,
      "created_at": "2026-10-07T07:35:59.476Z",
      "updated_at": "2026-10-07T07:35:59.476Z",
      "expire_at": null,
      "expired_at": null,
      "deleted_at": null,
      "is_sender_validation_enabled": false,
      "payin_sender_id_list": null
    }
  ]
}
GET/v1/virtual-account/:va_idlivex-on-behalf-of

Get account details

One virtual account.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/virtual-account/:va_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'

FX & payouts

GET/v1/payout-method/alllivex-on-behalf-of

Payout methods for a corridor

Rails available to a destination. beneficiary_country and beneficiary_currency are required.

FieldTypeDescription
beneficiary_country*string
beneficiary_currency*string
  • sandbox_fee and estimated_delivery are proposed additions.
Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-method/all' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "38746db057525bd3a33ec398906e2ec8",
  "request_time": "2026-10-24T16:48:06.718Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "payout_method_id": "pom_5279e1c6854e476abd4f8be4537462cf",
      "payout_method_name": "id_bank_skn_idr",
      "payout_method_description": "Indonesia bank payout (NATIONAL CLEARING SYSTEM [SKN])",
      "payout_method_logo": "https://finmo-assets.s3.ap-southeast-2.amazonaws.com/Finmo_logo_full_color.png",
      "sender_country": "*",
      "sender_currency": "*",
      "beneficiary_country": "ID",
      "beneficiary_currency": "IDR",
      "payout_method_category": "BANK",
      "payout_method_class": "GCA",
      "payout_method_group": "NO_GROUP",
      "payout_beneficiary_param": {
        "company": [
          {
            "name": "address_city",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_line1",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_country",
            "type": "text",
            "regex": "^[A-z]{2}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "must be a valid ISO 3166-1 alpha-2 code"
          },
          {
            "name": "name",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "registration_number",
            "type": "text",
            "regex": "^[0-9A-Z]{1,20}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts uppercase characters and digits [length: 1 to 20]"
          }
        ],
        "base_param": [
          {
            "name": "account_number",
            "type": "text",
            "regex": "^\\d{1,16}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts digits [length: 1 to 16]"
          },
          {
            "name": "bic_swift",
            "type": "text",
            "regex": "^[0-9A-Z]{8}$|^[0-9A-Z]{11}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts uppercase characters and digits [length: 8 or 11]"
          }
        ],
        "individual": [
          {
            "name": "address_line1",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_city",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_country",
            "type": "text",
            "regex": "^[A-z]{2}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "must be a valid ISO 3166-1 alpha-2 code"
          },
          {
            "name": "first_name",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "last_name",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_state",
            "type": "text",
            "regex": "^.{1,255}",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
          },
          {
            "name": "address_zip_code",
            "type": "text",
            "regex": "^.{1,12}$",
            "mandatory": true,
            "field_description": "",
            "regex_description": "accepts alphanumeric characters [length: 1 to 12]"
          }
        ]
      },
      "min_amount": 1,
      "max_amount": 10000000,
      "is_returnable": true,
      "is_enabled": true
    }
  ]
}
GET/v1/payout-method/param/:namelivex-on-behalf-of

Fields a method needs

payout_beneficiary_param lists base_param (bank fields), company and individual fields with regex. Build the 'add supplier' form from this.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-method/param/:name' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "be09a5ba207ba319edf876e7fa52006f",
  "request_time": "2026-10-24T16:48:08.158Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": {
    "payout_method_id": "pom_5279e1c6854e476abd4f8be4537462cf",
    "payout_method_name": "id_bank_skn_idr",
    "payout_method_description": "Indonesia bank payout (NATIONAL CLEARING SYSTEM [SKN])",
    "payout_method_logo": "https://finmo-assets.s3.ap-southeast-2.amazonaws.com/Finmo_logo_full_color.png",
    "currency": "IDR",
    "sender_country": "*",
    "sender_currency": "*",
    "beneficiary_country": "ID",
    "beneficiary_currency": "IDR",
    "payout_method_category": "BANK",
    "payout_method_class": "GCA",
    "payout_method_group": "NO_GROUP",
    "payout_method_param": {},
    "payout_beneficiary_param": {
      "company": [
        {
          "name": "address_city",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_line1",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_country",
          "type": "text",
          "regex": "^[A-z]{2}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "must be a valid ISO 3166-1 alpha-2 code"
        },
        {
          "name": "name",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "registration_number",
          "type": "text",
          "regex": "^[0-9A-Z]{1,20}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts uppercase characters and digits [length: 1 to 20]"
        }
      ],
      "base_param": [
        {
          "name": "account_number",
          "type": "text",
          "regex": "^\\d{1,16}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts digits [length: 1 to 16]"
        },
        {
          "name": "bic_swift",
          "type": "text",
          "regex": "^[0-9A-Z]{8}$|^[0-9A-Z]{11}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts uppercase characters and digits [length: 8 or 11]"
        }
      ],
      "individual": [
        {
          "name": "address_line1",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_city",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_country",
          "type": "text",
          "regex": "^[A-z]{2}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "must be a valid ISO 3166-1 alpha-2 code"
        },
        {
          "name": "first_name",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "last_name",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_state",
          "type": "text",
          "regex": "^.{1,255}",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 255]"
        },
        {
          "name": "address_zip_code",
          "type": "text",
          "regex": "^.{1,12}$",
          "mandatory": true,
          "field_description": "",
          "regex_description": "accepts alphanumeric characters [length: 1 to 12]"
        }
      ]
    },
    "payout_method_instruction": null,
    "min_amount": 0,
    "max_amount": 350000000,
    "is_returnable": true,
    "is_contract_required": false,
    "is_enabled_by_default": true
  }
}
POST/v1/payout-beneficiarylivex-on-behalf-of

Create beneficiary (supplier)

Saves an overseas supplier on the sub account. Common suppliers are created once per sub account, ideally at onboarding.

Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/payout-beneficiary' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"type":"company","beneficiary_name":"Ubud Jungle Retreat","currency":"IDR","bank_country":"ID","account_number":"1234567890","bic_swift":"CENAIDJA","company":{"name":"Ubud Jungle Retreat","registration_number":"REG123456","address_line1":"1 Jl Raya Ubud","address_city":"Gianyar","address_country":"ID"}}'
GET/v1/payout-beneficiarylivex-on-behalf-of

List beneficiaries

Suppliers saved on the sub account.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-beneficiary' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "025304218360168fd0b278a3aae0cbf2",
  "request_time": "2026-10-24T16:48:10.692Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "payout_beneficiary_id": "po_ben_2a9758843a174c6f85ed648c1a7a449d",
      "org_id": "org_74092bcb151140d38f055086b60fdf62",
      "type": "company",
      "beneficiary_name": "Finmo Test",
      "description": null,
      "metadata": null,
      "created_at": "2026-10-07T11:20:30.811Z",
      "updated_at": "2026-10-07T11:20:30.811Z",
      "is_active": true,
      "currency": "SGD",
      "bank_country": "SG",
      "bank_state": null,
      "bank_city": null,
      "bank_name": "CTNA",
      "nickname": null,
      "account_number": "123456789",
      "bsb": null,
      "bic_swift": null,
      "intermediary_bic_swift": null,
      "iban": null,
      "ifsc": null,
      "bank_code": null,
      "branch_code": null,
      "aba": null,
      "sort_code": null,
      "pay_id": null,
      "pay_id_type": null,
      "proxy_type": null,
      "proxy_value": null,
      "account_type": null,
      "fps_proxy_type": null,
      "fps_proxy_value": null,
      "duitnow_proxy_type": null,
      "duitnow_proxy_value": null,
      "upi_id": null,
      "biller_code": null,
      "customer_reference_number": null,
      "interac_email": null,
      "cnaps": null,
      "organization_reference_id": null,
      "created_by": "org_user_id:org_user_45864f0142854c23b08db650f33e9668",
      "additional_data": null,
      "customer_id": null,
      "company": {
        "name": "Finmo Test",
        "registration_number": null,
        "company_incorporation_country": null,
        "address_country": "SG",
        "address_state": null,
        "address_city": null,
        "address_line1": null,
        "address_line2": null,
        "address_zip_code": null,
        "phone_number": null,
        "phone_country_code": null,
        "phone_number_e164": null,
        "company_email": null,
        "identification_type": null,
        "identification_value": null
      }
    }
  ]
}
GET/v1/payout-beneficiary/:ben_idlivex-on-behalf-of

Get beneficiary

One supplier.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout-beneficiary/:ben_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
POST/v1/payout-beneficiary/validatelivex-on-behalf-of

Validate bank details

Checks fields against the method's rules (IBAN mod-97, ABA checksum, SWIFT format) before money moves.

  • Try iban GB82WEST12345698765432 to see the 100001 error.
Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/payout-beneficiary/validate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"payout_method_name":"gb_bank_swift_gbp","is_beneficiary_name_match_enabled":true,"payout_beneficiary":{"type":"company","beneficiary_name":"Thames Corporate Travel","iban":"GB29NWBK60161331926819","bic_swift":"NWBKGB2L","company":{"name":"Thames Corporate Travel","address_line1":"1 King St","address_city":"London","address_country":"GB"}}}'
POST/v1/fx-ratelivex-on-behalf-of

Live FX quote

Returns fx_rate_id held for about 20 seconds. The rate already includes the sub account's pricing plan markup.

FieldTypeDescription
source_currency*string
target_currency*string
source_amountnumberSend exactly one of source_amount / target_amount
target_amountnumber
  • pricing (mid rate, Finmo spread, partner markup) is a proposed addition to show 'Finmo rate + Zenith markup'.
  • Sandbox mirrors live limits: IDR, THB, PHP, MYR and INR can be bought but not sold (406 104607).
Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/fx-rate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"source_currency":"AUD","target_currency":"IDR","source_amount":null,"target_amount":25000000}'
Response captured from api.finmo.net sandbox · 201
{
  "request_id": "17e657f7225fad40b6a8e7066fb0dbf6",
  "request_time": "2026-10-24T16:48:14.347Z",
  "success": true,
  "status_code": 201,
  "status_text": "Created",
  "data": {
    "fx_rate_id": "fx_rate_19b8d3bc68724ff8be4b05320acc0d3f",
    "org_id": "org_74092bcb151140d38f055086b60fdf62",
    "customer_id": null,
    "source_currency": "AUD",
    "target_currency": "IDR",
    "source_amount": 80.88,
    "target_amount": 1000000,
    "fixed_side": "BUY",
    "expire_at": "2026-10-24T16:48:34.541Z",
    "fx_rate": 12363.469197,
    "settle_by": "2026-10-25T16:48:14.541Z",
    "created_at": "2026-10-24T16:48:14.553Z",
    "updated_at": "2026-10-24T16:48:14.553Z"
  }
}
GET/v1/fx-rate/:fx_idlivex-on-behalf-of

Get quote

One quote.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/fx-rate/:fx_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
POST/v1/payoutlivex-on-behalf-ofneeds APPROVED KYB

Create payout

Pays a supplier. Attach fx_rate_id for a cross-currency payout; the rate locks. Status goes CREATED, PENDING, then COMPLETED, FAILED or RETURNED, each with a webhook.

FieldTypeDescription
payout_method_name*string
sender_currency*string
beneficiary_currency*string
beneficiary_countrystring
sender_amount | beneficiary_amount*number
fx_rate_idstring
debit_wallet_id*string
payout_beneficiary_id | payout_beneficiary_param*string | object
purpose_code*stringe.g. SUPA (supplier), TRVL
organization_reference_idstring
  • Send X-Idempotency-Key (UUID v4). A retry with the same key returns the original payout and an x-cached-request-id header.
  • Header x-sandbox-simulate: timeout creates the payout and returns 504, so you can practise 'check GET /payout before resending'.
Request
curl -X POST 'https://sandbox.finmotreasury.net/v1/payout' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H "X-Idempotency-Key: $(uuidgen)" \
  -H 'content-type: application/json' \
  -d '{"payout_method_name":"id_bank_skn_idr","sender_currency":"AUD","beneficiary_currency":"IDR","beneficiary_country":"ID","beneficiary_amount":25000000,"fx_rate_id":"{{fx_rate_id}}","debit_wallet_id":"{{wallet_id}}","payout_beneficiary_id":"{{payout_beneficiary_id}}","purpose_code":"SUPA","organization_reference_id":"BKG-88213"}'
Response captured from api.finmo.net sandbox · 201
{
  "request_id": "0df80106a80f26359084326afcfe2b88",
  "request_time": "2026-10-24T16:48:17.051Z",
  "success": true,
  "status_code": 201,
  "status_text": "Created",
  "data": {
    "payout_id": "payout_25e62509ff414232a596d0a627ffd42e",
    "org_id": "org_74092bcb151140d38f055086b60fdf62",
    "description": "Zenith sandbox fixture capture",
    "metadata": null,
    "payout_method_name": "id_bank_skn_idr",
    "status": "CREATED",
    "sender_country": null,
    "organization_reference_id": "zen-fixture-1",
    "additional_data": {},
    "bulk_payout_id": null,
    "payout_reference": "PO25E62509FF41423",
    "beneficiary_country": "ID",
    "payout_beneficiary_id": "po_ben_5308352cbc2d42b1b2b7413dffbf9089",
    "sender_amount": 80.88,
    "sender_currency": "AUD",
    "beneficiary_amount": 1000000,
    "beneficiary_currency": "IDR",
    "fx_rate": 12363.469197,
    "fx_rate_id": "fx_rate_19b8d3bc68724ff8be4b05320acc0d3f",
    "is_returnable": true,
    "payout_type": "GCA_PAYOUT",
    "debit_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
    "scope": "MASTER",
    "customer_id": null,
    "payout_sender_param": null,
    "payout_sender_id": null,
    "purpose_code": "SUPA",
    "payout_beneficiary_param": {
      "type": "company",
      "company": {
        "name": "Ubud Jungle Retreat",
        "address_city": "Gianyar",
        "address_line1": "1 Jl Raya Ubud",
        "address_country": "ID",
        "registration_number": "REG123456"
      },
      "currency": "IDR",
      "bic_swift": "CENAIDJA",
      "bank_country": "ID",
      "account_number": "1234567890"
    },
    "payout_method_param": {},
    "fees_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
    "pricing_event_data": {
      "total": {
        "aggregated_tax_on_fees": 0,
        "aggregated_fees_currency": "AUD",
        "aggregated_fees_without_tax": 43.16,
        "aggregated_fees_including_tax": 43.16
      },
      "PAYOUT_COMPLETED": {
        "tax_on_fees": 0,
        "fees_currency": "AUD",
        "fees_without_tax": 43.16,
        "fees_including_tax": 43.16
      }
    },
    "fees_without_tax": 43.16,
    "tax_on_fees": null,
    "fees_including_tax": 43.16,
    "fees_currency": "AUD",
    "returned_amount": null,
    "fx_conversion_id": null,
    "debit_wallet_transaction_id": "w_txn_5f278c822fc349d2bb25e3007140c98f",
    "paid_amount": null,
    "transaction_id": null,
    "fees_wallet_transaction_id": null,
    "receipt_email": null,
    "webhook_url": null,
    "paid_at": null,
    "paid_currency": null,
    "returned_at": null,
    "returned_currency": null,
    "payout_returned_wallet_id": null,
    "payout_returned_wallet_transaction_id": null,
    "payout_returned_transaction_id": null,
    "released_at": null,
    "payout_charge_bearer": null,
    "reason_for_return": null,
    "reason_for_failure": null,
    "account_payable_id": null,
    "category_id": null,
    "tag_id_list": null,
    "coa_id": null,
    "estimated_delivery_at": null,
    "is_paid": false,
    "is_returned": false,
    "is_fees_charged": false,
    "is_chargeable": true,
    "is_reconciled": false,
    "created_at": "2026-10-24T16:48:20.138Z",
    "updated_at": "2026-10-24T16:48:20.138Z"
  }
}
GET/v1/payoutlivex-on-behalf-of

List payouts

Filter by status, payout_method_name, organization_reference_id, start_time, end_time.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
GET/v1/payout/:payout_idlivex-on-behalf-of

Get payout

Status and details.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout/:payout_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "3563ffa87cbded2800d84692745c8410",
  "request_time": "2026-10-24T16:48:41.005Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": {
    "payout_id": "payout_25e62509ff414232a596d0a627ffd42e",
    "payout_method_name": "id_bank_skn_idr",
    "payout_method_param": {},
    "org_id": "org_74092bcb151140d38f055086b60fdf62",
    "customer_id": null,
    "scope": "MASTER",
    "debit_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
    "fees_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
    "debit_wallet_transaction_id": "w_txn_02f8445886254623be2df7ff0d47a994",
    "transaction_id": "txn_aa03c7d5f1684a668d30197d79706d36",
    "fees_wallet_transaction_id": "w_txn_bb9125dd00e5421b8af47ccda2131a1a",
    "beneficiary_amount": 1000000,
    "beneficiary_currency": "IDR",
    "beneficiary_country": "ID",
    "sender_amount": 80.88,
    "sender_currency": "AUD",
    "sender_country": null,
    "fx_conversion_id": null,
    "fx_rate_id": "fx_rate_19b8d3bc68724ff8be4b05320acc0d3f",
    "fx_rate": 12363.469197,
    "description": "Zenith sandbox fixture capture",
    "purpose_code": "SUPA",
    "receipt_email": null,
    "payout_reference": "PO25E62509FF41423",
    "webhook_url": null,
    "status": "COMPLETED",
    "payout_type": "GCA_PAYOUT",
    "payout_beneficiary_id": "po_ben_5308352cbc2d42b1b2b7413dffbf9089",
    "payout_sender_id": null,
    "payout_beneficiary_param": {
      "type": "company",
      "company": {
        "name": "Ubud Jungle Retreat",
        "address_city": "Gianyar",
        "address_line1": "1 Jl Raya Ubud",
        "address_country": "ID",
        "registration_number": "REG123456"
      },
      "currency": "IDR",
      "bic_swift": "CENAIDJA",
      "bank_country": "ID",
      "account_number": "1234567890"
    },
    "payout_sender_param": null,
    "is_paid": true,
    "paid_at": "2026-10-24T16:48:30.000Z",
    "paid_amount": 80.88,
    "paid_currency": "AUD",
    "is_returnable": true,
    "is_returned": false,
    "returned_at": null,
    "returned_amount": null,
    "returned_currency": null,
    "payout_returned_wallet_id": null,
    "payout_returned_wallet_transaction_id": null,
    "payout_returned_transaction_id": null,
    "released_at": "2026-10-24T16:48:25.000Z",
    "fees_without_tax": 43.16,
    "tax_on_fees": null,
    "fees_including_tax": 43.16,
    "fees_currency": "AUD",
    "is_fees_charged": true,
    "is_chargeable": true,
    "payout_charge_bearer": null,
    "metadata": null,
    "additional_data": {},
    "organization_reference_id": "zen-fixture-1",
    "is_reconciled": true,
    "created_at": "2026-10-24T16:48:20.138Z",
    "updated_at": "2026-10-24T16:48:32.000Z",
    "reason_for_return": null,
    "reason_for_failure": null,
    "bulk_payout_id": null,
    "account_payable_id": null,
    "pricing_event_data": {
      "total": {
        "aggregated_tax_on_fees": 0,
        "aggregated_fees_currency": "AUD",
        "aggregated_fees_without_tax": 43.16,
        "aggregated_fees_including_tax": 43.16
      },
      "PAYOUT_COMPLETED": {
        "tax_on_fees": 0,
        "fees_currency": "AUD",
        "fees_without_tax": 43.16,
        "fees_including_tax": 43.16
      }
    },
    "estimated_delivery_at": null
  }
}
GET/v1/payout/:payout_id/get-payout-pdflivex-on-behalf-of

Payment confirmation

download_url to a payment confirmation (sandbox serves an HTML memo).

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/payout/:payout_id/get-payout-pdf' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'

Webhooks

PUT/v1/partner/organization-setting/:org_idlive

Set webhook URL / token

One webhook URL per sub account. All sub accounts can point to the same Zenith listener; every event carries org_id.

FieldTypeDescription
key*stringwebhook_url (live) or webhook_security_token (proposed)
value*string
Request
curl -X PUT 'https://sandbox.finmotreasury.net/v1/partner/organization-setting/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'content-type: application/json' \
  -d '{"key":"webhook_url","value":"https://listener.zenith.example/finmo"}'
GET/v1/partner/organization-setting/:org_idproposed

List sub account settings

Read back webhook_url and a masked webhook_security_token.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/partner/organization-setting/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
GET/v1/webhook-notificationlive

List webhook deliveries

Every notification with status and attempt count. Without x-on-behalf-of it lists all sub accounts.

FieldTypeDescription
event_typestring
event_idstring
event_namestring
statusstring
  • attempts[], next_attempt_at and delivered_at are sandbox extras (confirm field names with product).
Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/webhook-notification' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
Response captured from api.finmo.net sandbox · 200
{
  "request_id": "db05c6927c9198e365442fc5df56d71c",
  "request_time": "2026-10-24T16:48:47.802Z",
  "success": true,
  "status_code": 200,
  "status_text": "OK",
  "data": [
    {
      "webhook_notification_id": "webhook_31e87344abea4954ab4249602f3fd487",
      "org_id": "org_74092bcb151140d38f055086b60fdf62",
      "event_id": "payout_25e62509ff414232a596d0a627ffd42e",
      "event_type": "PAYOUT",
      "event_name": "PAYOUT_COMPLETED",
      "event_description": "PAYOUT",
      "status": "PENDING",
      "webhook_url": null,
      "event_detail": {
        "scope": "MASTER",
        "coa_id": null,
        "org_id": "org_74092bcb151140d38f055086b60fdf62",
        "status": "COMPLETED",
        "fx_rate": 12363.469197,
        "is_paid": true,
        "paid_at": "2026-10-24T16:48:30.000Z",
        "metadata": null,
        "payout_id": "payout_25e62509ff414232a596d0a627ffd42e",
        "created_at": "2026-10-24T16:48:20.138Z",
        "fx_rate_id": "fx_rate_19b8d3bc68724ff8be4b05320acc0d3f",
        "updated_at": "2026-10-24T16:48:31.000Z",
        "category_id": null,
        "customer_id": null,
        "description": "Zenith sandbox fixture capture",
        "is_returned": false,
        "paid_amount": 80.88,
        "payout_type": "GCA_PAYOUT",
        "released_at": "2026-10-24T16:48:25.000Z",
        "returned_at": null,
        "reviewed_at": null,
        "reviewed_by": null,
        "tag_id_list": null,
        "tax_on_fees": null,
        "webhook_url": null,
        "purpose_code": "SUPA",
        "fees_currency": "AUD",
        "is_chargeable": true,
        "is_reconciled": false,
        "is_returnable": true,
        "paid_currency": "AUD",
        "receipt_email": null,
        "review_status": "NOT_REQUIRED",
        "sender_amount": 80.88,
        "bulk_payout_id": null,
        "fees_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "sender_country": null,
        "transaction_id": "txn_aa03c7d5f1684a668d30197d79706d36",
        "additional_data": {},
        "debit_wallet_id": "wallet_21e0eefa8e2243f39810faf7a820a19d",
        "is_fees_charged": true,
        "returned_amount": null,
        "sender_currency": "AUD",
        "fees_without_tax": 43.16,
        "fx_conversion_id": null,
        "payout_reference": "PO25E62509FF41423",
        "payout_sender_id": null,
        "reason_for_return": null,
        "returned_currency": null,
        "account_payable_id": null,
        "beneficiary_amount": 1000000,
        "fees_including_tax": 43.16,
        "payout_method_name": "id_bank_skn_idr",
        "pricing_event_data": {
          "total": {
            "aggregated_tax_on_fees": 0,
            "aggregated_fees_currency": "AUD",
            "aggregated_fees_without_tax": 43.16,
            "aggregated_fees_including_tax": 43.16
          },
          "PAYOUT_COMPLETED": {
            "tax_on_fees": 0,
            "fees_currency": "AUD",
            "fees_without_tax": 43.16,
            "fees_including_tax": 43.16
          }
        },
        "reason_for_failure": null,
        "beneficiary_country": "ID",
        "payout_method_param": {},
        "payout_sender_param": null,
        "beneficiary_currency": "IDR",
        "payout_charge_bearer": null,
        "estimated_delivery_at": null,
        "payout_beneficiary_id": "po_ben_5308352cbc2d42b1b2b7413dffbf9089",
        "payout_beneficiary_param": {
          "type": "company",
          "company": {
            "name": "Ubud Jungle Retreat",
            "address_city": "Gianyar",
            "address_line1": "1 Jl Raya Ubud",
            "address_country": "ID",
            "registration_number": "REG123456"
          },
          "currency": "IDR",
          "bic_swift": "CENAIDJA",
          "bank_country": "ID",
          "account_number": "1234567890"
        },
        "organization_reference_id": "zen-fixture-1",
        "payout_returned_wallet_id": null,
        "fees_wallet_transaction_id": "w_txn_bb9125dd00e5421b8af47ccda2131a1a",
        "debit_wallet_transaction_id": "w_txn_02f8445886254623be2df7ff0d47a994",
        "payout_returned_transaction_id": null,
        "payout_returned_wallet_transaction_id": null
      },
      "created_at": "2026-10-24T16:48:31.827Z",
      "updated_at": "2026-10-24T16:48:31.827Z",
      "expiry": null,
      "retry_interval": null,
      "http_response": null,
      "attempt_count": 0,
      "callback_info": null,
      "headers": null
    }
  ]
}
GET/v1/webhook-notification/:webhook_idlive

Get webhook delivery

One notification with its attempts.

Request
curl -X GET 'https://sandbox.finmotreasury.net/v1/webhook-notification/:webhook_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'
PATCH/v1/webhook-notification/:webhook_id/retriggerlive

Re-send a webhook

Queues an immediate delivery attempt. Picks up the current webhook_url.

Request
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/webhook-notification/:webhook_id/retrigger' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…'

Sandbox tools

PUT/v1/upload/:tokensandbox-only

Upload file bytes

Stands in for the presigned S3 URL. PUT the raw file; max 5 MB; expires 30 seconds after it was issued.

Request
curl -X PUT 'https://sandbox.finmotreasury.net/v1/upload/:token' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY"
PATCH/v1/partner/kyb/simulate/:org_idsandbox-only

Force a KYB outcome

Same style as Finmo's /simulate endpoints. Drive a sub account to APPROVED, REJECTED or ACTION_REQUIRED without waiting.

FieldTypeDescription
status*stringAPPROVED | REJECTED | ACTION_REQUIRED
Request
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/partner/kyb/simulate/:org_id' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'content-type: application/json' \
  -d '{"status":"APPROVED"}'
PATCH/v1/virtual-account/simulate-payinsandbox-onlyx-on-behalf-of

Simulate funds arriving

Same endpoint as Finmo's sandbox. Stands in for Zenith's AUD transfer into the sub account. Emits VA_PAYIN_COMPLETED.

FieldTypeDescription
virtual_account_id*string
amount*number
currency*string
Request
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/virtual-account/simulate-payin' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H 'content-type: application/json' \
  -d '{"virtual_account_id":"{{virtual_account_id}}","amount":25000,"currency":"AUD"}'
PATCH/v1/payout/simulatesandbox-onlyx-on-behalf-of

Simulate payout outcome

Same endpoint as Finmo's sandbox. COMPLETED/FAILED need status PENDING; RETURNED needs COMPLETED (406 100006 otherwise).

FieldTypeDescription
payout_id*string
status*stringCOMPLETED | FAILED | RETURNED
Request
curl -X PATCH 'https://sandbox.finmotreasury.net/v1/payout/simulate' \
  -u "$FINMO_ACCESS_KEY:$FINMO_SECRET_KEY" \
  -H 'x-on-behalf-of: org_…' \
  -H 'content-type: application/json' \
  -d '{"payout_id":"{{payout_id}}","status":"FAILED"}'
Response captured from api.finmo.net sandbox · 406
{
  "request_id": "650e3e4cc2c161993043032f4fbec57a",
  "request_time": "2026-10-24T16:48:42.250Z",
  "success": false,
  "status_code": 406,
  "status_text": "Not Acceptable",
  "error": {
    "code": 100006,
    "name": "PAYOUT_STATUS_MISMATCH_ERROR",
    "message": "Payout is not in PENDING state"
  }
}

Webhook events

POST to the sub account's webhook_url with header x-security-token (the value Zenith set). Respond 2xx within 5 s. Retries: 15m, 1h, 3h, 6h, 12h, 24h. Re-send any delivery with PATCH /webhook-notification/{id}/retrigger. Deliveries are at-least-once: dedupe on webhook_notification_id / event_id.

{
  "webhook_notification_id": "webhook_…",
  "org_id": "org_…",
  "event_id": "payout_…",
  "event_type": "PAYOUT",
  "event_name": "PAYOUT_COMPLETED",
  "event_description": "PAYOUT",
  "event_detail": {
    "…": "full payout object, same shape as GET /payout/{id}"
  },
  "attempt_count": 1,
  "created_at": "2026-10-29T00:12:31.000Z"
}
ORGANIZATION_KYB_APPROVEDORGANIZATIONSub account approved; AUD account details activeproposed
ORGANIZATION_KYB_ACTION_REQUIREDORGANIZATIONFinmo needs something from Zenith (possible screening match, incomplete registry record)proposed
ORGANIZATION_KYB_REJECTEDORGANIZATIONSub account cannot be openedproposed
VA_CREATEDVIRTUAL_ACCOUNTAUD account details activated (is_active true)live
VA_PAYIN_COMPLETEDVIRTUAL_ACCOUNTFunds arrived on the sub account's AUD account (the pre-read lists TOPUP / VA_PAYIN_COMPLETED)confirm
PAYOUT_CREATEDPAYOUTPayout accepted; funds reserved (available balance drops)live
PAYOUT_COMPLETEDPAYOUTFunds sent; actual balance debited. On SWIFT, completed means sentlive
PAYOUT_FAILEDPAYOUTPayout failed; reserved funds released to the balancelive
PAYOUT_RETURNEDPAYOUTReceiving bank returned a completed payout; amount credited backlive
FEES_PAYMENTFEESStandalone fee charges (per-payout fees sit on the payout object)confirm

Errors

400100400INVALID_FIELD_OR_VALUE_ERRORFix the request. message is an array of field problems
400100001FAILED_TO_VALIDATE_BENEFICIARY_DETAILS_ERRORBank details failed validation
400100009INSUFFICIENT_AMOUNT_IN_WALLETAvailable balance is less than amount + fee
401100401UNAUTHORIZED_ERRORCheck access key / secret key
403100403 / 100404ON_BEHALF_OF_FORBIDDEN_ERROR / ORGANIZATION_NOT_APPROVED_ERRORx-on-behalf-of is not your sub account, or KYB is not approved yet
404100601PAYOUT_NOT_FOUND_ERROR (and *_NOT_FOUND_ERROR)Unknown id for this sub account
406100006PAYOUT_STATUS_MISMATCH_ERRORSimulate/transition not allowed from the current status
406104607UNSUPPORTED_CURRENCY_PAIR_ERRORPair not supported (e.g. selling IDR, THB, PHP)
409100010IDEMPOTENCY_KEY_CONFLICT_ERRORSame X-Idempotency-Key with a different body. Do not retry
429100429TOO_MANY_REQUESTS_ERRORBack off and retry with the same key (production limits from engineering)
504100504GATEWAY_TIMEOUT_ERRORCheck status (GET) before resending a payment
500100500INTERNAL_SERVER_ERRORRetry with the same X-Idempotency-Key
409 captured from api.finmo.net sandbox
{
  "request_id": "3223a7b82120aa34ee3abffa8e904483",
  "request_time": "2026-10-24T16:48:22.000Z",
  "success": false,
  "status_code": 409,
  "status_text": "CONFLICT",
  "error": {
    "code": 100010,
    "name": "IDEMPOTENCY_KEY_CONFLICT_ERROR",
    "message": "Cannot process request with same X-Idempotency-Key: 90a04c9e-407f-4ef9-bc43-b4f6e9672ab8"
  }
}

Test data

Test ABNs (fictional, unissued range)
46 944 446 235approve
40 915 257 037screening hit
78 984 661 707registry incomplete
68 951 127 629reject

Any other checksum-valid ABN approves and echoes the org_name you sent (labelled "sandbox registry"). Real company data is never returned.

Payout outcomes
  • Account number ending 4000000002: FAILED (account closed)
  • Account / IBAN ending 4000000003: COMPLETED, then RETURNED
  • PATCH /payout/simulate: COMPLETED / FAILED from PENDING, RETURNED from COMPLETED
  • Header x-sandbox-simulate: timeout on POST /payout: created, then 504
  • IBAN GB82WEST12345698765432 fails validation (unknown bank); GB29NWBK60161331926819 passes
Payout methods in the sandbox (fees are sandbox pricing, not contract rates)
MethodDestinationFeeDelivery
au_bank_acctAU · AUD0.33 AUDSame day
au_bank_swift_audAU · AUD43.31 AUD1-2 business days
nz_bank_directcredit_nzdNZ · NZD1.8 NZDSame or next business day
nz_bank_swift_nzdNZ · NZD53.43 NZD1-2 business days
sg_bank_fastpayment_sgdSG · SGD0.33 SGDMinutes
sg_bank_swift_sgdSG · SGD38.54 SGD1-2 business days
us_bank_ach_usdUS · USD0.33 USD1-2 business days
us_bank_swift_usdUS · USD30.3 USD1-2 business days
gb_bank_swift_gbpGB · GBP22.86 GBP1-2 business days
de_bank_swift_eurDE · EUR26.73 EUR1-2 business days
fr_bank_swift_eurFR · EUR26.73 EUR1-2 business days
hk_bank_swift_hkdHK · HKD236.94 HKD1-2 business days
ae_bank_transfer_aedAE · AED0.33 AEDSame day
th_bank_swift_thbTH · THB1011.71 THB1-2 business days
id_bank_skn_idrID · IDR545455 IDR1 business day
jp_bank_swift_jpyJP · JPY30 USD1-2 business days
cn_bank_swift_cnyCN · CNY30 USD1-2 business days
vn_bank_swift_vndVN · VND30 USD1-2 business daysconfirm
fj_bank_swift_fjdFJ · FJD30 USD1-2 business daysconfirm
ph_bank_swift_phpPH · PHP30 USD1-2 business daysconfirm
in_bank_swift_inrIN · INR30 USD1-2 business daysconfirm
ca_bank_swift_cadCA · CAD30 USD1-2 business days

Live today vs proposed for Zenith

CapabilityStatusNote
Create sub account, KYB save, documents, list/get, webhook_urllivePartner API on api.finmo.net
abn / acn / address_city on create; registry pull + approval by relianceproposedFinmo pulls the company record itself; no forms to the merchant
Balances, account details, quotes and AUD account details returned in the create responseproposedInstant confirmation
ORGANIZATION_KYB_APPROVED / _ACTION_REQUIRED / _REJECTED webhooksproposedWorking names
kyb.stage, kyb.action_requiredproposedkyb.status keeps the live enum
webhook_security_token per sub accountproposedLive: token set on the account
Wallet, FX quote, beneficiaries, payouts, transactions, webhook notificationsliveCore API; x-on-behalf-of for sub accounts
pricing block on /fx-rate (mid, Finmo spread, partner markup)proposedShows 'Finmo rate + Zenith markup'
Per-transaction markupproposedTo scope at the workshop