Nexus API Reference
What is Nexus?
Nexus is a hosted crypto payment gateway. Merchants use it to accept cryptocurrency from their customers without running wallet, exchange-rate, or settlement infrastructure themselves. The service handles address generation, price conversion, confirmation tracking, and optional auto-conversion of received crypto into a preferred settlement currency.
Every endpoint in this document is a REST call made over HTTPS with a JSON body and an Authorization: Bearer <token> header. Responses are JSON.
Environments. Authentication (GraphQL, sign-in only): https://YOUR_EXCHANGE_HOST/graphql. Nexus API (REST): https://YOUR_NEXUS_HOST. Your Demo and Production hostnames are shared with your team during onboarding; substitute them wherever these placeholders appear below.
How It Works
- Merchant signs in. Exchange your API key and secret for a JWT Bearer token with Sign in for a bearer token. Every authenticated call carries this token. The exchange account must be active and have Nexus enabled, or calls return
403User is not authorized. - Merchant record exists.
PATCH /v1/user/checkincreates the merchant record on first use and syncs currencies. The dashboard calls it on sign-in. - Merchant creates a payment.
POST /v1/paymentcreates aninvoiceor anopenDeposit. - An address is created for the customer.
POST /v1/client/addressreturns (and on first use creates) the address for a currency/network pair. The customer sends funds to it. - Service processes the deposit. Each update from the exchange about the transaction is recorded. Deposits become final when the exchange completes them. Invoices then move to
Completed,Completed Loss,Completed ProfitorPartially Completed. An openDeposit staysProcessing. - Service notifies the merchant. Every enabled webhook receives transaction deliveries (
transaction_statusDetected,ClientCompleted,CompletedorRejected), payment deliveries (when an invoice reachesClient Completedor a completed status, or when a status is set manually) andpayout.*events. Each delivery is signed withx-webhook-signature=sha256(webhook_id + body)(see Register a webhook). - Merchant pays out settled funds. Create a payout with
POST /v1/payout, then approve it withPATCH /v1/payout/{payoutId}/approve. Approval needs a 2FA code unlessskip_payout_mfais on.
Two payment types
Both are created by the same endpoint. type decides the shape, and pricing_mode is required for both.
Scenario 1: Fixed Amount Invoice
Use this to charge the customer a specific amount in an order currency, for example 0.05 ETH for order #42. Unless passthrough_fees is true, the merchant and parent fees are added to the amount the customer must pay (target_currency_amount_required).
Step-by-step
- (Once) Register a webhook with
POST /v1/webhook. - List deposit currencies with
GET /v1/currency. - Create the invoice with
POST /v1/payment:{ "type": "invoice", "pricing_mode": "convertOnArrival", "amount_required": 0.05, "merchant_order_currency_id": "ETH", "merchant_order_id": "order-0001" } - Create the pay-to address with
POST /v1/client/address, passingpayment_id,currencyandcurrency_network, and show it to the customer. - Wait for settlement on your webhook, or read
GET /v1/payment/{id}. With custom confirmation counts, the payment can first reachClient Completed. Final statuses areCompleted,Completed Loss(underpaid within the threshold, or a price move against the merchant) andCompleted Profit(overpaid, or a price move in the merchant's favour). An underpayment beyond the threshold leaves the paymentPartially Completed.
Scenario 2: Open Deposit
Use this to give a customer a reusable deposit address for any amount. Leave out amount_required and merchant_order_currency_id; both are ignored for this type. If you leave out expiration, the payment never expires.
Step-by-step
- (Once) Register a webhook with
POST /v1/webhook. - Create the open deposit once per customer:
{ "type": "openDeposit", "pricing_mode": "convertOnArrival", "merchant_order_id": "deposit-alice", "merchant_order_metadata": { "customer": "alice@example.com" } } - Create the address with
POST /v1/client/addressfor each currency/network pair you want to offer. Repeated calls return the same address. - Credit the customer on the transaction delivery with
transaction_status: "Completed". Credit once per (payment_id,crypto_transaction_id), becauseCompletedis normally delivered twice.merchant_order_idandmerchant_order_metadataare echoed in every delivery.
Authentication
Exchange your API key and secret for a short-lived JWT bearer token. Every other endpoint in this reference requires this token in the Authorization: Bearer <token> header. Tokens expire, so repeat this call to refresh.
POST
/graphql
Sign in for a bearer token
Calls the service_signin GraphQL mutation with your API key and secret. Returns a JWT and its expiration timestamp. Use the returned jwt as the Bearer token on every subsequent REST call.
Variables
| Name | Type | Required | Description |
|---|---|---|---|
service_api_key |
string |
required | Your Nexus API key, issued by the platform. |
service_api_secret |
string |
required | Your Nexus API secret. Treat as a password and do not embed in client-side code. |
Response
| Field | Type | Description |
|---|---|---|
data.service_signin.jwt |
string |
The bearer token. Send as Authorization: Bearer <jwt> on every other endpoint. |
data.service_signin.expires_at |
number |
Token expiration as a Unix timestamp. Re-sign to refresh before this time. |
Code Examples
curl -X POST 'https://YOUR_EXCHANGE_HOST/graphql' \
-H 'Content-Type: application/json' \
-d '{"query":"mutation service_signin($key: String!, $secret: String!) { service_signin(service_api_key: $key, service_api_secret: $secret) { jwt expires_at } }","variables":{"key":"YOUR_API_KEY","secret":"YOUR_API_SECRET"}}'
import requests
url = "https://YOUR_EXCHANGE_HOST/graphql"
body = {
"query": "mutation service_signin($key: String!, $secret: String!) { service_signin(service_api_key: $key, service_api_secret: $secret) { jwt expires_at } }",
"variables": {"key": "YOUR_API_KEY", "secret": "YOUR_API_SECRET"},
}
response = requests.post(url, json=body)
jwt = response.json()["data"]["service_signin"]["jwt"]
print(jwt)
const response = await fetch("https://YOUR_EXCHANGE_HOST/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: "mutation service_signin($key: String!, $secret: String!) { service_signin(service_api_key: $key, service_api_secret: $secret) { jwt expires_at } }",
variables: { key: "YOUR_API_KEY", secret: "YOUR_API_SECRET" },
}),
});
const data = await response.json();
const jwt = data.data.service_signin.jwt;
console.log(jwt);Example response
{
"data": {
"service_signin": {
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": 1735689600
}
}
}
User
The merchant account: check-in, settings, KYC/2FA status and sub-users.
PATCH
/v1/user/checkin
Check in (create or sync merchant record)
Creates Nexus's merchant record for the calling account the first time it is called. Every later call syncs the account with the exchange: newly available deposit currencies are added to the currency settings, confirmation settings are refreshed, fee groups are updated and expired payments are marked. The Nexus dashboard calls this on sign-in. A server-only integration should call it once before anything else, because most other endpoints return User not found until the record exists. Returns 403 if the merchant record is disabled.
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/checkin' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/checkin"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/checkin", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
GET
/v1/user/settings
Get merchant settings
Return the merchant's currency settings, widget settings, label and account-level switches.
Response
| Field | Type | Description |
|---|---|---|
currency_settings[] |
array |
One entry per currency and network: enabled, currency_id, network, is_converted (auto-conversion to the preferred currency), required_confirmations, is_preferred, type, currency_metadata. |
widget_settings |
string |
The JSON string saved with Update widget settings. |
label |
string |
Merchant label. |
passthrough_fees |
boolean |
Deposit default: when true, invoice fees are not added to the amount the customer pays. |
payout_passthrough_fees |
boolean |
Payout default. See Payout. |
overpayment_conversion |
boolean |
Whether overpayments are converted to the preferred currency. |
skip_payout_mfa |
boolean |
Whether payout approval skips the 2FA code. See Payout. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/user/settings' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/settings"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/settings", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": "",
"currency_settings": [
{
"enabled": true,
"currency_id": "ETH",
"network": "SEPOLIA",
"is_converted": false,
"required_confirmations": 3,
"is_preferred": false,
"type": "Crypto",
"currency_metadata": null
}
],
"widget_settings": null,
"label": "Acme",
"passthrough_fees": false,
"payout_passthrough_fees": false,
"overpayment_conversion": false,
"skip_payout_mfa": true
}
GET
/v1/user/info
Get KYC and 2FA status
Return whether the merchant's exchange account has approved KYC and has 2FA enabled.
Response
| Field | Type | Description |
|---|---|---|
is_kyc_approved |
boolean |
KYC approved on the exchange. |
is_mfa_enabled |
boolean |
2FA enabled on the exchange. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/user/info' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/info"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/info", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"is_kyc_approved": true,
"is_mfa_enabled": true
}
GET
/v1/user/child-users
List sub-users
Return the sub-users (child merchants) of the calling merchant, with filters and pagination.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
showInactive |
boolean |
required | Include disabled sub-users. Required; the request is rejected without it. |
groupName |
string |
optional | Only sub-users in this fee group. |
preferredCurrency |
string |
optional | Only sub-users with this preferred currency. |
search |
string |
optional | Text search. |
pageIndex |
number |
optional | 1-based page number (default 1). 0 is treated as 1. |
pageSize |
number |
optional | Items per page (default 10). |
Response
| Field | Type | Description |
|---|---|---|
results[] |
array |
Sub-users: id, sub, parent_user_sub, exchange_id, preferred_currency_id, widget_settings, parent_fee_group_name, email, label, enabled. |
total_count / page / size |
number |
Paging information. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/user/child-users?showInactive=false&pageIndex=1&pageSize=10' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/child-users?showInactive=false&pageIndex=1&pageSize=10"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/child-users?showInactive=false&pageIndex=1&pageSize=10", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"sub": "c41f8a2e-7b3d-4e19-a6c5-0d9e2f1b7a34",
"parent_user_sub": "ec43ce90-8bd8-461d-8c00-df3b90d0b6cf",
"exchange_id": "your-exchange",
"preferred_currency_id": "USD",
"widget_settings": null,
"parent_fee_group_name": "standard",
"email": "ops@example.com",
"label": "Ops team",
"enabled": true
}
],
"total_count": 1,
"page": 1,
"size": 10
}
POST
/v1/user/child
Create a sub-user
Create a sub-user under the calling merchant and assign it to one of the merchant's Child fee groups. Fails if the label is already used by one of your sub-users, if the email already exists on the exchange, or if the fee group isn't a Child group you own.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
email |
string |
required | Sub-user email. Must be a valid address that doesn't already exist on the exchange. |
label |
string |
required | Display label, up to 36 characters. Must be unique among your sub-users. |
fee_group_name |
string |
required | Name of one of your Child fee groups (see Fee). |
preferred_currency_id |
string |
optional | Preferred currency. Defaults to the exchange's default preferred currency. |
Response
| Field | Type | Description |
|---|---|---|
user_id |
string (uuid) |
Id of the new sub-user. Use it in the Fee group calls. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/user/child' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"email":"ops@example.com","label":"Ops team","fee_group_name":"standard","preferred_currency_id":"USD"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/child"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"email": "ops@example.com",
"label": "Ops team",
"fee_group_name": "standard",
"preferred_currency_id": "USD"
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/child", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"email": "ops@example.com",
"label": "Ops team",
"fee_group_name": "standard",
"preferred_currency_id": "USD"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": "",
"user_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46"
}
PUT
/v1/user/child/{id}
Enable or disable a sub-user
Switch one of your sub-users between enabled and disabled. There is no request body, and each call flips the current state. Returns 404 if the user doesn't exist and 403 if it isn't your sub-user.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id |
string (uuid) |
required | Sub-user id (the user_id from Create a sub-user). |
Code Examples
curl -X PUT 'https://YOUR_NEXUS_HOST/v1/user/child/3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/child/3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.put(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/child/3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46", {
method: "PUT",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
POST
/v1/user/logo
Upload a logo
Upload a logo image for the payment widget and get back its public URL. Send it as multipart/form-data with a logo file field. Only .png and .svg files smaller than 2 MiB (2,097,152 bytes) are accepted. Anything else returns Invalid extension or exceeded max file size.
Response
| Field | Type | Description |
|---|---|---|
url |
string |
Public URL of the uploaded file. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/user/logo' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/logo"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.post(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/logo", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
PATCH
/v1/user/widget-settings
Update widget settings
Save the widget configuration. The value is stored and returned as an opaque string.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
widget_settings |
string |
required | Widget configuration, typically a JSON-encoded string. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/widget-settings' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"widget_settings":"{\"theme\":\"light\"}"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/widget-settings"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"widget_settings": "{\"theme\":\"light\"}"
}
response = requests.patch(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/widget-settings", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"widget_settings": "{\"theme\":\"light\"}"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PATCH
/v1/user/update-currency-settings
Update currency settings
Enable or disable deposit currencies and set auto-conversion per currency and network. Every pair you send must exist for the merchant. Otherwise the call fails with Some of provided currencies are not existed/configured, returned as plain text.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
currency_settings[] |
array |
required | List of settings. |
currency_settings[].currency_id |
string |
required | Currency id. |
currency_settings[].network |
string |
required | Network. The key must be present but can be an empty string. |
currency_settings[].is_converted |
boolean |
required | Auto-convert to the preferred currency. |
currency_settings[].enabled |
boolean |
required | Accept this currency. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/update-currency-settings' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"currency_settings":[{"currency_id":"ETH","network":"SEPOLIA","is_converted":false,"enabled":true}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/update-currency-settings"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"currency_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "is_converted": false, "enabled": true}]
}
response = requests.patch(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/update-currency-settings", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"currency_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "is_converted": false, "enabled": true}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PATCH
/v1/user/update-preferred-currency
Update preferred currency
Set the merchant's preferred currency, which is the conversion target. Returns 404 with the plain-text body Provided currency does not exist. if the currency isn't available.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
currency_id |
string |
required | Currency id. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/update-preferred-currency' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"currency_id":"USD"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/update-preferred-currency"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"currency_id": "USD"
}
response = requests.patch(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/update-preferred-currency", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"currency_id": "USD"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PATCH
/v1/user/update-crypto-confirmations
Update confirmation counts
Set the number of block confirmations per crypto currency and network at which a deposit counts as client-completed (ClientCompleted). Every pair must exist and be a crypto currency. Otherwise you get a plain-text error: Some of provided currencies are not existed/configured or Some of provided currencies are not crypto.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
crypto_confirmation_settings[] |
array |
required | List of settings. |
crypto_confirmation_settings[].currency_id |
string |
required | Currency id. |
crypto_confirmation_settings[].network |
string |
required | Network. |
crypto_confirmation_settings[].confirmations |
number |
required | Number of confirmations. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/update-crypto-confirmations' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"crypto_confirmation_settings":[{"currency_id":"ETH","network":"SEPOLIA","confirmations":2}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/update-crypto-confirmations"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"crypto_confirmation_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "confirmations": 2}]
}
response = requests.patch(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/update-crypto-confirmations", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"crypto_confirmation_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "confirmations": 2}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PATCH
/v1/user/update-threshold-settings
Update underpayment thresholds
Set the underpayment tolerance per currency and network for invoice payments. When an invoice is underpaid by no more than this fraction of the amount paid, it completes as CompletedLoss instead of staying partially paid. The value is used as a fraction: the default is 0.01, meaning 1%. Every pair must exist for the merchant.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
threshold_settings[] |
array |
required | List of settings. |
threshold_settings[].currency_id |
string |
required | Currency id. |
threshold_settings[].network |
string |
required | Network. The key must be present but can be an empty string. |
threshold_settings[].threshold_value |
number |
optional | Tolerance as a fraction, for example 0.01 for 1%. The validator accepts 0 to 100. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/update-threshold-settings' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"threshold_settings":[{"currency_id":"ETH","network":"SEPOLIA","threshold_value":0.01}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/update-threshold-settings"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"threshold_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "threshold_value": 0.01}]
}
response = requests.patch(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/update-threshold-settings", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"threshold_settings": [{"currency_id": "ETH", "network": "SEPOLIA", "threshold_value": 0.01}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PATCH
/v1/user/settings/passthrough/{value}
Set default deposit fee mode
Set the merchant's default passthrough_fees for new payments. On invoice payments, false adds the merchant and parent fees to the amount the customer must pay, and true leaves the amount as entered. Individual payments can override this. Returns the merchant settings.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
value |
boolean |
required | true or false. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/settings/passthrough/true' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/settings/passthrough/true"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/settings/passthrough/true", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
PATCH
/v1/user/settings/overpayment-conversion/{value}
Set overpayment conversion
Turn conversion of overpayments into the preferred currency on or off. Returns the merchant settings.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
value |
boolean |
required | true or false. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/settings/overpayment-conversion/false' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/settings/overpayment-conversion/false"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/settings/overpayment-conversion/false", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
PATCH
/v1/user/settings/skip-payout-mfa/{value}
Set payout 2FA skip (browser only)
Turn the per-approval payout 2FA check off (true) or back on (false). Turning it off requires a valid mfa_code; turning it back on doesn't. Browser only: requests without browser fetch metadata (Sec-Fetch-Site) and an Origin or Referer are rejected with 403, so use the Nexus dashboard for this, not a server. Returns the merchant settings.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
value |
boolean |
required | true to skip 2FA on payout approval. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
mfa_code |
string |
optional | Current 2FA code. Required when value is true. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/settings/skip-payout-mfa/{value}' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/settings/skip-payout-mfa/{value}"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/settings/skip-payout-mfa/{value}", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Currency
Currencies and networks available to the merchant.
GET
/v1/currency
List deposit currencies
Return the currencies and networks available for deposits on this merchant.
Response
| Field | Type | Description |
|---|---|---|
currencies[].currency_id |
string |
Currency id. |
currencies[].type |
string |
Currency type. |
currencies[].network |
string |
Network. Pass this as currency_network when you create an address. |
currencies[].min_confirmations / max_confirmations / block_time |
number |
Confirmation bounds and block time in seconds. Each is omitted when not set. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/currency' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/currency"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/currency", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": "",
"currencies": [
{
"currency_id": "ETH",
"type": "Crypto",
"network": "SEPOLIA",
"min_confirmations": 0,
"max_confirmations": 12,
"block_time": 15
}
]
}
GET
/v1/currency/{currency_id}
List currencies convertible with a currency
Return the currencies that have a trading instrument with currency_id on the merchant's exchange, as either base or quote currency.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
currency_id |
string |
required | Currency id. |
Response
| Field | Type | Description |
|---|---|---|
currencies[] |
array |
Same shape as List deposit currencies. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/currency/USDT' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/currency/USDT"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/currency/USDT", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
GET
/v1/currency/payout
List exchange crypto currencies
Return the crypto currencies on the merchant's exchange, one entry per currency id. To build a payout form, use Supported payout routes, which returns the currency and network pairs that are enabled for payouts.
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/currency/payout' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/currency/payout"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/currency/payout", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Payment
Create and manage invoices and open deposits.
GET
/v1/payment
List payments
Return the merchant's payments with filters, sorting and pagination.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
currency |
string |
optional | Order currency. |
status |
string |
optional | Payment status, as a display name (for example Client Completed) or a code name (for example ClientCompleted). |
startDate / endDate |
string (ISO 8601) |
optional | Filter on creation time (inclusive, UTC). |
search |
string |
optional | Exact payment id, or a case-insensitive partial match on merchant_order_id or the merchant label. |
sortBy |
string |
optional | CreatedAt (default), MerchantsName, OrderId, InvoiceId, InvoiceType, InvoiceAmount, EarnedFee, ExpirationDate, Status, KytStatus, UpdatedAt. |
sortDirection |
string |
optional | Descending (default) or Ascending. |
pageIndex |
number |
optional | 1-based page number (default 1). 0 is treated as 1. |
pageSize |
number |
optional | Items per page (default 10). |
Response
| Field | Type | Description |
|---|---|---|
results[] |
array |
Payment objects (see Get payment). |
total_count / page / size |
number |
Paging information. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payment?pageIndex=1&pageSize=10' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment?pageIndex=1&pageSize=10"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment?pageIndex=1&pageSize=10", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"id": "a427fc2a-be6b-44b4-9ebb-f0041496be70",
"owner_user_id": "674016eb-a47f-4c56-9a09-12fd0bccba4a",
"status": "New",
"kyt_status": null,
"currency_id": "ETH",
"expiration": 86400,
"target_currency_amount_required": 0.05,
"target_currency_amount_paid": null,
"merchant_label": null,
"merchant_order_id": "order-0001",
"merchant_order_metadata": {
"customer": "alice@example.com"
},
"merchant_order_description": null,
"own_merchant_fee": 0,
"type": "Invoice",
"pricing_mode": "Convert On Arrival",
"fees_in_price": true,
"passthrough_fees": true,
"created": "2026-11-06T09:00:14.291904+00:00",
"updated": "2026-11-06T09:00:14.291904+00:00",
"expired": null
}
],
"total_count": 1,
"page": 1,
"size": 10
}
POST
/v1/payment
Create a payment
Create an invoice (a fixed amount in an order currency) or an openDeposit (accepts any amount, any number of times). The merchant's currency settings at this moment are stored with the payment, and only those currency and network pairs can be used for its addresses. Returns 403 with an empty body if the account's KYC isn't approved (unless the exchange allows payments without KYC), or if the API key lacks the permission to create this payment type.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
type |
string |
required | invoice or openDeposit (case-insensitive; the display names Invoice / Open Deposit also work). |
pricing_mode |
string |
required | longLivedQuote or convertOnArrival. |
amount_required |
number |
optional | invoice only, and required there. Must be greater than 0, with no more decimals than the order currency's precision. Leave it out for openDeposit; 0 is rejected. |
merchant_order_currency_id |
string |
optional | invoice only, and required there. Must be a currency enabled in the merchant's settings. Ignored for openDeposit. |
merchant_order_id |
string |
optional | Your reference, up to 36 characters. It is echoed in deposit webhooks. |
merchant_order_metadata |
any JSON |
optional | Any JSON value (object, string and so on). It is stored and echoed back unchanged. |
merchant_order_description |
string |
optional | Free-text description. |
expiration |
string (duration) |
optional | Lifetime, as d.hh:mm:ss or hh:mm:ss, from 1 hour to 900 days, for example "1.00:00:00". Leave it out for a payment that never expires. |
fees_in_price |
boolean |
optional | Default true. |
passthrough_fees |
boolean |
optional | Overrides the merchant's passthrough_fees setting. |
Response
| Field | Type | Description |
|---|---|---|
payment |
object |
The payment object (see Get payment). |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/payment' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"type":"invoice","pricing_mode":"convertOnArrival","amount_required":0.05,"merchant_order_currency_id":"ETH","merchant_order_id":"order-0001","merchant_order_metadata":{"customer":"alice@example.com"},"expiration":"1.00:00:00"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"type": "invoice",
"pricing_mode": "convertOnArrival",
"amount_required": 0.05,
"merchant_order_currency_id": "ETH",
"merchant_order_id": "order-0001",
"merchant_order_metadata": {"customer": "alice@example.com"},
"expiration": "1.00:00:00"
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"type": "invoice",
"pricing_mode": "convertOnArrival",
"amount_required": 0.05,
"merchant_order_currency_id": "ETH",
"merchant_order_id": "order-0001",
"merchant_order_metadata": {"customer": "alice@example.com"},
"expiration": "1.00:00:00"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"payment": {
"id": "a427fc2a-be6b-44b4-9ebb-f0041496be70",
"owner_user_id": "674016eb-a47f-4c56-9a09-12fd0bccba4a",
"status": "New",
"kyt_status": null,
"currency_id": "ETH",
"expiration": 86400,
"target_currency_amount_required": 0.05,
"target_currency_amount_paid": null,
"merchant_label": null,
"merchant_order_id": "order-0001",
"merchant_order_metadata": {
"customer": "alice@example.com"
},
"merchant_order_description": null,
"own_merchant_fee": 0,
"type": "Invoice",
"pricing_mode": "Convert On Arrival",
"fees_in_price": true,
"passthrough_fees": true,
"created": "2026-11-06T09:00:14.291904+00:00",
"updated": "2026-11-06T09:00:14.291904+00:00",
"expired": null
},
"success": true,
"message": ""
}
GET
/v1/payment/{id}
Get payment
Return one of the merchant's payments.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id |
string (uuid) |
required | Payment id. |
Response
| Field | Type | Description |
|---|---|---|
id |
string (uuid) |
Payment id. |
owner_user_id |
string |
Owner merchant. |
status |
string |
Payment status, as a display name: New, Pending, Processing, Client Partially Completed, Partially Completed, Client Completed, Completed, Completed Loss, Completed Profit, Manual Completed, Manual Rejected, Expired. |
kyt_status |
string | null |
Pending, Approved, Partially KYT Rejected, Rejected, or null. |
currency_id |
string | null |
Order currency. null for openDeposit. |
expiration |
number | null |
Expiration in seconds from creation, or null if the payment never expires. |
target_currency_amount_required / target_currency_amount_paid |
number | null |
Required and paid amounts in the order currency. On an invoice without passthrough, the required amount includes the merchant and parent fees. null for openDeposit. |
merchant_order_id / merchant_order_metadata / merchant_order_description |
|
As sent at creation. |
own_merchant_fee |
number | null |
Merchant fee on the invoice. |
type / pricing_mode |
string |
Invoice / Open Deposit; Long Lived Quote / Convert On Arrival. |
fees_in_price / passthrough_fees |
boolean |
As set at creation. |
created / updated / expired |
string (ISO 8601) |
Timestamps. expired is null unless the payment expired. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "a427fc2a-be6b-44b4-9ebb-f0041496be70",
"owner_user_id": "674016eb-a47f-4c56-9a09-12fd0bccba4a",
"status": "New",
"kyt_status": null,
"currency_id": "ETH",
"expiration": 86400,
"target_currency_amount_required": 0.05,
"target_currency_amount_paid": null,
"merchant_label": null,
"merchant_order_id": "order-0001",
"merchant_order_metadata": {
"customer": "alice@example.com"
},
"merchant_order_description": null,
"own_merchant_fee": 0,
"type": "Invoice",
"pricing_mode": "Convert On Arrival",
"fees_in_price": true,
"passthrough_fees": true,
"created": "2026-11-06T09:00:14.291904+00:00",
"updated": "2026-11-06T09:00:14.291904+00:00",
"expired": null
}
GET
/v1/payment/{paymentId}/addresses
List a payment's addresses
Return the addresses that have already been created for a payment, each with the transactions detected on it. This call does not create addresses. To create one, use POST /v1/client/address. Available to the payment's owner and the owner's parent merchants.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
paymentId |
string (uuid) |
required | Payment id. |
Response
| Field | Type | Description |
|---|---|---|
addresses[].id / crypto_address / network / address_currency_id / tag_type / tag_value |
|
Address details. |
addresses[].transactions[] |
array |
Transactions detected on the address. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/addresses' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/addresses"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/addresses", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
GET
/v1/payment/export
Export payments (Excel)
Download the merchant's payments as an Excel file (.xlsx, sent as application/octet-stream). Accepts the same filters as List payments: currency, status, startDate, endDate and search. Returns No data to generate report when nothing matches.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
currency / status / startDate / endDate / search |
|
optional | As in List payments. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payment/export?startDate=2026-11-01&endDate=2026-11-06' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment/export?startDate=2026-11-01&endDate=2026-11-06"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment/export?startDate=2026-11-01&endDate=2026-11-06", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
PATCH
/v1/payment/{paymentId}/{paymentStatus}
Set payment status manually
Set one of your payments to Manual Completed (Complete) or Manual Rejected (Reject), and send a payment webhook delivery. After Reject, later deposits to the payment's addresses are still recorded and reported as transaction deliveries, but they are not converted. Complete does not change how later deposits are processed. Returns 404 Payment not found. for an id you don't own.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
paymentId |
string (uuid) |
required | Payment id. |
paymentStatus |
string |
required | Complete or Reject. |
Response
| Field | Type | Description |
|---|---|---|
(payment object) |
object |
See Get payment. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/Complete' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/Complete"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70/Complete", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Client (public)
Endpoints for the paying customer's side. No Bearer token is needed; the payment id identifies the payment.
POST
/v1/client/address
Get or create a payment address
Return the address for a payment and a currency/network pair, creating it on first use. Repeated calls with the same payment and pair return the same address. The currency is chosen as follows: for openDeposit payments and convertOnArrival invoices, the currency you send is used. For longLivedQuote invoices, the order currency is used, unless you pass a quote_id obtained from POST /v1/client/quote, in which case the quote's source currency and network are used. The pair must be in the payment's currency snapshot. Public: this endpoint needs no Bearer token, and the payment id acts as the credential.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
payment_id |
string (uuid) |
required | Payment id. |
currency |
string |
optional | Currency id. Used for openDeposit and convertOnArrival. |
currency_network |
string |
optional | Network. Converted to upper case. For invoices, defaults to the order currency's network. |
quote_id |
string (uuid) |
optional | Quote id, for longLivedQuote invoices. |
Response
| Field | Type | Description |
|---|---|---|
address_id |
string (uuid) |
Address id. |
address |
string |
On-chain address. |
address_currency_id / address_currency_network |
string |
Pair the address belongs to. |
tag_type / tag_value |
string | null |
Memo or tag, on chains that need one. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/client/address' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"payment_id":"a427fc2a-be6b-44b4-9ebb-f0041496be70","currency":"ETH","currency_network":"SEPOLIA"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/client/address"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"payment_id": "a427fc2a-be6b-44b4-9ebb-f0041496be70",
"currency": "ETH",
"currency_network": "SEPOLIA"
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/client/address", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"payment_id": "a427fc2a-be6b-44b4-9ebb-f0041496be70",
"currency": "ETH",
"currency_network": "SEPOLIA"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"address_id": "a1ff35ed-276f-4db4-9b35-01f28b97338a",
"address": "0xbC0B3C687496aB9D053b09BFcAfA05C184072aA4",
"address_currency_id": "ETH",
"address_currency_network": "SEPOLIA",
"tag_type": null,
"tag_value": null,
"success": true,
"message": ""
}
GET
/v1/client/payment/{id}
Get payment status (public)
Return a payment's public view, including its status and detected transactions. Public: no Bearer token needed. Returns 404 The payment does not exist. or 400 Payment with id: [{id}] is expired.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id |
string (uuid) |
required | Payment id. |
Response
| Field | Type | Description |
|---|---|---|
payment.client_status |
string |
Payment status. |
payment.* |
|
Also: id, currency_id, currency_network, target_currency_amount_required, target_currency_amount_paid, target_currency_amount_left, fee amounts, expiration, type, pricing_mode, currency_settings, passthrough_fees and more. |
transactions[] |
array |
Transactions detected so far. |
widget_setting / widget_languages |
|
Widget data. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/client/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/client/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/client/payment/a427fc2a-be6b-44b4-9ebb-f0041496be70", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Payout
Send settled funds to external addresses. A payout is created (Pending), then approved, which debits the balance and sends it on chain, and is finally completed or rejected. Every change is pushed to your webhook as a payout.* event. Payouts use the same host, Bearer token and webhook as payments.
Payout security settings
2FA on approval. By default, Approve a payout needs the merchant user's current 2FA code. For server-to-server integrations, a merchant user turns on skip_payout_mfa once, from the merchant dashboard. This needs a valid 2FA code, and the setting cannot be changed through the API. After that, approvals need no body, and creating payouts no longer requires 2FA to be enabled on the exchange account. The current value is returned by GET /v1/user/settings as skip_payout_mfa.
IP whitelist. Up to 10 IPs or CIDR ranges (minimum /16 for IPv4, /48 for IPv6) can be managed under /v1/user/settings/whitelisted-ips (GET, POST { "ip_address", "label" }, PUT /{id}, DELETE /{id}). Once the list is non-empty, Create and Approve from any other IP return 403 with Request IP address is not whitelisted.. An empty list means no restriction.
Status model
| Stage | approval_status | execution_status | Webhook event |
|---|---|---|---|
| Created | Pending | New | payout.initiated |
| Approved, being sent (can repeat) | Approved | Processing | payout.processing |
| Confirmed on chain | Approved | Completed | payout.completed |
| Rejected by the exchange (fees refunded) | Approved | Rejected | payout.rejected |
| Rejected by you while pending | Rejected | New | payout.rejected |
Payout webhook events
Payout events are delivered to every enabled webhook, in an envelope: event is one of payout.initiated, payout.processing, payout.completed or payout.rejected, and data.status repeats it. data.amount is the gross amount. To get fees and the net amount, call Get payout by id. Signatures work the same way as for every other delivery; see Register a webhook.
{
"event": "payout.completed",
"data": {
"payout_id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"blockchain_transaction_hash": "0x2887de8e5ce88810f7501b24af05a9abdd10c03ad6dc4ce97e86306af1f4fb28",
"status": "payout.completed",
"amount": 0.01,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"exchange_payment_id": "019dd623-f9fb-72ab-9163-03d8d87dd90e",
"note": "INT_CLIENT_0000001:WD-000123",
"currency": "ETH",
"timestamp": "2026-11-06T10:16:41.0087312Z",
"kyt": null
}
}
POST
/v1/payout
Create a payout
Create a crypto payout to an external address. The request is validated (account KYC/2FA prerequisites, enabled route, address validity for the network, minimum amount after fees) and the fees are quoted. The payout is recorded as Pending / New, and no funds move until you approve it. Fires payout.initiated. Subject to the payout IP whitelist.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
currency_id |
string |
required | Currency to send, e.g. "ETH", "USDT". Upper-cased. |
network |
string |
required | Network as returned by Supported payout routes (crypto_network), e.g. "SEPOLIA", "TRC20". Upper-cased. |
amount |
number |
required | Gross amount in the source currency. Must be greater than 0. After fees it must still be at or above payout_minimal_amount. |
destination_address |
string |
required | Recipient address. Validated against the network. |
destination_address_tag_type |
string |
optional | Tag type for routes that need a memo or destination tag. |
destination_address_tag_value |
string |
optional | Memo or destination tag value. |
note |
string |
optional | Free text, up to 256 characters. It is echoed in webhooks and can be searched in List payouts. |
passthrough_fees |
boolean |
optional | true: the recipient gets exactly amount and your account covers the fees. false: fees are deducted from amount. Defaults to your payout_passthrough_fees setting. |
Response
| Field | Type | Description |
|---|---|---|
id |
string (uuid) |
Payout id. Use it in every other payout call. Webhooks carry it as payout_id. |
currency |
string |
Asset being sent. |
network |
string |
Chain the payout is sent on (upper case). |
amount |
number |
Gross amount requested at creation. |
fee |
number |
Exchange network/withdrawal fee. Estimated at creation, replaced by the actual fee at approval. |
parent_merchant_fee |
number |
Fee charged by the parent merchant, if any. |
own_merchant_fee |
number |
Your own payout fee from your default fee group, if any. |
final_amount |
number |
What the recipient receives: amount when passthrough is on, otherwise amount - fee - parent_merchant_fee - own_merchant_fee. |
destination_address |
string |
Recipient address. |
tag_type / tag_value |
string | null |
Destination memo or tag, if one was sent. |
exchange_payment_id |
string | null |
Exchange-side payment id. Populated at approval. |
blockchain_hash |
string | null |
On-chain transaction hash, once known. |
note |
string | null |
Your free-text reference from creation. |
approval_status |
string |
Pending, Approved or Rejected. |
execution_status |
string |
New, Processing, Completed or Rejected. |
created_at / updated_at |
string (ISO 8601, UTC) |
Timestamps. |
kyt |
object | null |
KYT screening result when screening is enabled: kytStatus (Pending, Approved or Rejected), riscScore, decisionReason, errorMessage, analysedAt. |
payout_passthrough_fees |
boolean |
Whether fees were kept out of amount for this payout. |
is_refund / manual_refund |
boolean / object | null |
Set when the payout was created by a manual refund. false / null for API-created payouts. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/payout' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"currency_id":"ETH","network":"SEPOLIA","amount":0.01,"destination_address":"0x4e83362442B8d1bec281594CEa3050C8eB01311C","note":"INT_CLIENT_0000001:WD-000123","passthrough_fees":false}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"currency_id": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"note": "INT_CLIENT_0000001:WD-000123",
"passthrough_fees": False
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"currency_id": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"note": "INT_CLIENT_0000001:WD-000123",
"passthrough_fees": false
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"currency": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"fee": 0.0002,
"parent_merchant_fee": 0,
"own_merchant_fee": 0,
"final_amount": 0.0098,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"tag_type": null,
"tag_value": null,
"exchange_payment_id": null,
"blockchain_hash": null,
"note": "INT_CLIENT_0000001:WD-000123",
"approval_status": "Pending",
"execution_status": "New",
"created_at": "2026-11-06T10:15:02.184Z",
"updated_at": "2026-11-06T10:15:02.184Z",
"kyt": null,
"payout_passthrough_fees": false,
"is_refund": false,
"manual_refund": null
}
PATCH
/v1/payout/{payoutId}/approve
Approve a payout
Approve a Pending payout and send it to the exchange for on-chain execution. This checks free_balance against amount, books the payout fees, and moves the payout to Approved / Processing, filling in exchange_payment_id and the actual fee. Fires payout.processing. A payout can be approved only once. If approval fails, the payout stays Pending. The body is optional: mfa_code is only required when the merchant's skip_payout_mfa setting is off. Subject to the payout IP whitelist.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
payoutId |
string (uuid) |
required | The id returned by Create a payout. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
mfa_code |
string |
optional | Current 6-digit 2FA code of the merchant user. Required only when skip_payout_mfa is false. |
wallet_id |
string |
optional | Exchange wallet to debit, when the account has more than one. Leave it out to use the default wallet. |
Response
| Field | Type | Description |
|---|---|---|
(payout object) |
object |
Same shape as Create a payout. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/approve' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/approve"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/approve", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"currency": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"fee": 0.000029,
"parent_merchant_fee": 0,
"own_merchant_fee": 0,
"final_amount": 0.009971,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"tag_type": null,
"tag_value": null,
"exchange_payment_id": "019dd623-f9fb-72ab-9163-03d8d87dd90e",
"blockchain_hash": null,
"note": "INT_CLIENT_0000001:WD-000123",
"approval_status": "Approved",
"execution_status": "Processing",
"created_at": "2026-11-06T10:15:02.184Z",
"updated_at": "2026-11-06T10:15:03.902Z",
"kyt": null,
"payout_passthrough_fees": false,
"is_refund": false,
"manual_refund": null
}
PATCH
/v1/payout/{payoutId}/reject
Reject a payout
Cancel a Pending payout. The record is kept for audit, approval_status becomes Rejected, and no funds move. Fires payout.rejected. A payout that has already been approved cannot be rejected.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
payoutId |
string (uuid) |
required | The id returned by Create a payout. |
Response
| Field | Type | Description |
|---|---|---|
(payout object) |
object |
Same shape as Create a payout. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/reject' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/reject"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21/reject", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"currency": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"fee": 0.0002,
"parent_merchant_fee": 0,
"own_merchant_fee": 0,
"final_amount": 0.0098,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"tag_type": null,
"tag_value": null,
"exchange_payment_id": null,
"blockchain_hash": null,
"note": "INT_CLIENT_0000001:WD-000123",
"approval_status": "Rejected",
"execution_status": "New",
"created_at": "2026-11-06T10:15:02.184Z",
"updated_at": "2026-11-06T10:20:11.530Z",
"kyt": null,
"payout_passthrough_fees": false,
"is_refund": false,
"manual_refund": null
}
GET
/v1/payout/{payoutId}
Get payout by id
Look up one payout, with its current approval status, execution status, fees and on-chain hash. Returns 404 Withdrawal not found. if the id does not belong to the caller.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
payoutId |
string (uuid) |
required | The id returned by Create a payout. |
Response
| Field | Type | Description |
|---|---|---|
(payout object) |
object |
Same shape as Create a payout. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"currency": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"fee": 0.000029,
"parent_merchant_fee": 0,
"own_merchant_fee": 0,
"final_amount": 0.009971,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"tag_type": null,
"tag_value": null,
"exchange_payment_id": "019dd623-f9fb-72ab-9163-03d8d87dd90e",
"blockchain_hash": "0x2887de8e5ce88810f7501b24af05a9abdd10c03ad6dc4ce97e86306af1f4fb28",
"note": "INT_CLIENT_0000001:WD-000123",
"approval_status": "Approved",
"execution_status": "Completed",
"created_at": "2026-11-06T10:15:02.184Z",
"updated_at": "2026-11-06T10:16:41.006Z",
"kyt": null,
"payout_passthrough_fees": false,
"is_refund": false,
"manual_refund": null
}
GET
/v1/payout/list
List payouts
Return the merchant's payouts, newest first, with filters and pagination.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
pageIndex |
number |
optional | 1-based page number (default 1). |
pageSize |
number |
optional | Items per page (default 10). |
currency |
string |
optional | Filter by currency id. |
approvalStatus |
string |
optional | Pending, Approved or Rejected. |
executionStatus |
string |
optional | New, Processing, Completed or Rejected. |
startDate / endDate |
string (ISO 8601) |
optional | Filter on created_at (inclusive, UTC). |
search |
string |
optional | Exact payout id or exchange_payment_id, or any text contained in note. |
Response
| Field | Type | Description |
|---|---|---|
results |
array |
Payout objects (same shape as Create a payout). |
total_count |
number |
Total matching payouts. |
page / size |
number |
Echo of pageIndex / pageSize. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/list?pageIndex=1&pageSize=10&executionStatus=Processing' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/list?pageIndex=1&pageSize=10&executionStatus=Processing"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/list?pageIndex=1&pageSize=10&executionStatus=Processing", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"id": "6f1d2c3b-8a47-4e0f-9b52-0c7e1a9d4f21",
"currency": "ETH",
"network": "SEPOLIA",
"amount": 0.01,
"fee": 0.000029,
"parent_merchant_fee": 0,
"own_merchant_fee": 0,
"final_amount": 0.009971,
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"tag_type": null,
"tag_value": null,
"exchange_payment_id": "019dd623-f9fb-72ab-9163-03d8d87dd90e",
"blockchain_hash": null,
"note": "INT_CLIENT_0000001:WD-000123",
"approval_status": "Approved",
"execution_status": "Processing",
"created_at": "2026-11-06T10:15:02.184Z",
"updated_at": "2026-11-06T10:15:03.902Z",
"kyt": null,
"payout_passthrough_fees": false,
"is_refund": false,
"manual_refund": null
}
],
"total_count": 1,
"page": 1,
"size": 10
}
GET
/v1/payout/payment-routes
Supported payout routes
Return the currency and network pairs enabled for payouts on this merchant. Build payout forms from this list. It can differ from the deposit currency list.
Response
| Field | Type | Description |
|---|---|---|
payment_routes[].currency |
string |
Currency id. |
payment_routes[].crypto_network |
string |
Network to pass as network on Create a payout. |
payment_routes[].crypto_tag_type |
string |
Present only when the route needs a destination memo or tag. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/payment-routes' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/payment-routes"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/payment-routes", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"payment_routes": [
{
"currency": "ETH",
"crypto_network": "SEPOLIA"
},
{
"currency": "USDT",
"crypto_network": "TRC20"
}
]
}
GET
/v1/payout/info/{currency_id}
Payout balance and limits
Return the merchant's balance, minimum payout amount, remaining periodic payout limits and the total of payouts that are still pending, for one currency.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
currency_id |
string |
required | Currency id. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
walletId |
string |
optional | Exchange wallet to read the balance from. Defaults to the default wallet. |
Response
| Field | Type | Description |
|---|---|---|
account_balance.free_balance |
number |
Balance available for payouts. Approval checks amount against this figure. |
account_balance.total_balance / exposed_balance |
number |
Total balance, and the part that is reserved. |
payment_limit.payout_minimal_amount |
number |
Minimum net payout amount. |
payment_limit.payout_daily_limit / payout_weekly_limit / payout_monthly_limit |
number |
Remaining payout allowance in the current period. |
pending_payouts_amount |
number |
Sum of payouts created but not yet finished. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/info/ETH' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/info/ETH"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/info/ETH", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"account_balance": {
"free_balance": 1.25,
"total_balance": 1.3,
"exposed_balance": 0.05
},
"payment_limit": {
"currency": "ETH",
"payout_minimal_amount": 0.001,
"payout_daily_limit": 5,
"payout_weekly_limit": 20,
"payout_monthly_limit": 50
},
"pending_payouts_amount": 0.05
}
GET
/v1/payout/fee-estimation/{currency_id}/{network}/{amount}
Estimate payout fees
Quote the fees and the recipient amount for a hypothetical payout, using the same calculation as Create a payout. Read only.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
currency_id |
string |
required | Currency id. |
network |
string |
required | Network, as in Supported payout routes. |
amount |
number |
required | Gross amount. Must be greater than 0. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
passthroughFees |
boolean |
optional | Preview either fee mode. Defaults to the merchant's payout_passthrough_fees setting. |
Response
| Field | Type | Description |
|---|---|---|
fee_estimation |
number |
Total of all fees. |
final_amount |
number |
What the recipient would receive. |
fees.exchange_fee / fees.parent_merchant_fee / fees.merchant_fee |
number |
Fee breakdown. The exchange fee is an estimate. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/fee-estimation/ETH/SEPOLIA/0.01?passthroughFees=false' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/fee-estimation/ETH/SEPOLIA/0.01?passthroughFees=false"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/fee-estimation/ETH/SEPOLIA/0.01?passthroughFees=false", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"fee_estimation": 0.0002,
"final_amount": 0.0098,
"fees": {
"parent_merchant_fee": 0,
"merchant_fee": 0,
"exchange_fee": 0.0002
}
}
GET
/v1/payout/addresses-history
Previously used payout addresses
Return the destination addresses this merchant has sent payouts to, most used first. Useful for an address-book style picker.
Response
| Field | Type | Description |
|---|---|---|
addresses[].destination_address / network / currency |
string |
Address and route. |
addresses[].address_tag_type / address_tag_value |
string |
Present only when a tag was used. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/payout/addresses-history' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/payout/addresses-history"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/payout/addresses-history", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"addresses": [
{
"destination_address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C",
"network": "SEPOLIA",
"currency": "ETH"
}
]
}
PATCH
/v1/user/settings/payout-passthrough/{value}
Set default payout fee mode
Set the merchant's default payout_passthrough_fees. With true, recipients get the full amount and your account covers the fees. With false, fees are deducted from amount. Individual payouts can override this with passthrough_fees. Returns the merchant settings.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
value |
boolean |
required | true or false. |
Code Examples
curl -X PATCH 'https://YOUR_NEXUS_HOST/v1/user/settings/payout-passthrough/true' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/user/settings/payout-passthrough/true"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.patch(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/user/settings/payout-passthrough/true", {
method: "PATCH",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Webhook
Register URLs to receive real-time payment and payout events, enable or disable them, or remove them.
GET
/v1/webhook
List webhooks
Return every webhook the merchant has registered.
Response
| Field | Type | Description |
|---|---|---|
web_hooks[] |
array |
Webhook objects: id, url, enabled, label, created. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/webhook' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/webhook"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/webhook", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": "",
"web_hooks": [
{
"id": "8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22",
"url": "https://example.com/webhooks/nexus",
"enabled": true,
"label": "Production events",
"created": "2026-11-06T09:58:12.481Z"
}
]
}
POST
/v1/webhook
Register a webhook
Register a URL to receive event notifications. A merchant can have up to 5 webhooks. The returned id is also the signing secret for deliveries, so store it safely.
Verifying deliveries
Every delivery is a POST with a JSON body and an x-webhook-signature header. The signature is a plain SHA-256 hash, not an HMAC: hex(sha256(webhook_id + raw_body)), lower case, where webhook_id is this webhook's id. There is no separate secret. Treat the id as one. Hash the raw request bytes, not JSON you have parsed and serialised again, and compare in constant time. A non-2xx response or a network error is retried twice, 1 s and then 2 s later (three attempts in total), and then the delivery is dropped. Payment events and payout events go to every enabled webhook.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
url |
string |
required | Absolute URL that will receive POST deliveries. |
label |
string |
optional | Human-readable label, up to 200 characters. |
Response
| Field | Type | Description |
|---|---|---|
web_hook.id |
string (uuid) |
Webhook id. It is also the signing secret. |
web_hook.url / label |
string |
As registered. |
web_hook.enabled |
boolean |
Whether deliveries are active. |
web_hook.created |
string |
Creation timestamp. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/webhook' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"label":"Production events","url":"https://example.com/webhooks/nexus"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/webhook"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"label": "Production events",
"url": "https://example.com/webhooks/nexus"
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/webhook", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"label": "Production events",
"url": "https://example.com/webhooks/nexus"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": "",
"web_hook": {
"id": "8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22",
"url": "https://example.com/webhooks/nexus",
"enabled": true,
"label": "Production events",
"created": "2026-11-06T09:58:12.481Z"
}
}
PUT
/v1/webhook/{webhook_id}
Enable or disable a webhook
Switch a webhook between enabled and disabled. There is no request body, and each call flips the current state. The URL and id cannot be changed. To rotate the signing secret, register a new webhook, move your verifier to the new id, then delete the old one.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
webhook_id |
string (uuid) |
required | Webhook id. |
Code Examples
curl -X PUT 'https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.put(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22", {
method: "PUT",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
DELETE
/v1/webhook/{webhook_id}
Delete a webhook
Remove a webhook. Deliveries to it stop immediately.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
webhook_id |
string (uuid) |
required | Webhook id. |
Code Examples
curl -X DELETE 'https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.delete(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/webhook/8f3c27d4-55b1-4c2e-9a7e-1f0b9a3e4d22", {
method: "DELETE",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
Address Book
The account's saved crypto destination addresses (stored on the exchange).
POST
/v1/addressbook
Save address-book contacts
Validate each address for its currency and network, then send the list to the exchange as the account's saved crypto addresses (favorite_addresses_crypto on the exchange user). The response is the saved list the exchange returns. If any address is invalid, nothing is saved and you get Invalid address provided for {currency} {network}.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
address_book_contacts[] |
array |
required | Contacts. |
address_book_contacts[].name |
string |
optional | Label. |
address_book_contacts[].currency |
string |
optional | Currency id. |
address_book_contacts[].network |
string |
optional | Network. |
address_book_contacts[].address |
string |
optional | Address. |
address_book_contacts[].address_tag_type / address_tag_value |
string |
optional | Memo or tag, if needed. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/addressbook' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"address_book_contacts":[{"name":"Cold storage","currency":"ETH","network":"SEPOLIA","address":"0x4e83362442B8d1bec281594CEa3050C8eB01311C"}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/addressbook"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"address_book_contacts": [{"name": "Cold storage", "currency": "ETH", "network": "SEPOLIA", "address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C"}]
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/addressbook", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"address_book_contacts": [{"name": "Cold storage", "currency": "ETH", "network": "SEPOLIA", "address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C"}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"name": "Cold storage",
"currency": "ETH",
"network": "SEPOLIA",
"address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C"
}
],
"total_count": 1,
"page": 1,
"size": 1
}
GET
/v1/addressbook/list
List address-book contacts
Return all saved contacts. The endpoint takes no paging parameters; every contact is returned in a single page.
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/addressbook/list' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/addressbook/list"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/addressbook/list", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"name": "Cold storage",
"currency": "ETH",
"network": "SEPOLIA",
"address": "0x4e83362442B8d1bec281594CEa3050C8eB01311C"
}
],
"total_count": 1,
"page": 1,
"size": 1
}
Fee
Fee groups set the deposit and payout fees for you and your sub-users. All percentage fees are fractions from 0 to 1.
GET
/v1/fee/payment-fees/{paymentId}
Fees for a payment
Return the fee records of a payment.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
paymentId |
string (uuid) |
required | Payment id. |
Response
| Field | Type | Description |
|---|---|---|
payment_fees[] |
array |
Fee records: fee_group_id, payment_id, amount_required, amount_paid, order_currency_amount, currency, fee_status, fail_message. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/fee/payment-fees/a427fc2a-be6b-44b4-9ebb-f0041496be70' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/payment-fees/a427fc2a-be6b-44b4-9ebb-f0041496be70"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/payment-fees/a427fc2a-be6b-44b4-9ebb-f0041496be70", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);
GET
/v1/fee/groups
List fee groups
Return the merchant's fee groups.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
type |
string |
optional | Child (groups for sub-users) or Own. |
search |
string |
optional | Text search. |
pageIndex |
number |
optional | 1-based page number (default 1). 0 is treated as 1. |
pageSize |
number |
optional | Items per page (default 10). |
Response
| Field | Type | Description |
|---|---|---|
results[] |
array |
Fee groups: id, group_name, is_default, group_type, default_deposit_fee, default_payout_fee, fees (currency_id, deposit_fee, deposit_flat_fee, updated_at, is_custom), payout_fees (currency_id, progressive_fee, flat_fee, updated_at, is_custom), users. |
total_count / page / size |
number |
Paging information. |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/fee/groups?type=Child&pageIndex=1&pageSize=10' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/groups?type=Child&pageIndex=1&pageSize=10"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/groups?type=Child&pageIndex=1&pageSize=10", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"results": [
{
"id": "9c2e7a14-0b3d-4f58-8e61-2d7a9b4c1f03",
"group_name": "standard",
"is_default": false,
"group_type": "Child",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [
{
"currency_id": "ETH",
"deposit_fee": 0.008,
"deposit_flat_fee": null,
"updated_at": "2026-11-06T09:00:00Z",
"is_custom": true
}
],
"payout_fees": [],
"users": []
}
],
"total_count": 1,
"page": 1,
"size": 10
}
GET
/v1/fee/group/{groupName}
Get fee group by name
Return one of your fee groups. Returns 404 You do not have fee group with provided name: {name}. if it doesn't exist.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
groupName |
string |
required | Group name (URL-encoded). |
Code Examples
curl -X GET 'https://YOUR_NEXUS_HOST/v1/fee/group/standard' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group/standard"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.get(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group/standard", {
method: "GET",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "9c2e7a14-0b3d-4f58-8e61-2d7a9b4c1f03",
"group_name": "standard",
"is_default": false,
"group_type": "Child",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [
{
"currency_id": "ETH",
"deposit_fee": 0.008,
"deposit_flat_fee": null,
"updated_at": "2026-11-06T09:00:00Z",
"is_custom": true
}
],
"payout_fees": [],
"users": []
}
POST
/v1/fee/group
Create a fee group
Create a fee group. Groups created here are always of type Child, meaning they are assigned to sub-users. Returns the new group.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
name |
string |
required | Group name. |
default_deposit_fee |
number |
required | Default deposit fee as a fraction from 0 to 1 (0.01 = 1%). |
default_payout_fee |
number |
optional | Default payout fee as a fraction from 0 to 1. |
fees[] |
array |
optional | Per-currency deposit fees: currency_id (required), deposit_fee (fraction from 0 to 1), deposit_flat_fee (at least 0). |
payout_fees[] |
array |
optional | Per-currency payout fees: currency_id (required), progressive_fee (fraction from 0 to 1), flat_fee (at least 0). |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/fee/group' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"standard","default_deposit_fee":0.01,"default_payout_fee":0.005,"fees":[{"currency_id":"ETH","deposit_fee":0.008}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"name": "standard",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [{"currency_id": "ETH", "deposit_fee": 0.008}]
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "standard",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [{"currency_id": "ETH", "deposit_fee": 0.008}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "9c2e7a14-0b3d-4f58-8e61-2d7a9b4c1f03",
"group_name": "standard",
"is_default": false,
"group_type": "Child",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [
{
"currency_id": "ETH",
"deposit_fee": 0.008,
"deposit_flat_fee": null,
"updated_at": "2026-11-06T09:00:00Z",
"is_custom": true
}
],
"payout_fees": [],
"users": []
}
PUT
/v1/fee/group
Update a fee group
Replace a fee group's rates, and optionally rename it. This is a full replacement: fees and payout_fees replace the existing per-currency lists, default_payout_fee becomes null if you leave it out, and default_deposit_fee becomes 0 if you leave it out. Send every value you want to keep. Leave out new_name, or repeat the current name, to keep the name. The default group can't be renamed. Returns the updated group.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
old_name |
string |
required | Current group name. |
new_name |
string |
optional | New name. |
default_deposit_fee |
number |
optional | Default deposit fee as a fraction from 0 to 1 (0.01 = 1%). |
default_payout_fee |
number |
optional | Default payout fee as a fraction from 0 to 1. |
fees[] |
array |
optional | Per-currency deposit fees: currency_id (required), deposit_fee (fraction from 0 to 1), deposit_flat_fee (at least 0). |
payout_fees[] |
array |
optional | Per-currency payout fees: currency_id (required), progressive_fee (fraction from 0 to 1), flat_fee (at least 0). |
Code Examples
curl -X PUT 'https://YOUR_NEXUS_HOST/v1/fee/group' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"old_name":"standard","new_name":"standard","default_deposit_fee":0.01,"fees":[{"currency_id":"ETH","deposit_fee":0.007}]}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"old_name": "standard",
"new_name": "standard",
"default_deposit_fee": 0.01,
"fees": [{"currency_id": "ETH", "deposit_fee": 0.007}]
}
response = requests.put(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group", {
method: "PUT",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"old_name": "standard",
"new_name": "standard",
"default_deposit_fee": 0.01,
"fees": [{"currency_id": "ETH", "deposit_fee": 0.007}]
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"id": "9c2e7a14-0b3d-4f58-8e61-2d7a9b4c1f03",
"group_name": "standard",
"is_default": false,
"group_type": "Child",
"default_deposit_fee": 0.01,
"default_payout_fee": 0.005,
"fees": [
{
"currency_id": "ETH",
"deposit_fee": 0.008,
"deposit_flat_fee": null,
"updated_at": "2026-11-06T09:00:00Z",
"is_custom": true
}
],
"payout_fees": [],
"users": []
}
DELETE
/v1/fee/group/{groupName}
Delete a fee group
Delete one of your fee groups. The default group can't be deleted, and a group that still has sub-users can't be deleted either. Move them to another group first.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
groupName |
string |
required | Group name (URL-encoded). |
Code Examples
curl -X DELETE 'https://YOUR_NEXUS_HOST/v1/fee/group/standard' \
-H 'Authorization: Bearer YOUR_TOKEN'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group/standard"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
}
response = requests.delete(url, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group/standard", {
method: "DELETE",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
},
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
POST
/v1/fee/group/add-user
Add a sub-user to a fee group
Assign a sub-user to one of your fee groups. Returns 404 (empty body) if the group or user doesn't exist, or if the user is disabled.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
user_id |
string (uuid) |
required | Sub-user id. |
group_name |
string |
required | Fee group name. |
Code Examples
curl -X POST 'https://YOUR_NEXUS_HOST/v1/fee/group/add-user' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"user_id":"3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46","group_name":"standard"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group/add-user"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"user_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"group_name": "standard"
}
response = requests.post(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group/add-user", {
method: "POST",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"user_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"group_name": "standard"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
PUT
/v1/fee/group/change-user
Move a sub-user to another fee group
Move one of your sub-users to a different fee group. Errors: Sub user not found, You can't manage this user.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
sub_merchant_id |
string (uuid) |
required | Sub-user id. |
new_group_name |
string |
required | Target fee group name. |
Code Examples
curl -X PUT 'https://YOUR_NEXUS_HOST/v1/fee/group/change-user' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"sub_merchant_id":"3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46","new_group_name":"vip"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group/change-user"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"sub_merchant_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"new_group_name": "vip"
}
response = requests.put(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group/change-user", {
method: "PUT",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"sub_merchant_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"new_group_name": "vip"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}
DELETE
/v1/fee/group/remove-user
Remove a sub-user from a fee group
Remove a sub-user from a fee group. The ids go in a JSON request body.
Request body
| Name | Type | Required | Description |
|---|---|---|---|
sub_user_id |
string (uuid) |
required | Sub-user id. |
group_name |
string |
required | Fee group name. |
Code Examples
curl -X DELETE 'https://YOUR_NEXUS_HOST/v1/fee/group/remove-user' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"sub_user_id":"3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46","group_name":"vip"}'
import requests
url = "https://YOUR_NEXUS_HOST/v1/fee/group/remove-user"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
}
body = {
"sub_user_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"group_name": "vip"
}
response = requests.delete(url, json=body, headers=headers)
print(response.status_code, response.json())
const response = await fetch("https://YOUR_NEXUS_HOST/v1/fee/group/remove-user", {
method: "DELETE",
headers: {
"Authorization": `Bearer ${YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"sub_user_id": "3b9d6c1e-2f4a-4c8b-9e7d-5a1f0c2b8d46",
"group_name": "vip"
}),
});
const data = await response.json();
console.log(response.status, data);Example response
{
"success": true,
"message": null
}