All endpoints
All 63 endpoints, generated from the same middleware the server runs.
Every endpoint, generated from the same middleware the server runs, so it
cannot drift from the API it describes. The document itself is at
/openapi.json here, and served live
by every deployment at GET /v1/openapi.json.
If you are writing the integration rather than looking something up, start at the API reference instead — same endpoints, fewer of them, with working requests in six languages.
Using the document
It is an ordinary OpenAPI 3.1 file. Feed it to whatever you already use.
# Any language openapi-generator supports.
npx @openapitools/openapi-generator-cli generate \
-i https://api.payment.unifiwallet.com/v1/openapi.json \
-g typescript-fetch \
-o ./unifiwallet-client
# The signing still has to be added around it — see Authentication.
# Import the document directly:
# File → Import → Link
# https://api.payment.unifiwallet.com/v1/openapi.json
#
# Requests will 401 until you add the signing headers. There is a
# pre-request script in the authentication guide that computes them.
# Point any Swagger UI at the document:
docker run -p 8080:8080 \
-e SWAGGER_JSON_URL=https://api.payment.unifiwallet.com/v1/openapi.json \
swaggerapi/swagger-ui
# "Try it out" will not work — see the note above.
Try-it-out cannot work here, in any tool.
Every request carries an HMAC over its own body, computed with your secret.
A browser can only do that if the secret is in the browser — and a secret
that reaches a browser is a secret you have published. Any explorer you
point at this document will return 401 on every call until you
add the signing yourself.
That is why this page renders the document rather than embedding an explorer: a button that always fails teaches people to distrust the page. Use the signed client instead — it is twenty lines and you need it in production anyway.
Conventions
- Money is a decimal string. Never a float.
- A field marked · beside its name is required.
- Lists return
{ object, data, has_more, next_cursor }. - Every
POSTon the machine plane needs anIdempotency-Key. - Unknown response fields are added over time. Ignore what you do not recognise.
What is not in here
The merchant panel's own endpoints and the sign-in routes. They exist for our front end, they change when it changes, and publishing them as a contract would promise a stability we do not intend to offer — somebody would generate a client from them and we would break it.
Payments
GET
/v1/payments
List payments
Scope: payments:read
200 A page of payments, newest first.
Returns PaymentList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of Payment |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
POST
/v1/payments
Create a payment
Fixes the fee, the rate and the settlement address onto the payment, so what settles is what was quoted — including weeks later, if it comes to an argument.
Requires an Idempotency-Key header.
Scope: payments:write
| Field | Type | |
|---|---|---|
amount · |
string | What to charge, as a decimal string in currency — "49.99", not 4999 and not 49.99 the float. Sending money as a float is how you lose a cent a thousand times., matches ^\d+(\.\d+)?$ |
currency · |
string | The currency the price is quoted in: a fiat code such as USD or EUR, or a token symbol to price directly in crypto., at least 2 characters, up to 10 characters |
merchant_order_id |
string | Your own order number. Returned on every event and settlement so you can reconcile without storing our ids., up to 200 characters |
description |
string | What the buyer is paying for. Shown on the hosted checkout page., up to 500 characters |
customer |
object | Who is paying. Every field is optional — a payment needs no customer at all. |
customer.reference |
string | Your id for this customer. |
customer.email |
string (email) | Where the receipt goes, and where a refund notice goes. |
customer.email_receipt |
boolean | Send the buyer a receipt when the payment settles. |
customer.address |
object | Billing address, used for tax and for the invoice. |
customer.tax_id |
object | The buyer's tax registration, for a reverse-charge invoice. |
customer.refund_address |
string | Where a refund should go. If absent, refunds go back to the wallet that paid. |
line_items |
array of object | The itemised breakdown. When present, the lines must sum to amount. |
discounts |
array of object | Reductions applied before tax. |
tax_behavior |
inclusive · exclusive |
Whether amount already contains the tax (inclusive) or the tax is added on top (exclusive). |
tax_rate_percent |
number | A single rate to apply to the whole payment, when you are not using tax rate ids., min 0, max 100 |
settlement |
object | Where this payment pays out, when not the account default. |
settlement.destination_id |
string | A verified destination on your account. Overrides the account default for this payment only. |
settlement.address |
string | Pay this one out to an address that is not on your account — a marketplace paying the seller who made the sale. Refused unless per-payment routing is switched on in the panel, because an API key that can name any payout address is an API key that can drain the account., matches ^0x[a-fA-F0-9]{40}$ |
settlement.asset |
string | Token to settle in. |
settlement.chain_id |
number | Chain to settle on. |
capture_method |
automatic · manual |
automatic settles as soon as the funds confirm. manual holds the payment authorised until you call capture — for orders you might not be able to fulfil. |
hold_window_hours |
number | For a manual payment: how long the funds stay held before the buyer may reclaim them. Defaults to your account setting, and is capped by the platform maximum — 168 hours is what a card authorization gets., min 1 |
rate_mode |
fixed_rate · floating_rate |
fixed_rate locks the crypto amount for rate_lock_seconds, so you carry no price risk inside the window. floating_rate prices at confirmation. |
rate_lock_seconds |
number | How long a fixed rate holds, in seconds. Longer costs a wider spread., min 300, max 1800 |
payer_address_hint |
string | The wallet you expect to pay, when you already know it. |
return_url |
string (uri) | Where the buyer lands after paying. Never treat arriving here as proof of payment — the webhook is the proof. |
cancel_url |
string (uri) | Where the buyer lands if they abandon the checkout. |
failure_url |
string (uri) | Where the buyer lands if the payment fails. |
expires_in |
number | Seconds until the payment expires unpaid. Anything arriving after that is refunded, not settled., min 60, max 86400 |
fee_payer |
merchant · buyer |
Who carries the gateway fee. buyer adds it to the amount they are shown. |
gas_payer |
merchant · buyer |
Who carries the network fee for putting this payment on chain. buyer adds it to their total; merchant takes it from the settlement. Defaults to the account setting. A held payment is two transactions, so it is priced as two. |
metadata |
object | Your own key/value pairs, returned on every event. Never put anything secret here — it is echoed to your webhook endpoint and visible in the panel. |
201 The payment, with a checkout_url to send the buyer to.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
GET
/v1/payments/{id}
Retrieve a payment
Scope: payments:read
200 The payment, including the snapshot of the terms that applied.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
POST
/v1/payments/{id}/cancel
Cancel a payment
Only one nobody has paid. Money already on chain must be refunded instead. Cancelling cannot reach into the buyer's wallet: an order they signed before the deadline can still be mined, and arrives as payment.late_settled.
Requires an Idempotency-Key header.
Scope: payments:write
200 Success.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
POST
/v1/payments/{id}/capture
Capture an authorized payment
Part of authorize-and-capture, which is not available yet.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: payments:capture
| Field | Type | |
|---|---|---|
amount |
string | How much of the authorised amount to take, as a decimal string. Defaults to all of it. The remainder is released, not held. |
200 Success.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
GET
/v1/payments/{id}/events
Payment status history
The states this payment has been through, with reasons. The fastest answer to "why is this stuck", and better than inferring it from the current state.
Scope: payments:read
200 Success.
POST
/v1/payments/{id}/expire
Expire a payment early
Requires an Idempotency-Key header.
Scope: payments:write
200 Success.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
POST
/v1/payments/{id}/void
Void an authorization
Part of authorize-and-capture, which is not available yet.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: payments:capture
200 Success.
Returns Payment.
| Property | Type | |
|---|---|---|
id |
string | The payment. Ids are prefixed pay_ and opaque; do not parse them. |
object |
string | Always payment. |
mode |
live · test |
Whether this is real money or test money. |
status |
requires_payment · processing · requires_capture · succeeded · canceled · expired · failed · refunded · partially_refunded |
Where the payment is. succeeded is the only status that means you have been paid — and even then, on a non-custodial gateway, paid means the funds reached your address. |
amount |
string | What was charged, in currency. Decimal string — never parse it as a float. |
currency |
string | Currency the price was quoted in. |
merchant_order_id |
string | Your own order number, as you sent it. |
description |
string | What the buyer is paying for. |
metadata |
object | Your own key/value pairs, as you sent them. |
customer |
object | Who is paying. Only the fields safe to return. |
customer.reference |
string | Your id for this customer. |
customer.country |
string | Two-letter country code, where one was given. |
customer.refund_address |
string | Where a refund of this payment would go. |
required |
object | Exactly what the buyer has to send, once they have chosen an asset. |
required.asset |
string | Token symbol. |
required.chain_id |
number | Chain the payment must arrive on. |
required.amount |
string | The amount in that token. Decimal string — never parse it as a float. |
required.amount_base_units |
string | The same amount in the token's smallest unit. This is the figure to compare against an on-chain value; the decimal form is for people. |
rate_lock |
object | The held exchange rate, when rate_mode is fixed_rate. |
rate_lock.rate |
string | Units of the token per unit of currency. |
rate_lock.source |
string | Which price feed it came from. |
rate_lock.locked_at |
string (date-time) | When it was struck. |
rate_lock.expires_at |
string (date-time) | When it stops being honoured. After this the buyer is re-quoted. |
rate_lock.tolerance_bps |
number | How far the market may move before the payment is short-paid, in basis points. |
snapshot |
object | The terms as they stood when the payment was created. Frozen on purpose: changing your account settings must not change what an outstanding payment costs, or where it pays out. |
snapshot.fee_plan_version |
string | Which fee plan applied. |
snapshot.capture_method |
automatic · manual |
As requested. |
snapshot.authorization_expires_at |
string (date-time) | When an uncaptured authorisation is released. |
snapshot.rate_mode |
fixed_rate · floating_rate |
As requested. |
snapshot.settlement |
object | Where this payment pays out, resolved at creation. |
snapshot.collector |
string | The address or contract the buyer sends to. |
snapshot.confirmations_required |
number | Confirmations before the money is treated as arrived. |
snapshot.fee_bps |
number | What the contract enforces: the gateway fee plus whatever share of the network fee this payment's settings put on it. |
snapshot.gas_base_units |
string | The estimated network fee for this payment, in the settlement asset's base units. A held payment is two transactions and is priced as two. |
snapshot.gas_payer |
buyer · merchant |
Who carries that network fee. |
snapshot.tax |
object | Tax as computed at creation. |
snapshot.totals |
object | The arithmetic: subtotal, discount, tax, total. |
escrow_operation |
object | A capture or void that has been sent and not yet confirmed. While this is present, another one is refused — that is what stops a buyer being charged twice. |
escrow_operation.kind |
capture · void · reclaim |
What was sent. |
escrow_operation.tx_hash |
string | The transaction to watch. |
escrow_operation.amount_base_units |
string | How much it was for. |
escrow_operation.submitted_at |
string (date-time) | When it was sent. |
deposit_return |
object | Money owed back to the buyer from a deposit address, and how the return is going. |
deposit_return.state |
pending · failed · returned |
returned is done; failed needs a person. |
deposit_return.reason |
string | Why the last attempt did not land. |
deposit_return.attempts |
number | Attempts made so far. |
deposit_return.tx_hash |
string | The transaction that returned it, once one did. |
intent_address |
string | The single-use deposit address for this payment, when the buyer chose to pay by transfer rather than by contract call. |
payer_address |
string | The wallet that paid, once seen. |
confirmations |
number | Confirmations counted so far. |
amount_capturable |
string | Authorised and still capturable. Decimal string — never parse it as a float. |
amount_captured |
string | Captured so far. Decimal string — never parse it as a float. |
expires_at |
string (date-time) | When an unpaid payment stops being payable. |
created_at |
string (date-time) | When it was created. |
Checkout
GET
/v1/checkout/{token}
What the buyer sees
Public — the token is the authorisation. Treat it as a capability: whoever holds it can quote and submit this checkout, so keep it out of logs and analytics.
Scope: none
200 Success.
POST
/v1/checkout/{token}/authorize
Build an escrow authorization
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
asset · |
string | Token the buyer is paying with. Must be one the merchant accepts. |
chain_id |
number | Chain the buyer is paying on. |
payer_address · |
string | The wallet that will send the funds. The returned calldata is built for it. |
200 Success.
POST
/v1/checkout/{token}/deposit-address
Issue a deposit address
For wallets that cannot sign a contract call. Derived deterministically, and fixed once issued — the refund address is part of how it is derived. ERC-20 settlement assets only: a native-coin transfer leaves no log to observe. Anything unforwarded at expiry is returned to the refund address.
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
refund_address |
string | Where to send funds if this payment is refunded or overpaid. Worth collecting: a deposit address has no sender to refund to automatically., matches ^0x[a-fA-F0-9]{40}$ |
200 Success.
POST
/v1/checkout/{token}/quote
Quote an asset and build the call
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
asset · |
string | Symbol of the token the buyer intends to pay with, as listed by GET /v1/assets. |
chain_id |
number | Chain the buyer is paying on. Defaults to the asset's only chain when it has one. |
payer_address · |
string | The wallet that will send the funds. Used to price gas and to check the balance. |
refund_address |
string | Where a refund of this payment should go, if it is not the paying wallet., matches ^0x[a-fA-F0-9]{40}$ |
refund_address_signature |
string | Signature from payer_address over the refund address. Required whenever refund_address is given: whoever holds the checkout link is not necessarily the buyer., matches ^0x[a-fA-F0-9]+$ |
200 Success.
POST
/v1/checkout/{token}/simulate
Simulate an outcome (test mode)
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
outcome |
string | Which ending to act out — see GET /v1/test/outcomes. Defaults to a successful payment. Refused for a live payment. |
200 Success.
GET
/v1/checkout/{token}/status
Poll a checkout
Scope: none
200 Success.
POST
/v1/checkout/{token}/submit
Report the transaction
A claim, not proof. The payment moves to settling and the hash is checked: if it reverts or settles nothing, the checkout reopens (payment.submission_failed). Settlement is only ever recognised from the chain event.
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
tx_hash · |
string | Hash of the transaction the buyer broadcast. Watching starts from it; the payment still only settles on a confirmed on-chain event. |
payer_address |
string | The wallet that sent it, when known. |
200 Success.
Subscriptions
GET
/v1/subscriptions
List subscriptions
Scope: payments:read
200 Success.
Returns SubscriptionList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of Subscription |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
POST
/v1/subscriptions
Create a subscription
Charges nothing. A new subscription stays incomplete until the buyer acts — read that literally, or you will ship for nothing.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: payments:write
| Field | Type | |
|---|---|---|
amount · |
string | Price of one cycle, as a decimal string in currency., matches ^\d+(\.\d{1,8})?$ |
currency · |
string | Currency the cycle price is quoted in, as a three-letter code., exactly 3 characters |
interval · |
day · week · month · year |
The billing period. month and year follow the calendar, so a subscription started on the 31st bills on the last day of a shorter month. |
interval_count |
integer | Number of intervals per cycle — interval: "month", interval_count: 3 bills quarterly. Defaults to 1., min 1, max 52 |
collection_method |
auto_charge · payment_link |
auto_charge takes each cycle from a spend permission the buyer signed once. payment_link emails a fresh payment every cycle and takes nothing on its own. |
description |
string | What the buyer is subscribing to. Shown when they authorise it., up to 500 characters |
merchant_reference |
string | Your own id for this subscription., up to 200 characters |
trial_end |
string (date-time) | When the free period ends, ISO 8601. The first cycle is billed then, not now. |
ends_at |
string (date-time) | When the subscription stops on its own, ISO 8601. Absent means it runs until cancelled. |
allowance_multiplier |
number | Headroom in the signed spend permission, as a multiple of one cycle. 2 lets the price rise up to double before the buyer has to sign again. It does not let you charge more than a cycle in a period — the on-chain permission caps that., min 1, max 12 |
settlement |
object | Where each cycle of this subscription pays out. |
settlement.destination_id |
string | A verified destination on your account. |
settlement.address |
string | An address off your account. Needs per-payment routing switched on in the panel., matches ^0x[a-fA-F0-9]{40}$ |
settlement.asset |
string | Token to settle in. |
settlement.chain_id |
number | Chain to settle on. |
customer |
object | Who is subscribing. |
customer.reference |
string | Your id for this customer., up to 200 characters |
customer.email |
string (email) | Where the authorisation request and the cycle receipts go. |
customer.wallet_address |
string | The wallet that will sign the spend permission, when you already know it., matches ^0x[a-fA-F0-9]{40}$ |
customer.address |
object | Billing address. |
metadata |
object | Your own key/value pairs, echoed on every cycle event. |
201 The subscription, and for auto-charge the structure the buyer signs.
Returns Subscription.
| Property | Type | |
|---|---|---|
id |
string | The subscription. Ids are prefixed sub_ and opaque; do not parse them. |
object |
string | Always subscription. |
mode |
live · test |
Real money or test money. |
status |
incomplete · trialing · active · past_due · canceled · ended |
Creating a subscription charges nothing. It cannot bill until it reaches active. |
collection_method |
auto_charge · payment_link |
How each cycle is collected. |
amount |
string | Price of one cycle. Decimal string — never parse it as a float. |
currency |
string | Currency of the cycle price. |
description |
string | What the buyer subscribed to. |
merchant_reference |
string | Your own id. |
metadata |
object | Your own key/value pairs. |
interval |
day · week · month · year |
The billing period. |
interval_count |
number | Intervals per cycle. |
trial_end |
string (date-time) | When the free period ends. |
ends_at |
string (date-time) | When the subscription stops on its own. |
customer |
object | Who is subscribing. |
customer.reference |
string | Your id for them. |
customer.country |
string | Two-letter country code. |
customer.payer_address |
string | The wallet paying. |
settlement |
object | Where cycles pay out. |
settlement.destination_id |
string | Destination used. |
settlement.target |
string | How it resolves. |
settlement.address |
string | The receiving address. Signed into the permission, so it cannot be changed without the buyer signing again. |
settlement.asset |
string | Token settled in. |
settlement.chain_id |
number | Chain settled on. |
fee_bps |
number | Gateway fee in basis points, as signed. |
spend_permission |
object | The on-chain authorisation. Never includes the signature: whoever holds that can submit an approval we did not initiate. |
spend_permission.account |
string | The buyer's wallet. |
spend_permission.token |
string | Token contract being spent. |
spend_permission.allowance |
string | Maximum per period, in base units. |
spend_permission.allowance_formatted |
string | The same allowance in human units. Decimal string — never parse it as a float. |
spend_permission.allowance_asset |
string | Which token that allowance is in. |
spend_permission.period_seconds |
number | Length of a spending period. The allowance resets each period and does not accumulate. |
spend_permission.start |
number | Unix time it becomes usable. |
spend_permission.end |
number | Unix time it expires. |
spend_permission.chain_id |
number | Chain it is valid on. |
spend_permission.manager |
string | Address of the SpendPermissionManager holding it. |
spend_permission.hash |
string | EIP-712 hash of the permission. What the contract keys revocation on. |
spend_permission.approved_at |
string (date-time) | When the buyer signed. |
spend_permission.revoked_at |
string (date-time) | When it was revoked, on-chain or by cancellation. |
cycle_count |
number | Cycles opened so far. |
current_period_start |
string (date-time) | Start of the period being paid for. |
current_period_end |
string (date-time) | End of it. |
next_charge_at |
string (date-time) | When the next charge is attempted. |
last_charged_at |
string (date-time) | When the last successful charge happened. |
failure_count |
number | Consecutive failed cycles. |
last_failure_reason |
string | Why the last one failed. |
cancel_at_period_end |
boolean | Whether it stops when the paid period runs out. |
canceled_at |
string (date-time) | When it was cancelled. |
created_at |
string (date-time) | When it was created. |
GET
/v1/subscriptions/{id}
Retrieve a subscription
Includes whether the spend permission is still live on chain. The buyer can revoke without telling us, so the stored status is a guess until the chain is asked.
Scope: payments:read
200 Success.
Returns Subscription.
| Property | Type | |
|---|---|---|
id |
string | The subscription. Ids are prefixed sub_ and opaque; do not parse them. |
object |
string | Always subscription. |
mode |
live · test |
Real money or test money. |
status |
incomplete · trialing · active · past_due · canceled · ended |
Creating a subscription charges nothing. It cannot bill until it reaches active. |
collection_method |
auto_charge · payment_link |
How each cycle is collected. |
amount |
string | Price of one cycle. Decimal string — never parse it as a float. |
currency |
string | Currency of the cycle price. |
description |
string | What the buyer subscribed to. |
merchant_reference |
string | Your own id. |
metadata |
object | Your own key/value pairs. |
interval |
day · week · month · year |
The billing period. |
interval_count |
number | Intervals per cycle. |
trial_end |
string (date-time) | When the free period ends. |
ends_at |
string (date-time) | When the subscription stops on its own. |
customer |
object | Who is subscribing. |
customer.reference |
string | Your id for them. |
customer.country |
string | Two-letter country code. |
customer.payer_address |
string | The wallet paying. |
settlement |
object | Where cycles pay out. |
settlement.destination_id |
string | Destination used. |
settlement.target |
string | How it resolves. |
settlement.address |
string | The receiving address. Signed into the permission, so it cannot be changed without the buyer signing again. |
settlement.asset |
string | Token settled in. |
settlement.chain_id |
number | Chain settled on. |
fee_bps |
number | Gateway fee in basis points, as signed. |
spend_permission |
object | The on-chain authorisation. Never includes the signature: whoever holds that can submit an approval we did not initiate. |
spend_permission.account |
string | The buyer's wallet. |
spend_permission.token |
string | Token contract being spent. |
spend_permission.allowance |
string | Maximum per period, in base units. |
spend_permission.allowance_formatted |
string | The same allowance in human units. Decimal string — never parse it as a float. |
spend_permission.allowance_asset |
string | Which token that allowance is in. |
spend_permission.period_seconds |
number | Length of a spending period. The allowance resets each period and does not accumulate. |
spend_permission.start |
number | Unix time it becomes usable. |
spend_permission.end |
number | Unix time it expires. |
spend_permission.chain_id |
number | Chain it is valid on. |
spend_permission.manager |
string | Address of the SpendPermissionManager holding it. |
spend_permission.hash |
string | EIP-712 hash of the permission. What the contract keys revocation on. |
spend_permission.approved_at |
string (date-time) | When the buyer signed. |
spend_permission.revoked_at |
string (date-time) | When it was revoked, on-chain or by cancellation. |
cycle_count |
number | Cycles opened so far. |
current_period_start |
string (date-time) | Start of the period being paid for. |
current_period_end |
string (date-time) | End of it. |
next_charge_at |
string (date-time) | When the next charge is attempted. |
last_charged_at |
string (date-time) | When the last successful charge happened. |
failure_count |
number | Consecutive failed cycles. |
last_failure_reason |
string | Why the last one failed. |
cancel_at_period_end |
boolean | Whether it stops when the paid period runs out. |
canceled_at |
string (date-time) | When it was cancelled. |
created_at |
string (date-time) | When it was created. |
GET
/v1/subscriptions/{id}/authorization
The permission the buyer signs
An EIP-712 structure with the ceiling, the period, your address and the fee all inside it, plus a plain-language summary of what the buyer is agreeing to.
Scope: payments:read
200 Success.
POST
/v1/subscriptions/{id}/authorize
Submit the signature
Makes the subscription billable. Verified here, not only on chain.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: payments:write
| Field | Type | |
|---|---|---|
permission · |
object | The permission the buyer signed, field for field. It must match the one we issued exactly; anything else is refused rather than reconciled. |
permission.account · |
string | The buyer's wallet — the account being debited., matches ^0x[a-fA-F0-9]{40}$ |
permission.spender · |
string | The contract allowed to pull, from GET /v1/subscriptions/{id}/authorization., matches ^0x[a-fA-F0-9]{40}$ |
permission.token · |
string | Contract address of the token being spent., matches ^0x[a-fA-F0-9]{40}$ |
permission.recipient · |
string | Where each charge lands — your settlement address. Signed by the buyer, so we cannot redirect it afterwards., matches ^0x[a-fA-F0-9]{40}$ |
permission.fee_recipient · |
string | Where the gateway fee lands. Also signed, for the same reason., matches ^0x[a-fA-F0-9]{40}$ |
permission.fee_bps · |
integer | The fee, in basis points, capped at 500. The buyer signs the number, so it cannot be raised later., min 0, max 500 |
permission.allowance · |
string | Maximum spendable per period, in the token's base units, as a decimal string., matches ^\d+$ |
permission.period · |
integer | Length of a spending period in seconds. Allowance resets each period and does not accumulate: an unused period is lost, not banked., min 60 |
permission.start · |
integer | Unix time the permission becomes usable. |
permission.end · |
integer | Unix time it stops. Charges after this fail on-chain, not in our code. |
permission.salt · |
string | Uniqueness value, so two identical permissions are distinguishable., matches ^\d+$ |
permission.chain_id |
number | Chain the permission is for. |
signature · |
string | The buyer's EIP-712 signature over permission. Smart-contract wallets are checked through ERC-1271., matches ^0x[a-fA-F0-9]+$ |
200 Success.
Returns Subscription.
| Property | Type | |
|---|---|---|
id |
string | The subscription. Ids are prefixed sub_ and opaque; do not parse them. |
object |
string | Always subscription. |
mode |
live · test |
Real money or test money. |
status |
incomplete · trialing · active · past_due · canceled · ended |
Creating a subscription charges nothing. It cannot bill until it reaches active. |
collection_method |
auto_charge · payment_link |
How each cycle is collected. |
amount |
string | Price of one cycle. Decimal string — never parse it as a float. |
currency |
string | Currency of the cycle price. |
description |
string | What the buyer subscribed to. |
merchant_reference |
string | Your own id. |
metadata |
object | Your own key/value pairs. |
interval |
day · week · month · year |
The billing period. |
interval_count |
number | Intervals per cycle. |
trial_end |
string (date-time) | When the free period ends. |
ends_at |
string (date-time) | When the subscription stops on its own. |
customer |
object | Who is subscribing. |
customer.reference |
string | Your id for them. |
customer.country |
string | Two-letter country code. |
customer.payer_address |
string | The wallet paying. |
settlement |
object | Where cycles pay out. |
settlement.destination_id |
string | Destination used. |
settlement.target |
string | How it resolves. |
settlement.address |
string | The receiving address. Signed into the permission, so it cannot be changed without the buyer signing again. |
settlement.asset |
string | Token settled in. |
settlement.chain_id |
number | Chain settled on. |
fee_bps |
number | Gateway fee in basis points, as signed. |
spend_permission |
object | The on-chain authorisation. Never includes the signature: whoever holds that can submit an approval we did not initiate. |
spend_permission.account |
string | The buyer's wallet. |
spend_permission.token |
string | Token contract being spent. |
spend_permission.allowance |
string | Maximum per period, in base units. |
spend_permission.allowance_formatted |
string | The same allowance in human units. Decimal string — never parse it as a float. |
spend_permission.allowance_asset |
string | Which token that allowance is in. |
spend_permission.period_seconds |
number | Length of a spending period. The allowance resets each period and does not accumulate. |
spend_permission.start |
number | Unix time it becomes usable. |
spend_permission.end |
number | Unix time it expires. |
spend_permission.chain_id |
number | Chain it is valid on. |
spend_permission.manager |
string | Address of the SpendPermissionManager holding it. |
spend_permission.hash |
string | EIP-712 hash of the permission. What the contract keys revocation on. |
spend_permission.approved_at |
string (date-time) | When the buyer signed. |
spend_permission.revoked_at |
string (date-time) | When it was revoked, on-chain or by cancellation. |
cycle_count |
number | Cycles opened so far. |
current_period_start |
string (date-time) | Start of the period being paid for. |
current_period_end |
string (date-time) | End of it. |
next_charge_at |
string (date-time) | When the next charge is attempted. |
last_charged_at |
string (date-time) | When the last successful charge happened. |
failure_count |
number | Consecutive failed cycles. |
last_failure_reason |
string | Why the last one failed. |
cancel_at_period_end |
boolean | Whether it stops when the paid period runs out. |
canceled_at |
string (date-time) | When it was cancelled. |
created_at |
string (date-time) | When it was created. |
POST
/v1/subscriptions/{id}/cancel
Stop charging
Stops us charging. It does not revoke the buyer's on-chain permission — only they can, from their own wallet. The response includes the call they would make.
Requires an Idempotency-Key header.
Scope: payments:write
| Field | Type | |
|---|---|---|
at_period_end |
boolean | Let the paid-for cycle run to its end instead of stopping now. Default is to stop immediately. |
reason |
string | Why, for your own records and the audit log., up to 500 characters |
200 Success.
Returns Subscription.
| Property | Type | |
|---|---|---|
id |
string | The subscription. Ids are prefixed sub_ and opaque; do not parse them. |
object |
string | Always subscription. |
mode |
live · test |
Real money or test money. |
status |
incomplete · trialing · active · past_due · canceled · ended |
Creating a subscription charges nothing. It cannot bill until it reaches active. |
collection_method |
auto_charge · payment_link |
How each cycle is collected. |
amount |
string | Price of one cycle. Decimal string — never parse it as a float. |
currency |
string | Currency of the cycle price. |
description |
string | What the buyer subscribed to. |
merchant_reference |
string | Your own id. |
metadata |
object | Your own key/value pairs. |
interval |
day · week · month · year |
The billing period. |
interval_count |
number | Intervals per cycle. |
trial_end |
string (date-time) | When the free period ends. |
ends_at |
string (date-time) | When the subscription stops on its own. |
customer |
object | Who is subscribing. |
customer.reference |
string | Your id for them. |
customer.country |
string | Two-letter country code. |
customer.payer_address |
string | The wallet paying. |
settlement |
object | Where cycles pay out. |
settlement.destination_id |
string | Destination used. |
settlement.target |
string | How it resolves. |
settlement.address |
string | The receiving address. Signed into the permission, so it cannot be changed without the buyer signing again. |
settlement.asset |
string | Token settled in. |
settlement.chain_id |
number | Chain settled on. |
fee_bps |
number | Gateway fee in basis points, as signed. |
spend_permission |
object | The on-chain authorisation. Never includes the signature: whoever holds that can submit an approval we did not initiate. |
spend_permission.account |
string | The buyer's wallet. |
spend_permission.token |
string | Token contract being spent. |
spend_permission.allowance |
string | Maximum per period, in base units. |
spend_permission.allowance_formatted |
string | The same allowance in human units. Decimal string — never parse it as a float. |
spend_permission.allowance_asset |
string | Which token that allowance is in. |
spend_permission.period_seconds |
number | Length of a spending period. The allowance resets each period and does not accumulate. |
spend_permission.start |
number | Unix time it becomes usable. |
spend_permission.end |
number | Unix time it expires. |
spend_permission.chain_id |
number | Chain it is valid on. |
spend_permission.manager |
string | Address of the SpendPermissionManager holding it. |
spend_permission.hash |
string | EIP-712 hash of the permission. What the contract keys revocation on. |
spend_permission.approved_at |
string (date-time) | When the buyer signed. |
spend_permission.revoked_at |
string (date-time) | When it was revoked, on-chain or by cancellation. |
cycle_count |
number | Cycles opened so far. |
current_period_start |
string (date-time) | Start of the period being paid for. |
current_period_end |
string (date-time) | End of it. |
next_charge_at |
string (date-time) | When the next charge is attempted. |
last_charged_at |
string (date-time) | When the last successful charge happened. |
failure_count |
number | Consecutive failed cycles. |
last_failure_reason |
string | Why the last one failed. |
cancel_at_period_end |
boolean | Whether it stops when the paid period runs out. |
canceled_at |
string (date-time) | When it was cancelled. |
created_at |
string (date-time) | When it was created. |
POST
/v1/subscriptions/{id}/charge
Charge a cycle now
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: payments:write
200 Success.
GET
/v1/subscriptions/{id}/cycles
List billing cycles
Every period and what happened to it, including the ones that failed and how often they were retried.
Scope: payments:read
200 Success.
Returns SubscriptionCycleList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of SubscriptionCycle |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
Settlements
GET
/v1/settlements
What actually arrived
Gross, fee, net and the transaction hash. Refused events are excluded; ask for them with ?status=quarantined.
Scope: settlements:read
200 Success.
Returns SettlementList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of Settlement |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
GET
/v1/settlements/{id}
Retrieve a settlement
Scope: settlements:read
200 Success.
Returns Settlement.
| Property | Type | |
|---|---|---|
id |
string | The settlement. Ids are prefixed stl_ and opaque; do not parse them. |
object |
string | Always settlement. |
payment_id |
string | The payment this settles. |
path |
string | How it was settled — direct, router, or swept from a deposit address. |
chain_id |
number | Chain it happened on. |
tx_hash |
string | The transaction. This is the receipt; everything else here is derived from it. |
block_number |
number | Block it was included in. |
block_timestamp |
string (date-time) | When that block was mined. |
asset |
string | Token received. |
gross |
string | What arrived. Decimal string — never parse it as a float. |
fee |
string | Gateway fee taken. Decimal string — never parse it as a float. |
gas |
string | Gas recovered, where the gateway paid it. Decimal string — never parse it as a float. |
net |
string | What reached your address. This is your revenue. Decimal string — never parse it as a float. |
excess_returned |
string | Overpayment sent back to the buyer. Decimal string — never parse it as a float. |
to_address |
string | Where the net went. |
fiat_value |
object | The value at settlement time, for your books. |
confirmations |
number | Confirmations at the last check. |
reorged |
boolean | Whether the block was later reorganised away. If true, this settlement did not happen and the payment went back to unpaid. |
status |
recorded · quarantined |
A quarantined settlement is a transaction that carried this payment's id but did not match its terms — wrong recipient, wrong token, too little. Nothing was credited. It is listed rather than hidden so you can see the attempt. |
mismatches |
array of string | On a quarantined settlement, which terms disagreed. |
note |
string | On a quarantined settlement, a plain-language explanation. |
created_at |
string (date-time) | When it was recorded. |
GET
/v1/settlements/summary
Volume by asset and chain
Scope: settlements:read
200 Success.
GET
/v1/statements
Flow records with fiat valuations
Valued at the moment each one arrived, which is what an accountant needs.
Scope: settlements:read
200 Success.
Destinations
GET
/v1/destinations
List settlement destinations
Scope: account:read
200 Success.
Returns SettlementDestinationList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of SettlementDestination |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
POST
/v1/destinations
Register a destination
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
| Field | Type | |
|---|---|---|
kind · |
shield · address |
shield settles into a UnifiWallet Shield account by code. address settles to a wallet you control and must be verified by signature before it can receive. |
shield_code |
string | The Shield code to pay into. Required when kind is shield. |
address |
string | The wallet to pay into. Required when kind is address. |
chains |
array of number | Chain ids this destination can receive on. Defaults to every chain the asset exists on. |
asset |
string | Restrict this destination to one token. Absent means any accepted token. |
label |
string | Your name for it, shown in the panel., up to 100 characters |
201 Success.
Returns SettlementDestination.
| Property | Type | |
|---|---|---|
id |
string | The destination. Ids are prefixed dst_ and opaque; do not parse them. |
object |
string | Always settlement_destination. |
kind |
shield · address |
A Shield account, or a plain address. |
shield_code |
string | The Shield code, when that is what it is. |
resolved_address |
string | The address that actually receives. |
chains |
array of number | Chain ids it can receive on. |
asset |
string | Token it is restricted to, if any. |
label |
string | Your name for it. |
status |
pending_verification · pending_screening · active · blocked · removed |
A destination cannot receive until it is active. pending_verification means nobody has proved they hold the key yet. |
verified_at |
string (date-time) | When the signature proof was accepted. |
usable_at |
string (date-time) | When it may first be settled to. New destinations wait, so a stolen session cannot add an address and drain the next payment before anyone notices. |
screening_state |
string | Result of sanctions screening on the address. |
created_at |
string (date-time) | When it was added. |
verification |
object | Re-offered on every read while proof is outstanding, so closing the page between adding a destination and signing for it is not a dead end. |
verification.method |
string | Always signature. |
verification.message |
string | The exact message to sign with the destination wallet. |
verification.instructions |
string | What to do with it. |
GET
/v1/destinations/{id}
Retrieve a destination
Carries the verification message while ownership is unproved.
Scope: account:read
200 Success.
Returns SettlementDestination.
| Property | Type | |
|---|---|---|
id |
string | The destination. Ids are prefixed dst_ and opaque; do not parse them. |
object |
string | Always settlement_destination. |
kind |
shield · address |
A Shield account, or a plain address. |
shield_code |
string | The Shield code, when that is what it is. |
resolved_address |
string | The address that actually receives. |
chains |
array of number | Chain ids it can receive on. |
asset |
string | Token it is restricted to, if any. |
label |
string | Your name for it. |
status |
pending_verification · pending_screening · active · blocked · removed |
A destination cannot receive until it is active. pending_verification means nobody has proved they hold the key yet. |
verified_at |
string (date-time) | When the signature proof was accepted. |
usable_at |
string (date-time) | When it may first be settled to. New destinations wait, so a stolen session cannot add an address and drain the next payment before anyone notices. |
screening_state |
string | Result of sanctions screening on the address. |
created_at |
string (date-time) | When it was added. |
verification |
object | Re-offered on every read while proof is outstanding, so closing the page between adding a destination and signing for it is not a dead end. |
verification.method |
string | Always signature. |
verification.message |
string | The exact message to sign with the destination wallet. |
verification.instructions |
string | What to do with it. |
DELETE
/v1/destinations/{id}
Remove a destination
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
GET
/v1/destinations/{id}/balance
Live on-chain balance
Read from the chain. This is your wallet, not an account with us.
Scope: account:read
200 Success.
POST
/v1/destinations/{id}/verify
Prove you hold the wallet
Sign the message from the destination itself. Pasting an address proves nothing, and a settlement address nobody controls is money burnt on every future payment.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
| Field | Type | |
|---|---|---|
signature · |
string | Signature from the destination address over the challenge returned when it was created. Proves you hold the key, so a mistyped address cannot be settled to. |
200 Success.
Returns SettlementDestination.
| Property | Type | |
|---|---|---|
id |
string | The destination. Ids are prefixed dst_ and opaque; do not parse them. |
object |
string | Always settlement_destination. |
kind |
shield · address |
A Shield account, or a plain address. |
shield_code |
string | The Shield code, when that is what it is. |
resolved_address |
string | The address that actually receives. |
chains |
array of number | Chain ids it can receive on. |
asset |
string | Token it is restricted to, if any. |
label |
string | Your name for it. |
status |
pending_verification · pending_screening · active · blocked · removed |
A destination cannot receive until it is active. pending_verification means nobody has proved they hold the key yet. |
verified_at |
string (date-time) | When the signature proof was accepted. |
usable_at |
string (date-time) | When it may first be settled to. New destinations wait, so a stolen session cannot add an address and drain the next payment before anyone notices. |
screening_state |
string | Result of sanctions screening on the address. |
created_at |
string (date-time) | When it was added. |
verification |
object | Re-offered on every read while proof is outstanding, so closing the page between adding a destination and signing for it is not a dead end. |
verification.method |
string | Always signature. |
verification.message |
string | The exact message to sign with the destination wallet. |
verification.instructions |
string | What to do with it. |
Refunds
GET
/v1/refunds
List refunds
Scope: payments:read
200 Success.
Returns RefundList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of Refund |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
POST
/v1/refunds
Record a refund
Records what is owed, with a deadline. It does not move money — we never held it, so you send it and we verify it. Only for a completed payment: refunding one that a reorg can still take back would cost you twice.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: refunds:write
| Field | Type | |
|---|---|---|
payment_id · |
string | The settled payment being refunded. |
amount |
string | How much to return, as a decimal string. Defaults to the whole payment. Partial refunds may be repeated up to the full amount. |
to_address |
string | Where to send it. Defaults to the address the payment came from, which is the safe answer; naming a different one is only for a buyer who has told you to. |
reason |
string | Why, for your records and the buyer's receipt., up to 500 characters |
201 Success.
Returns Refund.
| Property | Type | |
|---|---|---|
id |
string | The refund. Ids are prefixed re_ and opaque; do not parse them. |
object |
string | Always refund. |
payment_id |
string | The payment being refunded. |
kind |
string | Whether this is a requested refund, an overpayment return, or a late payment sent back. |
amount |
string | Being returned. Decimal string — never parse it as a float. |
amount_base_units |
string | The same amount in the token's smallest unit. |
asset |
string | Token being returned. |
chain_id |
number | Chain it goes back on. |
to_address |
string | Where it goes. |
destination_kind |
buyer_confirmed · buyer_refund_address · payer_address |
How that address was chosen. payer_address is the wallet that paid — which is often an exchange withdrawal address that cannot receive, so a stated refund address wins over it. |
state |
pending · prepared · submitted · succeeded · failed · canceled |
Where the refund got to. |
requested_at |
string (date-time) | When it was asked for. |
sla_due_at |
string (date-time) | When you undertook to have sent it by. |
fulfilment_tx_hash |
string | The transaction that sent it. |
failure_reason |
string | Why the last submitted transaction did not complete this refund — reverted, no_matching_transfer, transfer_predates_payment, not_mined_after_24h, transfer_already_used. The refund is still owed. |
verified_at |
string (date-time) | When that transaction was seen confirmed. Until then the refund is a claim, not a fact. |
reason |
string | Why it was refunded. |
created_at |
string (date-time) | When the record was created. |
GET
/v1/refunds/{id}
Retrieve a refund
Scope: payments:read
200 Success.
Returns Refund.
| Property | Type | |
|---|---|---|
id |
string | The refund. Ids are prefixed re_ and opaque; do not parse them. |
object |
string | Always refund. |
payment_id |
string | The payment being refunded. |
kind |
string | Whether this is a requested refund, an overpayment return, or a late payment sent back. |
amount |
string | Being returned. Decimal string — never parse it as a float. |
amount_base_units |
string | The same amount in the token's smallest unit. |
asset |
string | Token being returned. |
chain_id |
number | Chain it goes back on. |
to_address |
string | Where it goes. |
destination_kind |
buyer_confirmed · buyer_refund_address · payer_address |
How that address was chosen. payer_address is the wallet that paid — which is often an exchange withdrawal address that cannot receive, so a stated refund address wins over it. |
state |
pending · prepared · submitted · succeeded · failed · canceled |
Where the refund got to. |
requested_at |
string (date-time) | When it was asked for. |
sla_due_at |
string (date-time) | When you undertook to have sent it by. |
fulfilment_tx_hash |
string | The transaction that sent it. |
failure_reason |
string | Why the last submitted transaction did not complete this refund — reverted, no_matching_transfer, transfer_predates_payment, not_mined_after_24h, transfer_already_used. The refund is still owed. |
verified_at |
string (date-time) | When that transaction was seen confirmed. Until then the refund is a claim, not a fact. |
reason |
string | Why it was refunded. |
created_at |
string (date-time) | When the record was created. |
POST
/v1/refunds/{id}/cancel
Withdraw a refund
Requires an Idempotency-Key header.
Scope: refunds:write
200 Success.
Returns Refund.
| Property | Type | |
|---|---|---|
id |
string | The refund. Ids are prefixed re_ and opaque; do not parse them. |
object |
string | Always refund. |
payment_id |
string | The payment being refunded. |
kind |
string | Whether this is a requested refund, an overpayment return, or a late payment sent back. |
amount |
string | Being returned. Decimal string — never parse it as a float. |
amount_base_units |
string | The same amount in the token's smallest unit. |
asset |
string | Token being returned. |
chain_id |
number | Chain it goes back on. |
to_address |
string | Where it goes. |
destination_kind |
buyer_confirmed · buyer_refund_address · payer_address |
How that address was chosen. payer_address is the wallet that paid — which is often an exchange withdrawal address that cannot receive, so a stated refund address wins over it. |
state |
pending · prepared · submitted · succeeded · failed · canceled |
Where the refund got to. |
requested_at |
string (date-time) | When it was asked for. |
sla_due_at |
string (date-time) | When you undertook to have sent it by. |
fulfilment_tx_hash |
string | The transaction that sent it. |
failure_reason |
string | Why the last submitted transaction did not complete this refund — reverted, no_matching_transfer, transfer_predates_payment, not_mined_after_24h, transfer_already_used. The refund is still owed. |
verified_at |
string (date-time) | When that transaction was seen confirmed. Until then the refund is a claim, not a fact. |
reason |
string | Why it was refunded. |
created_at |
string (date-time) | When the record was created. |
POST
/v1/refunds/{id}/prepare
Build the transaction to send
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: refunds:write
200 Success.
Returns Refund.
| Property | Type | |
|---|---|---|
id |
string | The refund. Ids are prefixed re_ and opaque; do not parse them. |
object |
string | Always refund. |
payment_id |
string | The payment being refunded. |
kind |
string | Whether this is a requested refund, an overpayment return, or a late payment sent back. |
amount |
string | Being returned. Decimal string — never parse it as a float. |
amount_base_units |
string | The same amount in the token's smallest unit. |
asset |
string | Token being returned. |
chain_id |
number | Chain it goes back on. |
to_address |
string | Where it goes. |
destination_kind |
buyer_confirmed · buyer_refund_address · payer_address |
How that address was chosen. payer_address is the wallet that paid — which is often an exchange withdrawal address that cannot receive, so a stated refund address wins over it. |
state |
pending · prepared · submitted · succeeded · failed · canceled |
Where the refund got to. |
requested_at |
string (date-time) | When it was asked for. |
sla_due_at |
string (date-time) | When you undertook to have sent it by. |
fulfilment_tx_hash |
string | The transaction that sent it. |
failure_reason |
string | Why the last submitted transaction did not complete this refund — reverted, no_matching_transfer, transfer_predates_payment, not_mined_after_24h, transfer_already_used. The refund is still owed. |
verified_at |
string (date-time) | When that transaction was seen confirmed. Until then the refund is a claim, not a fact. |
reason |
string | Why it was refunded. |
created_at |
string (date-time) | When the record was created. |
POST
/v1/refunds/{id}/submit
Submit the transaction hash
Verified on chain before the refund is marked complete, and one transfer can only ever settle one refund.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: refunds:write
| Field | Type | |
|---|---|---|
tx_hash · |
string | Hash of the transaction that sent the refund. The refund is only marked paid once that transaction is seen confirmed on-chain. |
200 Success.
Returns Refund.
| Property | Type | |
|---|---|---|
id |
string | The refund. Ids are prefixed re_ and opaque; do not parse them. |
object |
string | Always refund. |
payment_id |
string | The payment being refunded. |
kind |
string | Whether this is a requested refund, an overpayment return, or a late payment sent back. |
amount |
string | Being returned. Decimal string — never parse it as a float. |
amount_base_units |
string | The same amount in the token's smallest unit. |
asset |
string | Token being returned. |
chain_id |
number | Chain it goes back on. |
to_address |
string | Where it goes. |
destination_kind |
buyer_confirmed · buyer_refund_address · payer_address |
How that address was chosen. payer_address is the wallet that paid — which is often an exchange withdrawal address that cannot receive, so a stated refund address wins over it. |
state |
pending · prepared · submitted · succeeded · failed · canceled |
Where the refund got to. |
requested_at |
string (date-time) | When it was asked for. |
sla_due_at |
string (date-time) | When you undertook to have sent it by. |
fulfilment_tx_hash |
string | The transaction that sent it. |
failure_reason |
string | Why the last submitted transaction did not complete this refund — reverted, no_matching_transfer, transfer_predates_payment, not_mined_after_24h, transfer_already_used. The refund is still owed. |
verified_at |
string (date-time) | When that transaction was seen confirmed. Until then the refund is a claim, not a fact. |
reason |
string | Why it was refunded. |
created_at |
string (date-time) | When the record was created. |
Webhooks
GET
/v1/events
List events
Scope: webhooks:manage
200 Success.
POST
/v1/events/{id}/replay
Replay an event
Requires an Idempotency-Key header.
Scope: webhooks:manage
200 Success.
GET
/v1/webhook-deliveries
Delivery attempts
With response codes and errors. Use this when a merchant says the callback never arrived.
Scope: webhooks:manage
200 Success.
POST
/v1/webhook-deliveries/{id}/retry
Retry a delivery
Requires an Idempotency-Key header.
Scope: webhooks:manage
200 Success.
GET
/v1/webhook-endpoints
List endpoints
Scope: webhooks:manage
200 Success.
Returns WebhookEndpointList.
| Property | Type | |
|---|---|---|
object |
string | Always list. |
data |
array of WebhookEndpoint |
The page. |
has_more |
boolean | Whether another page exists. |
next_cursor |
string | Pass as starting_after to fetch it. Absent on the last page. |
POST
/v1/webhook-endpoints
Register an endpoint
Must be a public HTTPS host. Private and internal addresses are refused.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: webhooks:manage
| Field | Type | |
|---|---|---|
url · |
string (uri) | Where events are delivered. HTTPS only — an event carries payment detail, and plaintext delivery would hand it to the network. |
events |
array of string | Event types to send, from GET /v1/capabilities. Absent means all of them. |
201 The endpoint, and its signing secret — shown exactly once.
Returns WebhookEndpoint.
| Property | Type | |
|---|---|---|
id |
string | The endpoint. Ids are prefixed whe_ and opaque; do not parse them. |
object |
string | Always webhook_endpoint. |
url |
string | Where events are POSTed. HTTPS only. |
events |
array of string | Event types sent here. |
api_version |
string | The payload version this endpoint receives. |
status |
enabled · disabled |
A repeatedly failing endpoint is disabled rather than retried forever. |
mode |
live · test |
Whether it receives live or test events. |
consecutive_failures |
number | Failed deliveries in a row. Resets on success. |
disabled_at |
string (date-time) | When it was disabled for failing. |
created_at |
string (date-time) | When it was registered. |
DELETE
/v1/webhook-endpoints/{id}
Disable an endpoint
Undelivered events are kept and stay replayable to a new endpoint.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: webhooks:manage
200 Success.
POST
/v1/webhook-endpoints/{id}/rotate-secret
Rotate the signing secret
Both signatures are sent during the overlap, so you can migrate without downtime.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: webhooks:manage
200 Success.
Returns WebhookEndpoint.
| Property | Type | |
|---|---|---|
id |
string | The endpoint. Ids are prefixed whe_ and opaque; do not parse them. |
object |
string | Always webhook_endpoint. |
url |
string | Where events are POSTed. HTTPS only. |
events |
array of string | Event types sent here. |
api_version |
string | The payload version this endpoint receives. |
status |
enabled · disabled |
A repeatedly failing endpoint is disabled rather than retried forever. |
mode |
live · test |
Whether it receives live or test events. |
consecutive_failures |
number | Failed deliveries in a row. Resets on success. |
disabled_at |
string (date-time) | When it was disabled for failing. |
created_at |
string (date-time) | When it was registered. |
POST
/v1/webhook-endpoints/{id}/test
Send a test event
Requires an Idempotency-Key header.
Scope: webhooks:manage
200 Success.
Account
GET
/v1/account
Account configuration
Scope: account:read
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
PUT
/v1/account/accepted-assets
Change what you accept
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
POST
/v1/account/domains
Claim a domain
Claimed, not verified. Return URLs must be on a verified domain, so this issues a DNS challenge you publish and then check.
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
DELETE
/v1/account/domains/{domain}
Stop trusting a domain
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
POST
/v1/account/domains/{domain}/verify
Check the DNS challenge
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
PATCH
/v1/account/preferences
Change how you take money
Whether payments are held before they are charged, and who carries the network fee. Neither can move money anywhere new, which is why this is not a step-up action — unlike changing where you settle.
Requires an Idempotency-Key header.
Scope: account:write
| Field | Type | |
|---|---|---|
capture_method |
automatic · manual |
manual holds each payment until you capture it; automatic settles at once. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer can take their money back. Capped by the platform — Stripe holds a card authorization for 168 hours and offers up to 720; ours defaults to the same., min 1 |
rate_mode |
fixed_rate · floating_rate |
Default pricing mode for new payments. |
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
PATCH
/v1/account/settlement
Change settlement preferences
Bearer credentials are refused here. The request must be signed.
Requires an Idempotency-Key header.
Scope: account:write
200 Success.
Returns Account.
| Property | Type | |
|---|---|---|
id |
string | The account. Ids are prefixed org_ and opaque; do not parse them. |
object |
string | Always account. |
name |
string | Business name. |
kyb_status |
string | Where verification got to. |
merchant_of_record |
boolean | Whether you are the merchant of record. On this gateway you are: the money never touches us, so it cannot be ours to be liable for. |
settlement |
object | Account-default settlement: destination, asset, chain and mode. |
accepted |
object | Which assets and chains you take. |
branding |
object | How the hosted checkout looks. |
capture_method |
automatic · manual |
Default for new payments. manual holds the funds in escrow until you capture them. |
gas_payer |
buyer · merchant |
Who carries the network fee: added to the buyer's total, or taken from your settlement beside the gateway fee. |
hold_window_hours |
number | How long a held payment waits before the buyer may reclaim it. |
hold_window_max_hours |
number | The longest this platform allows. Your window cannot exceed it. |
rate_mode |
fixed_rate · floating_rate |
Default for new payments. |
tier |
string | Fee tier. |
refund_sla_hours |
number | How quickly you undertake to send refunds. |
verified_domains |
array of string | Domains proved yours. Only these may embed the checkout. |
pending_domains |
array of object | Claimed but not yet proved. |
status |
string | Whether the account can take money. |
GET
/v1/audit-log
Everything consequential anyone did
Scope: account:read
200 Success.
Reference
GET
/v1/assets
Supported assets
Decimals are per chain, deliberately: USDT is 6 on Ethereum and 18 on BNB Chain, and assuming otherwise mis-prices a payment by a factor of a trillion.
Scope: none
200 Success.
GET
/v1/capabilities
Scopes and event types
Read this rather than keeping your own copy — it is the list that cannot drift.
Scope: none
200 Success.
GET
/v1/chains
Chains and confirmation policy
Scope: none
200 Success.
GET
/v1/fees
Your fee plan
Scope: none
200 Success.
GET
/v1/openapi.json
This document
Public. Generate a client from it.
Scope: none
200 Success.
GET
/v1/rates
A rate between two assets
Scope: none
200 Success.
GET
/v1/status
Is the service up
Public, and deliberately minimal.
Scope: none
200 Success.
GET
/v1/status/detail
Operational health
Watcher lag, relayer balances, queue depths. Behind its own scope.
Scope: ops:read
200 Success.
Test mode
GET
/v1/test/outcomes
Outcomes you can produce
Scope: payments:read
200 Success.
POST
/v1/test/payments/{id}/simulate
Drive a payment to an outcome
Including underpayment and reorgs — the branches nobody builds until they have to.
Requires an Idempotency-Key header.
Scope: payments:write
| Field | Type | |
|---|---|---|
outcome |
string | Which ending to act out — see GET /v1/test/outcomes. Defaults to a successful payment. Always refused for a live credential. |
200 Success.
Subscription management
GET
/v1/manage/{token}
What the buyer sees about their own subscription
Public — the manage token is the authorisation, like a checkout token. Returned once as manage_url when the subscription is created, and included in the mail we send the payer. Put it in your own emails and account pages too: the shortest route out should be inside your product. It shows the price, the interval and the next charge, and nothing about your account.
Scope: none
200 Success.
POST
/v1/manage/{token}/cancel
The buyer cancels
No credential, no confirmation step and no retention flow — one request ends it. Defaults to stopping at the end of the period already paid for, which is what a person means by cancelling; immediately ends it now. You are told either way (subscription.cancel_scheduled or subscription.canceled, with canceled_by: "buyer"), and you must act on it: stop providing the service at current_period_end.
Requires an Idempotency-Key header.
Scope: none
| Field | Type | |
|---|---|---|
immediately |
boolean | End it now rather than at the end of the period already paid for. Defaults to false, which is what a person usually means by cancelling: do not charge me again, and let me keep what I have paid for. |
reason |
string | Optional, and never required — a cancellation must not be gated on answering a question., up to 300 characters |
200 Success.
GET
/v1/manage/{token}/revocation
The on-chain revoke call
The exact revoke call for the spend permission behind an auto_charge subscription. Cancelling here stops us charging — that is a promise we keep. Revoking is the buyer's own key acting on chain, needs neither us nor you, and is the half that does not require trusting anybody. 409 no_permission for a link-collected subscription, where nothing was pre-authorised.
Scope: none