Getting Started with the Weenx Integration API

Server-to-server contract for workspace-scoped crypto payments — invoices, hosted checkout, charges, payouts, refunds, on/off-ramp, auto-convert, settlement, balances, subscriptions, reporting, and signed webhooks.

Build a secure backend-to-backend integration between your platform and Weenx.

The Weenx Integration API is designed for trusted server-side systems. It gives your backend direct access to workspace-scoped invoicing and hosted checkout, incoming-payment reconciliation, authorize/capture charges, receive-address management, crypto payouts, invoice refunds and reversals, internal balance transfers, fiat on-ramp and off-ramp, auto-convert rules, hot/cold settlement configuration, wallet balances, recurring subscriptions, reporting, and signed outbound webhooks.

Overview

The Integration API allows a merchant backend to:

  • authenticate with a workspace API key
  • confirm which workspace the key resolves to, and inspect the scopes and plan it carries
  • read the asset catalog — the currencies, networks, and currencyNetworkId values enabled for the workspace
  • read wallet balances for funding and reconciliation
  • create invoices, build a hosted-checkout descriptor, and issue signed payment links
  • run an authorize/capture flow on top of an invoice with the charges API
  • assign a fixed per-customer receive address, or allocate a one-time per-invoice address
  • reconcile incoming payments, deposits, and settlement batches
  • queue crypto payouts, estimate their fees, cancel them while pending, and manage the payout destination whitelist
  • queue invoice refunds and reversals back to a destination address
  • move balance between your own workspace environments with internal transfers
  • buy crypto with fiat (on-ramp) and sell crypto for fiat to a bank beneficiary (off-ramp)
  • define auto-convert rules that swap a received asset into a target asset
  • configure on-chain hot/cold settlement and USD hot-float threshold policies
  • run recurring billing with subscription plans and subscriptions
  • read plan, quota, and usage information
  • pull reporting as JSON or CSV
  • manage webhook endpoints and consume signed outbound events

The API is workspace-scoped. The workspace is resolved from the X-Api-Key header. Do not send a workspace identifier in a route, query string, or request body — the API ignores it and always acts on the workspace the key belongs to.

How the money moves

Three balances matter, and they move at different moments.

The workspace balance is your settled crypto held with Weenx, tracked per asset (currencyNetworkId). It is credited when an incoming payment confirms on-chain and is settled, and it is debited when you queue a payout, a refund, or an outgoing internal transfer.

An invoice is a request for payment. You create it for an amount in a specific asset; Weenx watches the receive address and records incoming on-chain payments against it. An invoice moves through Created, Waiting, Partial, Confirming, Paid, Expired, Failed, Cancelled, and ManualReview. Nothing is credited until the underlying on-chain payment reaches the required number of confirmations.

The card / customer-facing balances are out of scope for this money model: this API settles crypto to your workspace, and pays crypto out from it.

Two rules follow from this:

  • The chain is the source of truth. An incoming payment is only credited — and only announced to your webhook endpoint, dashboard, and ledger — after it reaches finality. Build for the confirmation delay; do not treat a detected-but-unconfirmed payment as money you hold.
  • Your platform settlement fee is deducted from your proceeds when an invoice is paid, not billed separately per transaction. The remainder is your net credit. See Security and Authentication and your plan for the exact percentage.

Practically: read GET /v1/balances before you queue a payout, watch for the PaymentConfirmed webhook (or poll GET /v1/invoices/{invoiceId}/status) to know an invoice is paid, and reconcile with GET /v1/payments when you need the on-chain detail.

Base URL

Weenx issues your Integration API host together with your API key. Every example on these pages uses the placeholder below; substitute the host you were given.

https://api.weenx.com

Every endpoint is served under the v1/ path prefix, for example https://api.weenx.com/v1/me.

Authentication

Every endpoint except the unauthenticated root (/), health (/health), and the OpenAPI document (/openapi/v1.json) requires the X-Api-Key header:

