POST /api/inquiry
Request
| Name | Type | Required | Validation | Description |
|---|---|---|---|---|
| merchant_transaction_id | string | true | Merchant-provided unique transaction identifier. | |
| bank_code | string | true | Bank code used for the transaction (see Appendix). | |
| amount | number | true | Required, Numeric, Between 1 - 12 digits | Transaction amount as a numeric value. |
| account_number | string | true | Required, Numeric Between 1 - 30 digits | Customer account number for the transaction. |
| customer_name | string | true | Between 5 - 25 characters Allowed chars: a-z, A-Z, 0-9, - (dash),(space) | Customer name linked to the transaction. |
{
"merchant_transaction_id": "RP123333333",
"amount": 100000,
"bank_code": "014",
"account_number": "0123456789",
"customer_name": "John Doe"
}
Response
| Name | Description |
|---|---|
| status | Operation status indicator. true indicates success, false indicates failure. |
| code | Machine-readable error code, present only on coded rejections: INVALID_BANK_CODE and INVALID_ACCOUNT_NUMBER (HTTP 400), PAYOUT_NOT_CONFIGURED (HTTP 403), and INQUIRY_IN_PROGRESS (HTTP 409 — see Concurrency below). See Response codes below. Match on this field, never on message. |
| message | Present on replayed inquiries (e.g. "Inquiry retrieved successfully") and on failures; omitted on a freshly created, non-failed inquiry. |
| data | Inquiry details. null on validation rejections (400/403), the concurrency-lock response (409), internal errors (HTTP 200, status:false, message only), and the generic 500. |
| data.inquiry_id | Unique identifier for the inquiry. |
| data.merchant_transaction_id | Merchant-provided transaction identifier. |
| data.status | Current inquiry status: pending, valid (approved, awaiting transfer), processing, success, fail. See Check Inquiry Status for the same vocabulary. |
| data.account_number | Account number linked to the transaction. |
| data.account_name | Account holder name (can be null if unavailable). |
| data.bank_code | Bank code used for the transaction. |
| data.bank_name | Name of the bank processing the transaction. |
| data.amount | Transaction amount. A number holding the requested amount on a freshly created, non-failed inquiry; a string with 2 decimal places holding the amount credited to the beneficiary on replayed and failed inquiries. |
| data.fee | Applied transaction fee, as a string with 2 decimal places (e.g. "5500.00"). |
| data.requested_amount | Amount the client asked to disburse, as a string with 2 decimal places. Same on fresh, replayed, and failed inquiries. |
| data.user_receives | Amount credited to the beneficiary, as a string with 2 decimal places. Equals requested_amount minus fee for charged_to_user, and requested_amount for charged_to_client. |
| data.payout_fee_type | Fee charging model: charged_to_user (fee deducted from the requested amount) or charged_to_client (fee charged to the client balance on top). |
| data.reason | Failure reason. Present only when data.status is fail. |
| data.payment_at | Completion timestamp, server time (UTC+7), no offset, YYYY-MM-DD HH:MM:SS (e.g. "2026-08-13 09:12:45"), same format as data.expired_at. Present only when data.status is success. |
| data.expired_at | Inquiry expiry timestamp, server time (UTC+7), no offset, YYYY-MM-DD HH:MM:SS (e.g. "2026-08-13 09:30:00"). Present whenever data.status is not fail. |
| data.expired_at_iso | Same expiry as expired_at, as ISO 8601 with offset (e.g. "2025-02-26T19:00:00+07:00"). Same format on every channel. null when expired_at is null. |
When data.status is fail, data carries the same field set as other responses plus reason, minus payment_at and expired_at. Note that account_name is frequently null on failed inquiries — the bank never confirmed the account holder for an inquiry that failed validation.
{
"status": true,
"data": {
"inquiry_id": "01jj1g751vqw68ng5546xnda5c",
"merchant_transaction_id": "RP123333333",
"status": "valid",
"account_number": "0123456789",
"account_name": "John Doe",
"bank_code": "014",
"bank_name": "Bank Central Asia",
"amount": 100000,
"fee": "5500.00",
"requested_amount": "100000.00",
"user_receives": "100000.00",
"payout_fee_type": "charged_to_client",
"expired_at": "2026-08-13 09:30:00",
"expired_at_iso": "2026-08-13T09:30:00+07:00"
}
}
{
"status": true,
"data": {
"inquiry_id": "01jj1g751vqw68ng5546xnda5c",
"merchant_transaction_id": "RP123333333",
"status": "pending",
"account_number": "0123456789",
"account_name": "John Doe",
"bank_code": "014",
"bank_name": "Bank Central Asia",
"amount": 100000,
"fee": "5500.00",
"requested_amount": "100000.00",
"user_receives": "100000.00",
"payout_fee_type": "charged_to_client",
"expired_at": "2026-08-13 09:30:00",
"expired_at_iso": "2026-08-13T09:30:00+07:00"
}
}
{
"status": true,
"message": "Inquiry retrieved successfully",
"data": {
"inquiry_id": "01jj1g751vqw68ng5546xnda5c",
"merchant_transaction_id": "RP123333333",
"status": "success",
"account_number": "0123456789",
"account_name": "John Doe",
"bank_code": "014",
"bank_name": "Bank Central Asia",
"amount": "100000.00",
"fee": "5500.00",
"requested_amount": "100000.00",
"user_receives": "100000.00",
"payout_fee_type": "charged_to_client",
"payment_at": "2026-08-13 09:12:45",
"expired_at": "2026-08-13 09:30:00",
"expired_at_iso": "2026-08-13T09:30:00+07:00"
}
}
{
"status": false,
"message": "Insufficient Balance",
"data": {
"inquiry_id": "01jj1g751vqw68ng5546xnda5c",
"merchant_transaction_id": "RP123333333",
"status": "fail",
"account_number": "0123456789",
"account_name": null,
"bank_code": "014",
"bank_name": "Bank Central Asia",
"amount": "100000.00",
"fee": "5500.00",
"requested_amount": "100000.00",
"user_receives": "100000.00",
"payout_fee_type": "charged_to_client",
"reason": "Insufficient Balance"
}
}
Idempotency
Calling this endpoint again with the same merchant_transaction_id never creates a second inquiry — the existing inquiry is returned with its current data.status. A fail inquiry is final: its merchant_transaction_id cannot be reused; start over with a new one.
Concurrency
If two requests with the same merchant_transaction_id arrive at the same time, the second receives HTTP 409 with code: "INQUIRY_IN_PROGRESS" — retry it after a moment to receive the stored inquiry.
{
"status": false,
"code": "INQUIRY_IN_PROGRESS",
"message": "A request with the same merchant_transaction_id is already being processed. Please wait before retrying.",
"data": null
}
Response codes
| HTTP | code | Message | Recommended action |
|---|---|---|---|
| 400 | INVALID_BANK_CODE | Invalid bank code. | Use a valid code from the Appendix and re-send |
| 400 | INVALID_ACCOUNT_NUMBER | Invalid account number maximum 30 digits. | Fix the account number and re-send |
| 403 | PAYOUT_NOT_CONFIGURED | Payout is not configured, please contact support. | Contact support |
| 409 | INQUIRY_IN_PROGRESS | see the example above | Retry after a short delay to receive the stored inquiry |
See the full error-code reference for every error code across both endpoints, plus the code- and field-stability contract.