Skip to main content
POST
Convert between your own wallets — money moves

Authorizations

X-AptaPay-Signature
string
header
required

v1={hex HMAC-SHA256} over the ten-field canonical string. Sent alongside X-AptaPay-Key, X-AptaPay-Timestamp and X-AptaPay-Nonce — all four are required. OpenAPI can only model one header per scheme, so the other three are described in the Authentication section above.

Headers

Idempotency-Key
string
required

Required. A missing key is a 400 — never a server-generated one.

Maximum string length: 255

Body

application/json
from
enum<string>
required

Source currency. Must differ from to.

Available options:
UGX,
RWF,
XAF,
XOF,
KES,
GHS,
NGN,
TZS,
ZMW,
USD,
EUR,
GBP
to
enum<string>
required

Destination currency.

Available options:
UGX,
RWF,
XAF,
XOF,
KES,
GHS,
NGN,
TZS,
ZMW,
USD,
EUR,
GBP
amount
string
required

Major units as a decimal STRING. See /v1/fx/quote.

Example:

"1000"

Response

The conversion that was applied.

The single response envelope, used by EVERY endpoint so a consuming app parses one shape everywhere.

code
integer
required
Example:

200

message
string
required
Example:

"OK"

data
any

Present on success. Shape varies per endpoint.

error
object

Machine-readable error classification. EXACTLY ONE of terminal/retriable/ ambiguous is true. laces_api inferred this from the HTTP status and got it wrong, stranding real money twice (2026-08-15, 2026-08-16). Branch on these booleans, never on the status code:

terminal -> the provider refused. Reverse the debit and tell the user. retriable -> safe to retry with the SAME Idempotency-Key. ambiguous -> the outcome is UNKNOWN. Do NOT reverse. Poll instead.