X-Api-Key: YOUR_WORKSPACE_API_KEY

Example:

curl --request GET \
  --url https://api.weenx.com/v1/me \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY'

An API key is workspace-scoped and carries a set of granted scopes. A request is rejected when the key is missing, empty, malformed, inactive, expired, or cannot resolve to an active workspace. Store API keys only in trusted backend infrastructure. Never expose them in browser code, mobile apps, public JavaScript bundles, public repositories, or customer-facing clients.

Scopes follow a resource:action shape — invoices:read, payouts:write, and so on — and a key that holds the wildcard * satisfies every endpoint. The full scope-to-endpoint mapping is in Security and Authentication.

The response envelope

Every response, success or failure, is the same envelope. The three keys are always present.

Successful responses:

{
  "success": true,
  "message": "Invoice created.",
  "data": { }
}

On success, message is a short human-readable string and the payload you want is in data. Drive your integration from data, not from the exact wording of message.

Failure responses carry success: false and a display-safe message. Typed domain errors also carry a stable machine-readable code:

{
  "success": false,
  "message": "Your plan does not include this capability.",
  "code": "plan.capability_denied"
}

Not every failure carries a code — some checks (for example a missing scope) return just success and message. When a request fails input validation on individual fields, the envelope also carries an errors object keyed by field name. Drive your control flow from the HTTP status code and, where present, the code; treat message as display text whose exact wording can change.

Idempotency

State-changing writes can be made safe to retry with an idempotency key. There are two placements, and which one an endpoint uses is fixed:

  • Idempotency-Key headerPOST /v1/invoices accepts an optional Idempotency-Key header. A retry with the same key and the same payload replays the stored response; the same key with a different payload is rejected with 409 Conflict.
  • idempotencyKey body field — payouts (POST /v1/payouts), internal transfers (POST /v1/transfers), and ramp order creation carry the idempotency key inside the request body. For internal transfers the field is required; the service deduplicates on it so a retry returns the original transfer instead of moving funds twice.

An idempotency key may be up to 128 characters and is retained for 24 hours. Reuse the same key only for the same logical business action with the same payload; do not mint a new key for a write whose outcome is unknown — retry with the same key, or reconcile through the read endpoints and webhooks.

Amounts and currencies

Every money value is a JSON number. Parse it into a decimal type; never compare the serialized text, and do not assume a fixed number of fraction digits — the transport form carries the scale of the value, which varies by asset and by endpoint. Round for display to the asset's own minor unit.

Assets are identified by an integer currencyNetworkId, which pins both the currency and the network it settles on (for example USDT on TRC-20 is a different currencyNetworkId from USDT on ERC-20). Resolve the valid values for your workspace from the catalog:

  • GET /v1/catalog/currencies — the currencies (code, symbol, decimals, isFiat, isStable)
  • GET /v1/catalog/networks — the networks (family, chain id, default confirmations, address-tag rules)
  • GET /v1/catalog/currency-networks — the enabled currencyNetworkId values, each with its token standard and contract address

Store the currencyNetworkId values your integration uses; do not hard-code them, because the set is scoped to the assets enabled for your workspace and plan.

Timestamps

Every timestamp in every response and webhook payload is a UTC instant in ISO-8601 format with a trailing Z, for example 2026-08-14T10:30:00Z. Field names carry the ...AtUtc suffix to make this explicit. Parse timestamps with a library that honours the offset and convert to your users' local zone only at display time; do not assume a value is already in your server's local zone.

Pagination

List endpoints paginate in one of two styles, depending on the resource:

  • page / pageSize — invoices, payouts, incoming payments, deposits, settlement batches, and webhook deliveries. page starts at 1; pageSize is clamped to a per-endpoint maximum. These responses carry page, pageSize, and total.
  • skip / take — quick links, no-code buttons, subscriptions, and subscription plans.

