Skip to content

Partner API overview

The Partner API lets your servers create pay-ins (collect money) and payouts (send money), check your balance, withdraw funds and verify transfer slips.

https://api.example.com/v1
TaskEndpointPage
Collect money from a payer/v1/payinsPay-ins
Send money to a payer/v1/payoutsPayouts
Manage your end users’ bank accounts/v1/payers, /v1/banksPayers
Read your account, balance and totals/v1/account, /v1/reportsBalance and reports
Withdraw your balance to your own account/v1/withdrawalsWithdrawals
Verify a transfer slip/v1/slips/verifySlip verification
Get notified when a status changes(we call your URL)Webhooks

All keys use the same base URL. The type of API key decides how requests are treated.

KeyFormatUse
Live keypk_live_ + 24 charactersProduction
Test keypk_test_...Integration testing. Works only while your account is in test mode. Issued by support
  • Partners with an older key (32 hex characters) keep using it; signing works exactly the same way.
  • With a test key only POST /v1/slips/verify returns simulated results (see Slip verification). Every other endpoint behaves normally, so pay-ins and payouts you create are real. Test with small amounts and your own accounts.
  • How to get your key and secret: Quick start.
  • JSON, UTF-8 in both directions. Send Content-Type: application/json when there is a body.
  • camelCase field names, for example payerId, webhookUrl, createdAt.
  • Amounts are decimal strings such as "150.00": 2 decimals (USDT uses 6). Send amounts as strings too, never as numbers.
  • Currencies are upper case: THB, USD, USDT, LAK.
  • Timestamps are ISO-8601 in UTC, for example 2026-01-01T00:00:00.000Z. Report dates are YYYY-MM-DD in Thailand time (UTC+7).
  • IDs carry a type prefix followed by 32 lowercase hex characters. Store them as opaque strings.
PrefixType
pin_pay-in
pout_payout
payer_payer
wd_withdrawal
evt_webhook event
  • Fields without a value are null, never an empty string.
  • Unknown body fields and query parameters are rejected with 400 parameter_unknown. Send only the documented fields.

Success:

{
"data": { "object": "payin", "id": "pin_3f2b1c0d9e8f4a7b8c6d5e4f3a2b1c0d", "...": "..." },
"requestId": "req_Z3k9QmP2xR7tLw4NbV8cYh1s"
}

Error:

{
"error": {
"type": "invalid_request_error",
"code": "payer_not_found",
"message": "No such payer.",
"param": "payerId"
},
"requestId": "req_Z3k9QmP2xR7tLw4NbV8cYh1s"
}
  • Every response has an X-Request-Id header equal to requestId. Log it, and quote it whenever you contact support.
  • Branch on error.code; error.message is for humans and may change. See Errors for every code.
  • Every object has an object field naming its type, such as "payin", "payout" or "payer".
  • A success response may also contain warnings, notices that do not change the result (for example payer_name_differs). See Errors.

List endpoints (GET /v1/payins, GET /v1/payouts, GET /v1/payers, GET /v1/payers/{id}/payments) accept:

ParameterValue
limit1-100, default 20
cursornextCursor from the previous page
{
"data": [ { "object": "payin", "...": "..." } ],
"pagination": { "limit": 20, "hasMore": true, "nextCursor": "eyJvIjoyMH0" },
"requestId": "req_..."
}
  • Results are newest first.
  • While hasMore is true, repeat the same query with cursor=<nextCursor>.
  • Cursors are opaque. Do not build or edit them (an invalid one returns 400 invalid_cursor).

You only see your own account’s data. An ID from another account, or a malformed ID, always returns 404 resource_not_found.

  1. Authentication and request signing
  2. Quick start
  3. API reference with every endpoint