Internal transfers
Generated page, from the OpenAPI specification the gateway serves (
GET /v1/openapi.json). Do not edit it by hand: it is rewritten on every build.
| Method | Path | Description |
|---|---|---|
GET |
/v1/transfers |
List internal transfers |
POST |
/v1/transfers |
Internal transfer |
GET |
/v1/transfers/{id} |
Retrieve an internal transfer |
GET /v1/transfers
List internal transfers
Same pagination as payments.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
page |
query | no | Page, starting at 1. |
per_page |
query | no | Page size, 100 at most. |
Responses
200— OK (OperationList)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
POST /v1/transfers
Internal transfer
Moves funds to another account on the platform, with no external rail: no rail fee, no outbound call, one ledger entry. Scope can_payout, and the internal_transfers option enabled on the account.
Naming the corridor: platform_id or platform_code. Both are accepted and neither is deprecated. ⚠️ platform_code — orange, wave, yas — is the only one of the two that means the same platform everywhere: numeric ids are assigned by database insertion order, so a platform_id read in sandbox can name a different rail in production. Prefer the code. Sending both is accepted only when they agree; otherwise the route answers 422 platform_conflict rather than picking one.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
Idempotency-Key |
header | no | An idempotency key specific to THIS operation. Replaying the same key with the same payload returns the original; replaying it with a different payload is refused (409). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
recipient_id |
string | yes | The recipient account, by its public id. |
asset_id |
integer | yes | |
amount_minor |
string | yes | Amount in MINOR UNITS, as a string. Never a floating-point number: both lose centimes. The asset's decimal count comes from GET /v1/assets. |
country |
string | yes | ISO 3166-1 alpha-2 |
platform_id |
integer | no | The corridor's numeric id. ⚠️ NOT PORTABLE BETWEEN ENVIRONMENTS: platform ids are assigned by database insertion order, so an id read from sandbox may name a different rail in production. Prefer platform_code. Send either; sending both is accepted only when they agree, and refused with 422 platform_conflict when they do not. |
platform_code |
string | no | The corridor's STABLE code — 'orange', 'wave', 'yas'. Case-insensitive. Means the same platform in every environment, which platform_id does not. Send this or platform_id. |
client_ref |
string | no | |
description |
string | no |
Responses
201— Transfer created (Operation)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)409— Idempotency key replayed with a different payload (Error)422— Well-formed but refused: missing field, closed corridor, insufficient balance (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)503—platform_codemomentarily unresolvable: the platform catalogue cannot be read (temporarily_unavailable). This is not a refusal — send the same request again after Retry-After (Error)
GET /v1/transfers/{id}
Retrieve an internal transfer
The same masked view as GET /v1/payments/{id}.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id |
path | yes | Internal identifier, the operation's reference, or your own client_ref. |
Responses
200— OK (Operation)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
Schemas
The shapes the operations above return.
OperationList
| Field | Type | Description |
|---|---|---|
data |
Operation[] | |
data[].id |
string | The operation's public id. It is the one in the /v1/payments/{id} paths. |
data[].ref |
string | Our internal, readable reference. Distinct from the id: quote this one to support. |
data[].client_ref |
string | The reference you supplied at creation, returned unchanged. |
data[].kind |
string | payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which. |
data[].status |
string | The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail. |
data[].outcome |
string | pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on. |
data[].asset_id |
integer | The operation's asset, by its id (GET /v1/assets). |
data[].amount_minor |
string | The GROSS amount in minor units, as a string. |
data[].fee_minor |
string | The fee taken, in minor units. |
data[].net_minor |
string | The net in minor units: amount_minor less fee_minor. |
data[].platform_id |
integer | The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose. |
data[].is_test |
boolean | True for an operation created with a test key. No real money moves. |
data[].payment_url |
string | The hosted payment page, when the rail provides one. Absent until submission has succeeded. |
data[].deeplink |
string | The deep link into the rail's app, when it provides one. |
data[].qrcode_url |
string | The QR to show the payer, when the rail provides one. |
data[].risk |
Risk | The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block. |
data[].risk.status |
string | held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report. |
data[].risk.case_ref |
string | The operational case reference, to quote to support. Null when the hold is a compliance review. |
data[].risk.case_kind |
string | Accompanies case_ref, or nothing at all. |
data[].risk.reason |
string | The only free text this block carries, and it is identical for every hold. |
data[].risk.signals |
object[] | Product signals, advisory. Absent when there are none. |
data[].risk.signals[].code |
string | |
data[].risk.signals[].detail_fr |
string | |
data[].amount_refunded_minor |
string | Collections only: the sum of SUCCEEDED refunds, in minor units. |
data[].amount_refund_pending_minor |
string | Collections only: the sum of refunds IN PROGRESS, in minor units. |
data[].amount_refundable_minor |
string | Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…). |
data[].refund_count |
integer | Collections only: the number of refunds that did not fail. |
data[].partial_refund_deadline |
string | Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled. |
page |
integer | |
per_page |
integer |
Error
| Field | Type | Description |
|---|---|---|
error |
object | |
error.code |
string | |
error.message |
string |
Operation
One money operation — collection, payout, refund, transfer or rebalance. The same object across all five families.
| Field | Type | Description |
|---|---|---|
id |
string | The operation's public id. It is the one in the /v1/payments/{id} paths. |
ref |
string | Our internal, readable reference. Distinct from the id: quote this one to support. |
client_ref |
string | The reference you supplied at creation, returned unchanged. |
kind |
string | payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which. |
status |
string | The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail. |
outcome |
string | pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on. |
asset_id |
integer | The operation's asset, by its id (GET /v1/assets). |
amount_minor |
string | The GROSS amount in minor units, as a string. |
fee_minor |
string | The fee taken, in minor units. |
net_minor |
string | The net in minor units: amount_minor less fee_minor. |
platform_id |
integer | The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose. |
is_test |
boolean | True for an operation created with a test key. No real money moves. |
payment_url |
string | The hosted payment page, when the rail provides one. Absent until submission has succeeded. |
deeplink |
string | The deep link into the rail's app, when it provides one. |
qrcode_url |
string | The QR to show the payer, when the rail provides one. |
risk |
Risk | The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block. |
risk.status |
string | held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report. |
risk.case_ref |
string | The operational case reference, to quote to support. Null when the hold is a compliance review. |
risk.case_kind |
string | Accompanies case_ref, or nothing at all. |
risk.reason |
string | The only free text this block carries, and it is identical for every hold. |
risk.signals |
object[] | Product signals, advisory. Absent when there are none. |
risk.signals[].code |
string | |
risk.signals[].detail_fr |
string | |
amount_refunded_minor |
string | Collections only: the sum of SUCCEEDED refunds, in minor units. |
amount_refund_pending_minor |
string | Collections only: the sum of refunds IN PROGRESS, in minor units. |
amount_refundable_minor |
string | Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…). |
refund_count |
integer | Collections only: the number of refunds that did not fail. |
partial_refund_deadline |
string | Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled. |