One transport detail to plan for: on the paged list endpoints, a row's status is serialized as an integer code, while the corresponding detail/getter endpoint returns the string enum name for the same field. Read a list row's status as a number and a detail view's status as a string.

Recommended first calls

Run these once, in this order, when you connect a new API key:

  1. GET /v1/me
  2. GET /v1/billing/plan
  3. GET /v1/catalog/currency-networks
  4. GET /v1/balances
  5. POST /v1/invoices
  6. GET /v1/invoices/{invoiceId}/status
  7. POST /v1/webhooks

This confirms credentials and workspace identity, the plan and its capabilities, the assets you can transact in, your balances, and the invoice and webhook behaviour, before you put real traffic through.

Step 1: Confirm the key context

curl --request GET \
  --url https://api.weenx.com/v1/me \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY'

GET /v1/me needs only a valid key — no scope. It returns:

  • workspaceEnvironmentId — the workspace this key acts on
  • apiKeyId — the id of the authenticating key
  • grantedScopes — the scopes the key carries
  • plan — the effective plan and its capabilities, or null
  • planUnavailableReason — set when plan is null

Store the expected workspaceEnvironmentId in your backend configuration and fail your health check if the value returned does not match.

Step 2: Read the plan

curl --request GET \
  --url https://api.weenx.com/v1/billing/plan \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY'

GET /v1/billing/plan returns your plan code and name, the monthly and setup fees, the settlement fee percentage, per-asset limits, and the capability flags that gate several endpoints — hostedCheckout, customPaymentPage, staticAddresses, autoConvert, webhooks, makerCheckerPayouts, dedicatedWallets, and customSettlementSchedules. A call to a capability your plan does not grant is rejected with 403 and the machine code plan.capability_denied, so check the flags before you enable a flow. The capacity and usage endpoints under GET /v1/billing/capacity/... and GET /v1/billing/usage/monthly-volume report how much of each quota you have consumed.

Step 3: Read the catalog and balances

curl --request GET \
  --url https://api.weenx.com/v1/catalog/currency-networks \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY'

curl --request GET \
  --url https://api.weenx.com/v1/balances \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY'

The catalog gives you the valid currencyNetworkId values. GET /v1/balances returns one row per wallet with availableBalance, lockedBalance, and totalBalance in the wallet's asset. Read availableBalance before any billable operation such as a payout.

Step 4: Create an invoice

curl --request POST \
  --url https://api.weenx.com/v1/invoices \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY' \
  --header 'Idempotency-Key: order-1234' \
  --data '{
    "currencyNetworkId": 1001,
    "amount": 49.99,
    "orderId": "order-1234",
    "title": "Order #1234",
    "expiresInSeconds": 3600,
    "redirectUrl": "https://example.com/return"
  }'

Only currencyNetworkId (a positive integer) and amount (a positive number) are required. A successful response returns:

  • invoiceId
  • status — the invoice status as a string name (often Waiting on a fresh invoice)
  • expectedAmount
  • expiresAtUtc — nullable

Store the returned invoiceId. Use it to read detail (GET /v1/invoices/{invoiceId}), poll status (GET /v1/invoices/{invoiceId}/status), build a hosted-checkout descriptor (GET /v1/invoices/{invoiceId}/hosted-checkout), issue a signed payment link (POST /v1/invoices/{invoiceId}/links), or allocate a one-time receive address (POST /v1/invoices/{invoiceId}/address).

Step 5: Get paid, and know when

A cardholder — here, a payer — sends crypto to the invoice's receive address. Weenx detects the transaction, waits for the required confirmations, and settles it to your workspace balance. There are two ways to observe this, and you should use both:

  • Webhooks (push). Subscribe an endpoint and handle PaymentDetected (pre-confirmation) and PaymentConfirmed (final). See Webhooks.
  • Reads (pull). Poll GET /v1/invoices/{invoiceId}/status for the invoice, or reconcile the on-chain detail with GET /v1/payments, GET /v1/payments/deposits, and GET /v1/payments/settlement-batches.

Use webhooks for fast notification and the read endpoints for authoritative current state.

Step 6: Pay out

curl --request POST \
  --url https://api.weenx.com/v1/payouts \
  --header 'Content-Type: application/json' \
  --header 'X-Api-Key: YOUR_WORKSPACE_API_KEY' \
  --data '{
    "currencyNetworkId": 1001,
    "amount": 25.00,
    "destinationAddress": "TXk...destination",
    "idempotencyKey": "payout-order-1234"
  }'

Creating a payout over the Integration API queues the request. The destination is checked against your payout whitelist at create time, and approval and on-chain sending remain operator-gated in the Weenx console. This is deliberate: a leaked API key cannot move funds out on its own. Read the payout back with GET /v1/payouts/{payoutRequestId}, estimate fees beforehand with GET /v1/payouts/fee-estimate, and follow completion through the PayoutSent, PayoutConfirming, and PayoutCompleted webhooks. The money-movement model is covered in full in Payouts and Money Movement.

Main endpoint groups

Context and catalog

  • GET /v1/me
  • GET /v1/catalog/currencies
  • GET /v1/catalog/networks
  • GET /v1/catalog/currency-networks
  • GET /v1/balances

Invoices, charges, and links

  • GET /v1/invoices
  • POST /v1/invoices
  • GET /v1/invoices/{invoiceId}
  • GET /v1/invoices/{invoiceId}/status
  • POST /v1/invoices/{invoiceId}/cancel
  • GET /v1/invoices/{invoiceId}/hosted-checkout
  • POST /v1/invoices/{invoiceId}/links
  • GET /v1/invoices/{invoiceId}/links
  • POST /v1/charges
  • GET /v1/charges/{chargeId}
  • POST /v1/charges/{chargeId}/refresh
  • POST /v1/charges/{chargeId}/pricing/select
  • POST /v1/charges/{chargeId}/authorize
  • POST /v1/charges/{chargeId}/capture
  • POST /v1/charges/{chargeId}/cancel
  • GET /v1/charges/{chargeId}/captures
  • GET /v1/charges/{chargeId}/events
  • POST /v1/links/quicklinks
  • GET /v1/links/quicklinks
  • POST /v1/links/quicklinks/{id}/disable
  • GET /v1/links/{paymentLinkId}
  • POST /v1/links/{paymentLinkId}/disable
  • POST /v1/buttons
  • PUT /v1/buttons/{id}
  • GET /v1/buttons
  • POST /v1/buttons/address-only/provision

Addresses and customers

  • POST /v1/addresses/static
  • POST /v1/addresses/static/bulk
  • GET /v1/addresses/static
  • GET /v1/addresses/static/{id}/history
  • POST /v1/addresses/static/{id}/state
  • POST /v1/addresses/static/{id}/retire
  • POST /v1/addresses/static/{id}/rotate
  • POST /v1/invoices/{invoiceId}/address
  • GET /v1/invoices/{invoiceId}/addresses
  • POST /v1/customers
  • GET /v1/customers
  • GET /v1/customers/{id}
  • PUT /v1/customers/{id}
  • POST /v1/customers/{id}/archive
  • POST /v1/customers/{id}/restore
  • DELETE /v1/customers/{id}

Payments, payouts, refunds, and transfers

  • GET /v1/payments
  • GET /v1/payments/{id}
  • GET /v1/payments/deposits
  • GET /v1/payments/settlement-batches
  • POST /v1/payouts
  • GET /v1/payouts
  • GET /v1/payouts/{payoutRequestId}
  • GET /v1/payouts/fee-estimate
  • POST /v1/payouts/{payoutRequestId}/cancel
  • GET /v1/payout-whitelist
  • POST /v1/payout-whitelist
  • POST /v1/payout-whitelist/{id}/activate
  • POST /v1/payout-whitelist/{id}/deactivate
  • GET /v1/invoices/{invoiceId}/refunds
  • POST /v1/invoices/{invoiceId}/refunds/quote
  • POST /v1/invoices/{invoiceId}/refunds
  • GET /v1/invoices/{invoiceId}/reversals
  • POST /v1/invoices/{invoiceId}/reversals/quote
  • POST /v1/invoices/{invoiceId}/reversals
  • POST /v1/transfers
  • GET /v1/transfers

Ramp, auto-convert, and settlement

  • POST /v1/onramp/quotes
  • POST /v1/onramp/orders
  • GET /v1/onramp/orders
  • GET /v1/onramp/orders/{orderId}
  • POST /v1/offramp/beneficiaries
  • POST /v1/offramp/beneficiaries/{id}/verify
  • GET /v1/offramp/beneficiaries
  • POST /v1/offramp/quotes
  • POST /v1/offramp/orders
  • GET /v1/offramp/orders
  • GET /v1/offramp/orders/{orderId}
  • GET /v1/auto-convert/rules
  • POST /v1/auto-convert/rules
  • DELETE /v1/auto-convert/rules/{id}
  • GET /v1/settlement/policies
  • POST /v1/settlement/policies
  • POST /v1/settlement/policies/apply
  • POST /v1/settlement/config
  • POST /v1/settlement/config/preview-split
  • PUT /v1/settlement/coin-acceptance/policy
  • GET /v1/settlement/coin-acceptance
  • GET /v1/settlement/coin-acceptance/effective/{currencyNetworkId}

Subscriptions, billing, reports, and webhooks

  • POST /v1/subscription-plans
  • PUT /v1/subscription-plans/{id}
  • GET /v1/subscription-plans
  • DELETE /v1/subscription-plans/{id}
  • POST /v1/subscriptions
  • GET /v1/subscriptions
  • POST /v1/subscriptions/{id}/pause
  • POST /v1/subscriptions/{id}/resume
  • POST /v1/subscriptions/{id}/cancel
  • POST /v1/subscriptions/{id}/change-plan/preview
  • POST /v1/subscriptions/{id}/change-plan
  • GET /v1/billing/plan
  • GET /v1/billing/capacity/static-addresses
  • GET /v1/billing/capacity/team-members
  • GET /v1/billing/capacity/assets
  • GET /v1/billing/usage/monthly-volume
  • GET /v1/reports/snapshot
  • GET /v1/reports/daily
  • GET /v1/reports/fee-breakdown
  • GET /v1/reports/treasury-balances
  • GET /v1/reports/settlements
  • GET /v1/reports/product/... (ramp volume, card spend, subscriptions, affiliate, profit-and-loss, invoice conversion)
  • POST /v1/webhooks
  • GET /v1/webhooks
  • GET /v1/webhooks/{id}/deliveries
  • POST /v1/webhooks/{id}/rotate-secret
  • POST /v1/webhooks/{id}/test
  • POST /v1/webhooks/{id}/disable
  • GET /v1/webhooks/events

Most reporting endpoints also expose a CSV variant at .../export.csv.

Production rules

  • Store API keys only in backend secret storage; never expose them in browser, mobile, public JavaScript, or public repositories.
  • Use HTTPS for all production traffic.
  • Resolve currencyNetworkId values from the catalog; do not hard-code them.
  • Send the same idempotency key when retrying the same write, and never mint a new key for a write whose final state is unknown.
  • Treat a detected-but-unconfirmed payment as not-yet-money; wait for PaymentConfirmed or a Paid invoice status.
  • Store returned invoiceId, payoutRequestId, and operation ids for reconciliation.
  • Verify every webhook signature against the raw request body before you act on it.
  • Check plan capability flags before enabling gated flows, and handle the plan.capability_denied 403.
  • Reconcile uncertain outcomes with invoice status, payment reads, payout reads, deposits, settlement batches, and webhooks.
  • Build only on the documented fields in the responses you consume; ignore any field you do not recognise.

Did this page help you?