MonaxPay

API reference

Create payment links from your own product, call-center desk, CRM, or accounting flow; then read status, customers, webhooks, settlements, and reports from the same API.

Base URL: https://api.monaxpay.com/v1v0.1.0 ยท OpenAPI JSON

Authentication

Create API keys in your dashboard. Every request carries x-api-key. Mutating requests are signed with x-api-timestamp, x-api-nonce, and an HMAC-SHA256 x-api-signature over timestamp.nonce.method.path.body; most writes require an Idempotency-Key header.

Quickstart

Every account can create API keys from the dashboard and embed payment-link creation, status reads, webhooks, customers, and reports into its own flow.

curl -X POST https://api.monaxpay.com/v1/transaction-intents \
  -H "Idempotency-Key: 7c1f1e2a-..." \
  -H "x-api-key: $MONAXPAY_API_KEY" \
  -H "x-api-timestamp: 1718200000" \
  -H "x-api-nonce: 0f9a..." \
  -H "x-api-signature: $SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "acct_8f2c10",
    "rail": "merchant_payment",
    "payerCountry": "DE",
    "recipientCountry": "TR",
    "fiatCurrency": "EUR",
    "fiatAmountMinor": 24000,
    "targetAsset": "SOL",
    "targetNetwork": "solana",
    "walletAddress": "7xKXโ€ฆq9P2",
    "merchantDisplayName": "Northstar Studio",
    "reference": "INV-1024",
    "purpose": "Design retainer",
    "expiresIn": "72h"
  }'

/api-credentials

get/api-credentialsList redacted API credentials for the authenticated or delegated account.

Merchant credentials list their own account. The platform credential can pass accountId (query or x-monaxpay-dashboard-account header) to list a merchant account on behalf of the dashboard bridge.

Parameters

accountId querystring (6โ€“80 chars)Optional delegation target. Must match the credential account unless the caller is the configured platform credential.

Responses

  • 200Redacted API credentials. Secret hashes and raw secrets are never returned.
  • 403Credential does not have api_credentials:read scope or cannot read credentials for the requested account.
post/api-credentialsCreate a scoped API credential and return the raw API secret once.

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can mint credentials for merchant accounts.
requestedBy optionalstring (3โ€“120 chars)
scopes requiredstring[]
prefix optionalstring
expiresAt optionalstring (date-time)

Responses

  • 201Credential created. The raw API secret is returned once and is not available from list APIs.
  • 400Invalid scope, prefix, or expiry.
  • 403Credential cannot manage API credentials for the requested account.
  • 409Idempotency payload mismatch or replayed signature.
post/api-credentials/{credentialKey}/rotateRotate an active API credential with a bounded overlap window.

Parameters

credentialKey path ยท requiredstring

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can rotate merchant credentials.
requestedBy optionalstring (3โ€“120 chars)
prefix optionalstring
overlapMinutes optionalinteger (1โ€“10080)

Responses

  • 201New credential created and the replaced credential moved to rotating state.
  • 403Credential cannot manage API credentials for the requested account.
  • 404Credential not found for the target account.
  • 409Credential is not active, idempotency mismatch, or replayed signature.
post/api-credentials/{credentialKey}/revokeRevoke an API credential for the authenticated or delegated account.

Parameters

credentialKey path ยท requiredstring

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can revoke merchant credentials.
requestedBy optionalstring (3โ€“120 chars)

Responses

  • 200Credential revoked or idempotent replay returned.
  • 403Credential cannot manage API credentials for the requested account.
  • 404Credential not found for the target account.
  • 409Idempotency payload mismatch or replayed signature.
post/api-credentials/{credentialKey}/policyUpdate source IP allowlist and per-scope max-age policy for an API credential.

Parameters

credentialKey path ยท requiredstring

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can update merchant credential policies.
requestedBy optionalstring (3โ€“120 chars)
ipAllowlist optionalstring (2โ€“64 chars)[]
scopeMaxAgeDays optionalobject

Responses

  • 200Credential policy updated or idempotent replay returned.
  • 400Invalid IP/CIDR allowlist or scope max-age policy.
  • 403Credential cannot manage API credentials for the requested account.
  • 404Credential not found for the target account.
  • 409Idempotency payload mismatch or replayed signature.
post/api-credentials/{credentialKey}/statusSuspend or mark an API credential as compromised.

Parameters

credentialKey path ยท requiredstring

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can update merchant credential status.
requestedBy optionalstring (3โ€“120 chars)
status required"suspended" | "compromised"
reason optionalstring (6โ€“240 chars)

Responses

  • 200Credential status updated or idempotent replay returned.
  • 403Credential cannot manage API credentials for the requested account.
  • 404Credential not found for the target account.
  • 409Idempotency payload mismatch or replayed signature.

/auth

post/auth/replay-consumptionsConsume a dashboard authentication replay key exactly once.

Used by the dashboard bridge for wallet SIWS challenges. The raw nonce is never sent; callers submit a SHA-256 replay key hash. Dashboard recovery codes use the dedicated /auth/recovery-codes endpoints.

Responses

  • 201Replay key consumed.
  • 400Invalid replay type, hash, expiry, or metadata.
  • 403Credential is not scoped to the submitted account.
  • 409Replay key was already consumed or signed nonce was replayed.
post/auth/recovery-codes/rotateRotate dashboard recovery-code hashes for an account audience.

Used by the dashboard bridge after secure delivery preparation. Raw recovery codes are never submitted; callers submit SHA-256 recovery-code hashes, and previous active batches for the same account/audience are revoked.

Responses

  • 201Recovery-code hash batch activated.
  • 400Invalid audience, hash list, delivery metadata, or idempotency key.
  • 403Credential is not scoped to the submitted account.
  • 409Idempotency payload mismatch or signed nonce replay.
post/auth/recovery-codes/consumeConsume one dashboard recovery-code hash exactly once.

Used by recovery login after password verification. The web bridge hashes the submitted recovery code locally, canonical API verifies membership in the active batch, then records a one-time replay consumption.

Responses

  • 200Recovery-code hash consumed.
  • 400Invalid audience, hash, or metadata.
  • 401Recovery code was not found in the active batch.
  • 403Credential is not scoped to the submitted account.
  • 409Recovery code was already consumed or signed nonce was replayed.
post/auth/dashboard-sessionsRegister an issued dashboard session in the canonical session registry.

Used by the dashboard bridge immediately before returning a signed dashboard cookie. The raw session ID is never sent; callers submit a SHA-256 session ID hash.

Responses

  • 201Dashboard session registered.
  • 400Invalid session hash, role set, expiry, or metadata.
  • 403Credential is not scoped to the submitted account.
  • 409Signed request nonce was replayed.
post/auth/dashboard-sessions/verifyVerify that a dashboard session hash is still active.

Used by production dashboard API routes before privileged operations. Inactive, expired, revoked, or unknown sessions return dashboard_session_inactive.

Responses

  • 200Dashboard session is active.
  • 400Invalid session hash or metadata.
  • 401Dashboard session is inactive, expired, revoked, or unknown.
  • 403Credential is not scoped to the submitted account.
  • 409Signed request nonce was replayed.
post/auth/dashboard-sessions/listList canonical dashboard session hashes for the authenticated account.

Used by dashboard session/device management. Returns account-scoped session hash metadata, derived active/expired/revoked status, and never exposes raw session IDs or cookie tokens.

Responses

  • 200Dashboard sessions returned.
  • 400Invalid status filter, limit, account, or metadata.
  • 403Credential is not scoped to the submitted account.
  • 409Signed request nonce was replayed.
post/auth/dashboard-sessions/revokeRevoke a dashboard session hash.

Used by dashboard logout and incident-response flows. Revocation is account-scoped and returns whether a matching active registry row was updated.

Responses

  • 200Dashboard session revocation processed.
  • 400Invalid session hash or reason.
  • 403Credential is not scoped to the submitted account.
  • 409Signed request nonce was replayed.
post/auth/self-serve/password-reset/requestRequest a self-serve dashboard password reset code.

Signed platform-bridge endpoint. Always responds with acceptance regardless of whether the email is registered (anti-enumeration). When the email matches an active merchant dashboard user, a single-use 6-digit code (10-minute TTL) is delivered via the security email channel. Send requests are lockout-limited per email.

Request body

email requiredstring (0โ€“254 chars, email)
audience optional"merchant"
locale optional"en" | "de" | "tr"

Responses

  • 202Reset request accepted ({ data: { accepted: true } }).
  • 403Credential is not the configured platform bridge credential.
  • 409Signed request nonce was replayed.
  • 429Too many reset requests for this email.
post/auth/self-serve/password-reset/confirmConfirm a password reset code and set a new dashboard password.

Signed platform-bridge endpoint. Verifies the single-use reset code, replaces the stored password hash, and invalidates the code. Wrong, expired, and reused codes return 401 invalid_reset_code and count toward the per-email lockout. TOTP enrollment is unchanged โ€” the second factor still applies at login.

Request body

email requiredstring (0โ€“254 chars, email)
audience optional"merchant"
code requiredstring
newPassword requiredstring (12โ€“200 chars)

Responses

  • 200Password updated ({ data: { updated: true } }).
  • 401Reset code is invalid, expired, or already used (invalid_reset_code).
  • 403Credential is not the configured platform bridge credential.
  • 409Signed nonce replay, or the account cannot reset its password.
  • 429Too many failed reset attempts for this email.
post/auth/social-identities/resolveResolve a linked dashboard social identity.

Used by production Google and Telegram login after provider ID-token verification. The canonical API matches account, audience, provider, subject, active status, and optional email before the web app can issue a dashboard session.

Responses

  • 200Social identity is linked and active.
  • 400Invalid account, provider, subject, email, or metadata.
  • 401Social identity is not linked, inactive, or email-bound to another user.
  • 403Credential is not scoped to the submitted account.
  • 409Signed request nonce was replayed.
post/auth/social-identitiesCreate or update an account-scoped social identity link.

Used by approved admin/operator workflows to bind Google or Telegram provider subjects to a dashboard account/audience. Writes are idempotent and audit logged.

Responses

  • 201Social identity link created or updated.
  • 400Invalid account, provider, subject, email, status, or metadata.
  • 403Credential is not scoped to the submitted account.
  • 409Idempotency payload mismatch or signed nonce replay.

/merchant-profile

post/merchant-profile/logoStore the public merchant checkout logo for an account.

Used by the dashboard bridge after local upload validation. The canonical API re-validates the image magic bytes and the 1 MB size cap server-side, then persists the bytes in Postgres. Merchant credentials must submit their own account; the platform credential can upload on behalf of a merchant account.

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can store logos for merchant accounts.
contentType required"image/png" | "image/jpeg" | "image/webp"
imageBase64 requiredstring (4โ€“1400000 chars)Standard base64 image payload, at most 1 MB decoded.
requestedBy optionalstring (3โ€“120 chars)

Responses

  • 201Logo stored. The response returns the content hash used for versioned public URLs and never echoes the image bytes.
  • 400Image is not valid base64, exceeds 1 MB, or fails magic-byte checks.
  • 403Credential cannot store logos for the requested account, or the account is not enabled.
  • 409Idempotency payload mismatch or replayed signature.
get/merchant-profile/logo/{accountId}Read the stored public merchant logo bytes for an account.

Public, unsigned read used by the web app's same-origin /api/merchant-logo proxy for checkout and dashboard branding. Responses carry the image content type, an ETag derived from the content hash, and immutable cache headers; pair with the ?v= content-hash query for cache busting.

Parameters

accountId path ยท requiredstring (6โ€“80 chars)

Responses

  • 200Raw logo bytes with image content type, ETag, and cache headers.
  • 304Logo unchanged for the supplied If-None-Match ETag.
  • 404No logo is stored for this account.

/compliance

post/compliance/precheckCheck whether a route can create a live transaction intent.

Responses

  • 200Compliance decision.

/fee-topups

post/fee-topupsCreate a pending prepaid fee-credit top-up intent.

Returns the exact Solana SPL token transfer instructions. Fee credit is not posted until Helius confirms a matching treasury transfer with the returned MP:<topupId> memo.

Request body

accountId requiredstring (6โ€“80 chars)
amountMinor requiredinteger (1โ€“100000000)
asset required"USDC" | "USDT"
network optional"solana"
requestedBy optionalstring (3โ€“120 chars)
metadata optionalobject

Responses

  • 201Pending top-up intent with destination treasury wallet, token mint, exact amount, memo, and expiry.
  • 402Reserved for future on-chain payment failures.
  • 409Idempotency payload mismatch or signed nonce replay.
  • 503Fee-credit treasury wallet or token mint configuration is missing.
post/fee-topups/listList prepaid fee-credit top-up intents for an account.

Signed, nonce-protected read (POST body keeps the accountId out of URLs and logs). The accountId must match the authenticated credential unless the caller is the platform credential.

Request body

accountId requiredstring (6โ€“80 chars)

Responses

  • 200Top-up intents (pending, confirmed, expired, cancelled) without internal treasury metadata.
  • 403Credential lacks fee_topups:read or cannot act for the requested account.
  • 409Replayed signed nonce.

/customers

get/customersList the merchant's customer directory.

Parameters

accountId querystring (6โ€“80 chars)Optional delegation target. Must match the credential account unless the caller is the platform credential.

Responses

  • 200Customers for the resolved account.
  • 403Credential lacks customers:read or cannot read customers for the requested account.
post/customersCreate a customer, or update one by passing its customerId.

Request body

accountId optionalstring (6โ€“80 chars)
customerId optionalstring (8โ€“80 chars)Pass an existing customerId to update instead of create.
displayName requiredstring (2โ€“160 chars)
email optionalstring (0โ€“254 chars, email)
companyName optionalstring (0โ€“160 chars)
billingAddress optionalstring (0โ€“500 chars)
country optionalstring (2โ€“2 chars)
taxId optionalstring (0โ€“80 chars)
notes optionalstring (0โ€“1000 chars)
status optional"active" | "archived"

Responses

  • 200Customer updated (customerId was supplied).
  • 201Customer created.
  • 404customerId was supplied but no such customer exists.
  • 409Idempotency payload mismatch or replayed signed nonce.
delete/customers/{customerId}GDPR self-service soft-delete of a customer.

Signed, nonce-protected endpoint. The customer row is retained with status='deleted' (so historic accounting documents keep their reference) and excluded from the customer list.

Parameters

accountId querystring (6โ€“80 chars)Optional delegation target. Must match the credential account unless the caller is the platform credential.

Responses

  • 200Customer soft-deleted.
  • 403Credential lacks customers:write or cannot delete customers for the requested account.
  • 404No live customer matches the supplied customerId.

/accounting

get/accounting/documentsList gross-only accounting documents (proformas, invoices, receipts).

Parameters

accountId querystring (6โ€“80 chars)Optional delegation target. Must match the credential account unless the caller is the platform credential.

Responses

  • 200Accounting documents for the resolved account.
  • 403Credential lacks accounting:read or cannot read documents for the requested account.
post/accounting/documentsCreate an accounting document, or update one by passing its documentId.

Line totals are computed server-side (quantity ร— unitAmountMinor, gross-only, taxMode none). Optional customerId and transactionPublicId references must exist for the account.

Request body

accountId optionalstring (6โ€“80 chars)
documentId optionalstring (8โ€“80 chars)Pass an existing documentId to update instead of create.
customerId optionalstring (8โ€“80 chars)
transactionPublicId optionalstring (3โ€“80 chars)
documentNumber optionalstring (3โ€“80 chars)
type optional"proforma" | "invoice" | "receipt" | "credit_note" | "refund_note" | "fee_statement"
status optional"draft" | "issued" | "linked" | "paid" | "cancelled" | "void" | "refunded"
currency optional"USD" | "EUR" | "TRY" | "GBP"
title requiredstring (2โ€“160 chars)
description optionalstring (0โ€“1000 chars)
dueAt optionalstring (date-time)
issuedAt optionalstring (date-time)
paidAt optionalstring (date-time)
lineItems requiredobject[]
metadata optionalobject

Responses

  • 200Document updated (documentId was supplied).
  • 201Document created.
  • 404A supplied documentId, customerId, or transactionPublicId does not exist for the account.
  • 409Idempotency payload mismatch or replayed signed nonce.
get/accounting/statements/{period}Monthly reconciliation statement for confirmed payment activity.

Aggregates the account's confirmed transaction-intent activity and confirmed refunds for one calendar month, grouped by the fiat currency the payment was priced in. Read-only over persisted records; no totals are fabricated.

Parameters

period path ยท requiredstringCalendar month in YYYY-MM form, e.g. 2026-06.
accountId querystring (6โ€“80 chars)Optional delegation target. Must match the credential account unless the caller is the platform credential.

Responses

  • 200Monthly statement for the resolved account and period.
  • 403Credential lacks accounting:read or cannot read statements for the requested account.

/transaction-intents

get/transaction-intentsList recent transaction intents for the authenticated account.

Responses

  • 200Recent intents.
post/transaction-intentsCreate a payment, request, buy, sell, swap, or send intent.

Request body

accountId requiredstring (6โ€“80 chars)
rail required"buy" | "sell" | "swap" | "send" | "request" | "merchant_payment" | "fee_collection" | "refund_manual"
payerCountry requiredstring (2โ€“2 chars)
recipientCountry requiredstring (2โ€“2 chars)
fiatCurrency optional"AED" | "AUD" | "BRL" | "CAD" | "CHF" | "CLP" | "COP" | "CZK" | "DKK" | "EUR" | "GBP" | "HKD" | "IDR" | "INR" | "JPY" | "KRW" | "MXN" | "NOK" | "NZD" | "PHP" | "PLN" | "QAR" | "RON" | "SAR" | "SEK" | "SGD" | "THB" | "TRY" | "TWD" | "USD" | "VND" | "ZAR"
fiatAmountMinor requiredinteger (1โ€“100000000)
targetAsset optional"USDC" | "USDT" | "SOL"V1 managed settlement assets. Additional assets stay route-gated and are not accepted by this endpoint.
targetNetwork optional"solana"V1 managed settlement network.
walletAddress requiredstring (24โ€“128 chars)
merchantDisplayName requiredstring (2โ€“80 chars)
payerName optionalstring (1โ€“120 chars)
payerEmail optionalstring (0โ€“254 chars, email)
reference requiredstring (3โ€“120 chars)
purpose requiredstring (3โ€“160 chars)
campaignId optionalstring (3โ€“80 chars)
linkMode optional"one_time"Reusable links are reserved for a later release with max-use and max-volume enforcement.
expiresIn optional"24h" | "72h" | "7d" | "manual"
expiresAt optionalstring (date-time)
successUrl optionalstring (uri)Optional public HTTPS redirect after provider success.
failureUrl optionalstring (uri)Optional public HTTPS redirect after provider failure.
internalNotes optionalstring (0โ€“1000 chars)
metadata optionalobject

Responses

  • 201Intent created. The response includes authoritative input, fee calculation, checkout URL, receipt URL, and optional signed Onramper URL.
  • 409Compliance manual review or idempotency payload mismatch.
get/transaction-intents/{publicId}Read one transaction intent by public ID.

Responses

  • 200Intent found.
  • 404Intent not found.
get/transaction-intents/{publicId}/receiptRead the issued receipt for a confirmed transaction intent.

Responses

  • 200Receipt found.
  • 404Receipt not issued or not found.
post/transaction-intents/{publicId}/cancelCancel a cancellable transaction intent.

Responses

  • 200Intent cancelled or idempotent replay.
  • 409Intent state cannot be cancelled.

/payer

get/payer/receiptsList receipts for a verified payer email through a platform-scoped bridge.

Used by the receipt vault after email-code verification. Requires a platform account credential with transaction_intents:read scope; merchant-scoped credentials cannot enumerate payer history.

Parameters

email query ยท requiredstring (0โ€“254 chars, email)
limit queryinteger (1โ€“100)

Responses

  • 200Receipts owned by the verified payer email.
  • 403Credential is not platform-scoped.

/receipts

get/receipts/{receiptId}Read one issued receipt by receipt ID.

Responses

  • 200Receipt found.
  • 404Receipt not found.
get/receipts/{receiptId}/deliveriesList delivery attempts for one receipt.

Responses

  • 200Receipt delivery attempts.
  • 404Receipt not found.
post/receipts/{receiptId}/deliveriesRecord an email delivery or failed resend attempt for one receipt.

Responses

  • 201Receipt delivery recorded.
  • 404Receipt not found.
  • 409Idempotency payload mismatch or replayed signature.

/partner-webhook-endpoints

get/partner-webhook-endpointsList merchant-owned outbound webhook endpoints without secret material.

Responses

  • 200Recent outbound webhook endpoints.
post/partner-webhook-endpointsCreate a merchant-owned outbound webhook endpoint and return its signing secret once.

Subscribe to one or more event types. Catalog: link.created, link.cancelled, link.expired; payment.confirmed, payment.underpaid (observed < expected), payment.overpaid (significant excess; the payment still confirms), payment.failed, payment.disputed, payment.refunded; settlement.completed (managed settlement swept net to the merchant on-chain); refund_case.opened / refund_case.approved / refund_case.rejected / refund_case.settled; kyc.status_changed, kyb.status_changed. Every delivery carries an HMAC-SHA256 signature header (x-monaxpay-signature: t=<unix>,v1=<hex>) over `<t>.<rawBody>`.

Responses

  • 201Endpoint created and signing secret returned once.
  • 400Endpoint URL is not allowed.
  • 409Idempotency payload mismatch or replayed signature.
post/partner-webhook-endpoints/{endpointId}/statusEnable or disable an outbound webhook endpoint.

Signed, nonce-protected. Disabling (status='suspended') stops delivery immediately without losing delivery history; re-enabling restores it.

Request body

accountId optionalstring (6โ€“80 chars)
status required"active" | "suspended"
requestedBy optionalstring (3โ€“120 chars)

Responses

  • 200Endpoint status updated.
  • 403Credential cannot manage webhook endpoints for the requested account.
  • 404Endpoint not found.
post/partner-webhook-endpoints/{endpointId}/deleteSoft-delete an outbound webhook endpoint.

Signed, nonce-protected. The endpoint is excluded from listings and never delivered to, while its delivery audit trail is preserved.

Responses

  • 200Endpoint soft-deleted.
  • 403Credential cannot manage webhook endpoints for the requested account.
  • 404Endpoint not found.
post/partner-webhook-endpoints/{endpointId}/rotate-secretRotate an endpoint's signing secret and return the new secret once.

Signed, nonce-protected. The new secret is returned exactly once; the old secret stops verifying immediately, so partners must update their verifier.

Responses

  • 200Secret rotated; new signing secret returned once.
  • 403Credential cannot manage webhook endpoints for the requested account.
  • 404Endpoint not found.

/partner-webhook-deliveries

get/partner-webhook-deliveriesList recent outbound webhook delivery attempts for the authenticated account.

Parameters

status query"pending" | "delivered" | "failed"Optional delivery status filter.
limit queryinteger (1โ€“100)Maximum delivery rows to return.
cursor querystringDelivery ID cursor returned as pagination.nextCursor.

Responses

  • 200Recent outbound webhook delivery attempts.
post/partner-webhook-deliveries/{deliveryId}/replayReplay one outbound webhook delivery with the original signed event payload.

Request body

accountId optionalstring (6โ€“80 chars)Optional delegation target. The platform credential can replay merchant deliveries.
requestedBy optionalstring (3โ€“120 chars)

Responses

  • 202Delivery replay attempted and recorded.
  • 403Credential cannot replay webhook deliveries for the requested account.
  • 404Delivery not found.
  • 409Idempotency payload mismatch, replayed signature, or inactive endpoint.

/analytics

get/analytics/overviewRead merchant analytics overview.

/refund-cases

get/refund-casesList account-scoped refund and dispute cases.

Signed read. Merchant credentials read their own refund cases; the platform credential can pass accountId to inspect a merchant account for admin support.

Parameters

accountId querystring (6โ€“80 chars)Optional delegation target. Requires the configured platform credential when different from the authenticated account.

Responses

  • 200Refund cases for the resolved account.
  • 403Credential lacks accounting:read or cannot read the requested account.
post/refund-casesCreate or update a refund/dispute case for a settled payment.

Signed, idempotent write. Crypto-settled refunds remain merchant-executed; MonaxPay records instructions, merchant transaction signatures, and optional Helius proof.

Request body

accountId optionalstring (6โ€“80 chars)
refundCaseId optionalstring (8โ€“80 chars)
transactionPublicId requiredstring (3โ€“80 chars)
customerId optionalstring (8โ€“80 chars)
requestedAmountMinor requiredinteger (1โ€“โˆž)
currency optional"USD" | "EUR" | "TRY" | "GBP"
asset required"USDC" | "USDT" | "SOL"
network required"solana"
destinationWalletAddress optionalstring (24โ€“128 chars)
merchantRefundTransactionId optionalstring (3โ€“180 chars)
reason requiredstring (3โ€“500 chars)
status optional"requested" | "instructions_sent" | "merchant_sent" | "confirmed" | "rejected" | "cancelled"
refundProof optionalobject

Responses

  • 200Refund case updated.
  • 201Refund case created.
  • 403Credential lacks accounting:write or cannot write the requested account.
  • 404Referenced transaction or refund case was not found.
  • 409Idempotency payload mismatch or replayed signature.

/operator-actions

get/operator-actionsList recent operator actions for the authenticated account.

Responses

  • 200Recent operator actions.
post/operator-actionsCreate an authenticated operator action for dashboard or back-office workflow.

The action is recorded under the submitted accountId. Merchant credentials must submit their own account; the platform credential can act for any account. Admin account-provisioning reviews additionally require account_provisioning:write and the configured platform account.

Request body

accountId requiredstring (6โ€“80 chars)
label requiredstring (3โ€“120 chars)
context requiredstring (3โ€“500 chars)
surface requiredstring (3โ€“120 chars)
requestedBy optionalstring (3โ€“120 chars)
metadata optionalobject

Responses

  • 202Operator action accepted and audit logged.
  • 403Credential cannot create actions for the requested account.
  • 409Idempotency payload mismatch or replayed signature.

/admin

get/admin/operator-actionsList recent platform-wide operator actions for admin audit.

Signed platform-credential-only read. Returns delegated merchant-account operator actions as well as platform-account actions for the admin audit tab.

Responses

  • 200Recent platform-wide operator actions.
  • 403Credential lacks operator_actions:read or is not the configured platform credential.
get/admin/operator-actions/pageKeyset-paged operator-action audit feed with surface + date filters.

Signed platform-credential-only read superseding the 200-row hard cap of /admin/operator-actions for deep audit history. Filterable by surface and created-at range; keyset paging anchored on (created_at, action_id).

Responses

  • 200A page of operator actions plus a nextCursor.
  • 403Credential lacks operator_actions:read or is not the configured platform credential.
get/admin/accountsKeyset-paged merchants directory across all accounts.

Signed platform-credential-only read. Joins accounts + public profile (display name) + merchant auth user (primary email) + merchant restrictions (freeze summary). Filterable by status, verification_status, account_type, and a free-text query; keyset paging anchored on (created_at, account_id).

Responses

  • 200A page of merchant summaries plus a nextCursor.
  • 400The supplied directory cursor is no longer valid.
  • 403Credential lacks accounts:read or is not the configured platform credential.
get/admin/analyticsPlatform-wide payment activity analytics from persisted data.

Signed platform-credential-only read. Returns per-currency payment volume by day and asset, top merchants, intent-status distribution, the KYC verification funnel, webhook health, merchant growth, and fee revenue across the prepaid, managed, and top-up rails. All rollups are computed in SQL (GROUP BY) and never sum across currencies. This is payment activity โ€” web page-view traffic is not persisted and is deliberately absent.

Responses

  • 200Platform analytics for the requested window.
  • 403Credential lacks analytics_platform:read or is not the configured platform credential.
get/admin/refund-casesCross-merchant refund-case queue.

Signed platform-credential-only read. Lists refund cases across every merchant, filterable by status; keyset paging anchored on (updated_at, refund_case_id).

Responses

  • 200A page of refund cases plus a nextCursor.
  • 403Credential lacks accounting:read or is not the configured platform credential.
get/admin/managed-settlementsCross-merchant managed-settlement queue.

Signed platform-credential-only read. Lists managed settlements across every merchant with gross/fee/net and lifecycle status (esp. failed rows needing intervention); keyset paging anchored on (updated_at, transaction_public_id).

Responses

  • 200A page of managed settlements plus a nextCursor.
  • 403Credential lacks settlements:read or is not the configured platform credential.
get/admin/provider-settingsRead the active admin-configured provider settings.

Platform-credential only. The active record is the highest append-only version; version 0 mirrors the code default provider router (sandbox, Onramper enabled, direct providers disabled) until an admin override exists.

Responses

  • 200Active provider settings with version and audit metadata.
  • 403Credential lacks provider_settings:read or is not the platform credential.
put/admin/provider-settingsUpdate provider environment, router strategy, route matrix, and country overrides.

Signed, nonce-protected, platform-credential-only endpoint. Appends a new provider-settings version and requires an audit change reason.

Request body

onrampEnvironment required"sandbox" | "production"
routingStrategy required"best_price" | "easiest_kyc" | "highest_success" | "manual_priority"
providers requiredstring[]Provider route configs: enabled flag, priority, buy/sell MonaxPay fee bps, rails, assets, fiats, country allow/block lists, readiness, and managed-wallet support.
countryOverrides requiredstring[]Country + rail specific provider allow/order overrides, e.g. DE buy routes first to Onramper.
changeReason requiredstring (6โ€“500 chars)

Responses

  • 200New active provider-settings version with audit metadata.
  • 403Credential lacks provider_settings:write or is not the platform credential.
  • 409Replayed signed nonce.
get/admin/platform-settingsRead the whitelabel platform identity settings.

Platform-credential only. Returns the admin-editable company identity facts (brand name, legal entity, register/tax identifiers, registered address, contact channels) plus audit metadata. Falls back to the seeded MonaxPay/DESA defaults when no override exists.

Responses

  • 200Active platform identity settings with audit metadata.
  • 403Credential lacks platform_settings:read or is not the platform credential.
put/admin/platform-settingsUpdate the whitelabel platform identity settings.

Signed, nonce-protected, platform-credential-only endpoint. Partial update: omitted fields keep their stored value, explicit null clears a nullable fact. Requires an audit change reason and records an operator action.

Request body

brandName optionalstring (1โ€“80 chars)
legalName optionalstring (1โ€“160 chars)
registrationNo optionalstring (1โ€“160 chars)
taxId optionalstring,null (1โ€“80 chars)
vatId optionalstring,null (1โ€“80 chars)
registeredAddress optionalstring (1โ€“500 chars)
managingDirector optionalstring,null (1โ€“160 chars)
contactEmail optionalstring (0โ€“254 chars, email)
supportEmail optionalstring (0โ€“254 chars, email)
contactPhone optionalstring,null (5โ€“32 chars)
merchantTotpRequired optionalboolean
changeReason requiredstring (6โ€“500 chars)

Responses

  • 200New active platform identity settings with audit metadata.
  • 400Validation failed or no identity field was provided.
  • 403Credential lacks platform_settings:write or is not the platform credential.
  • 409Replayed signed nonce.
put/admin/platform-settings/logoUpload or replace the platform brand logo.

Signed, nonce-protected, platform-credential-only endpoint. Accepts base64 PNG/JPEG/WebP up to 1 MB; magic bytes are re-validated server-side. The upsert is idempotent (single logo slot).

Request body

contentType required"image/png" | "image/jpeg" | "image/webp"
imageBase64 requiredstring (4โ€“1400000 chars)
changeReason requiredstring (6โ€“500 chars)

Responses

  • 200Stored platform logo metadata with its versioned public URL.
  • 400Logo too large, not valid base64, or magic bytes mismatch.
  • 403Credential lacks platform_settings:write or is not the platform credential.
  • 409Replayed signed nonce.
get/admin/fee-policyRead the active platform fee policy.

Platform-credential only. Returns append-only version metadata for payment-link, on-ramp, and off-ramp fees. Swap is free at the MonaxPay layer and is returned as swapBps=0 for backwards-compatible clients.

Responses

  • 200Active platform fee policy with version and audit metadata.
  • 403Credential lacks fee_policy:read or is not the platform credential.
put/admin/fee-policyImmediately update platform fee rates.

Signed, nonce-protected, platform-credential-only endpoint. V1 applies changes immediately, records a new append-only version, and requires an audit change reason.

Request body

paymentLinkBps requiredinteger (0โ€“5000)
onrampBps requiredinteger (0โ€“5000)
offrampBps requiredinteger (0โ€“5000)
swapBps optionalinteger (0โ€“0)Always 0. Swap has no MonaxPay platform fee; retained for backwards compatibility.
changeReason requiredstring (6โ€“500 chars)

Responses

  • 200New active platform fee policy.
  • 403Credential lacks fee_policy:write or is not the platform credential.
  • 409Replayed signed nonce.
get/admin/compliance-policyRead the active admin-configured compliance policy.

Platform-credential only. Version 0 mirrors the code default until an admin override exists.

Responses

  • 200Active compliance policy with version and audit metadata.
  • 403Credential lacks compliance_policy:read or is not the platform credential.
put/admin/compliance-policyImmediately update compliance route-gating policy.

Signed, nonce-protected, platform-credential-only endpoint. Updates prohibited category terms, manual-review rails, automated Solana assets, and wallet risk threshold. Requires an audit change reason.

Request body

blockedCategories requiredstring (1โ€“120 chars)[]
highRiskRails required"buy" | "sell" | "swap" | "send" | "request" | "merchant_payment" | "fee_collection" | "refund_manual"[]
automatedSolanaAssets required"USDC" | "USDT" | "SOL"[]
walletRiskThreshold requiredinteger (0โ€“100)
changeReason requiredstring (6โ€“500 chars)

Responses

  • 200New active compliance policy.
  • 403Credential lacks compliance_policy:write or is not the platform credential.
  • 409Replayed signed nonce.
get/admin/accounts/{accountId}/restrictionsRead merchant-specific controls and freeze state.

Platform-credential only. Returns asset, country, activity, fee override, API, link, account, and settlement controls for one merchant.

Parameters

accountId path ยท requiredstring (6โ€“80 chars)

Responses

  • 200Merchant restrictions, or null if none exist.
  • 403Credential lacks merchant_restrictions:read or is not the platform credential.
put/admin/accounts/{accountId}/restrictionsUpdate merchant restrictions, fee override, and freeze controls.

Signed, nonce-protected, platform-credential-only endpoint. Freeze controls are enforced in new-link creation, public checkout read, settlement sweep claim, and merchant API auth paths.

Parameters

accountId path ยท requiredstring (6โ€“80 chars)

Request body

blockedAssets optional"USDC" | "USDT" | "SOL"[]
blockedPayerCountries optionalstring (2โ€“2 chars)[]
blockedPurposeTerms optionalstring[]
accountFrozen optionalboolean
newLinksFrozen optionalboolean
activeLinksFrozen optionalboolean
settlementFrozen optionalboolean
apiAccessFrozen optionalboolean
feeBps optionalinteger,null (0โ€“5000)
notes optionalstring (0โ€“1000 chars)
changeReason optionalstring (6โ€“500 chars)

Responses

  • 200Updated merchant restrictions.
  • 403Credential lacks merchant_restrictions:write or is not the platform credential.
  • 404Merchant account was not found.
  • 409Replayed signed nonce.

/maintenance

post/maintenance/pruneDelete expired operational rows in capped batches.

Signed, nonce-protected platform-credential maintenance job. Deletes up to 5000 expired rows per table per call from idempotency keys, signed-request nonces, auth replay consumptions (only rows with an expiry), and expired dashboard sessions. Live rows are never touched, so repeated calls are idempotent. Responds with { data: { idempotencyKeys, nonces, authReplays, dashboardSessions } } deletion counts.

Responses

  • 200Deletion counts per pruned table.
  • 403Credential lacks maintenance:write or is not the configured platform credential.
  • 409Signed request nonce was replayed.

/account-provisioning

post/account-provisioning/applyApply an account provisioning review package.

Signed, nonce-protected, idempotent endpoint used by the admin dashboard bridge after the platform super admin validates a canonical operator action review package. The super admin applies every package alone โ€” including dual-control and risk-flagged reviews โ€” and the reviewer/approver identities are recorded in the audit trail. The review metadata is authoritative; duplicated apply calls for the same review do not double top-up fee credit.

Request body

accountId requiredstring (6โ€“80 chars)
reviewActionId requiredstring (3โ€“80 chars)
requestedAccountId requiredstring (6โ€“80 chars)
reviewPackageRef requiredstring (6โ€“120 chars)
secondApproverId requiredstring (3โ€“120 chars)

Responses

  • 200Provisioning applied or safely recognized as already applied.
  • 403Credential is not scoped to the submitted platform account.
  • 404Review operator action was not found.
  • 409Idempotency mismatch, invalid review package, review mismatch, or same approver attempted to apply.

/team-members

get/team-membersList account-scoped dashboard team members.

Returns redacted dashboard team member state for settings and admin surfaces. Requires team_members:read scope.

Responses

  • 200Recent team members returned.
  • 403Credential does not have team_members:read scope.
post/team-membersInvite, resend, suspend, or require TOTP for dashboard team members.

Signed, nonce-protected, idempotent endpoint used by the web dashboard bridge. Owner access is protected and cross-account bodies are rejected.

Responses

  • 200Team member operation applied or idempotent replay returned.
  • 201Team member invite accepted.
  • 400Invalid action, role, email, or metadata.
  • 403Credential is not scoped to the submitted account.
  • 404Team member was not found.
  • 409Idempotency payload mismatch, owner protection, suspended invite resend, or replayed signature.
post/team-members/acceptAccept a one-time dashboard team invite.

Signed, nonce-protected, idempotent endpoint used by invite links. The raw invite token is never stored; callers submit its SHA-256 hash and the canonical API consumes the pending invite.

Responses

  • 200Team invite accepted and member activated with TOTP required.
  • 400Invalid account, email, or invite token hash.
  • 403Credential is not scoped to the submitted account.
  • 404Team invite was not found.
  • 409Invite was already accepted, member is suspended, or signature replayed.
  • 410Team invite has expired.
post/team-members/accept/beginStart loginable invite acceptance: set a password and begin TOTP enrollment.

Signed, nonce-protected endpoint used by invite links. Validates the SHA-256 invite token hash, stages a dashboard auth user bound to the inviting account with the invited role, and returns a one-time TOTP secret and short-lived setup token. The invite is consumed only by /team-members/accept/confirm.

Responses

  • 200Password accepted and TOTP enrollment started; setup token returned.
  • 403Credential is not scoped to the submitted account.
  • 404Team invite was not found.
  • 409Email already has a merchant dashboard account elsewhere, member is suspended, owner-protected, or already active.
  • 410Team invite has expired.
post/team-members/accept/confirmConfirm TOTP and finalize loginable invite acceptance.

Signed, nonce-protected, idempotent endpoint. Verifies the TOTP code from /team-members/accept/begin, activates the invited member's dashboard auth user, and consumes the pending invite so the member can sign in with their own credentials and role.

Responses

  • 200Invite accepted and member dashboard access activated.
  • 401Authenticator code or setup token could not be verified.
  • 403Credential is not scoped to the submitted account.
  • 404Team invite was not found.
  • 409TOTP enrollment is not active, invite was already accepted, member suspended, or signature replayed.
  • 410Team invite has expired.

/fee-policy

get/fee-policy/publicPublic, non-secret consumer rail rates (buy/sell/swap).

Unauthenticated. Powers client-side 'you receive' estimates. Payment-link rates are merchant-paid and never exposed here. Responses are cacheable for 60 seconds.

Responses

  • 200Current onrampBps, offrampBps, and swapBps=0.

/accounts

get/accounts/{accountId}/effective-feeThe effective payment-link fee rate the merchant will pay.

Resolution order: per-merchant admin override โ†’ platform fee policy โ†’ environment default. Own account only, unless the caller is the platform credential.

Parameters

accountId path ยท requiredstring (6โ€“80 chars)

Responses

  • 200Effective feeBps with its source (merchant_override, platform_policy, default), settlement mode, and whether prepaid fee credit is required.
  • 403Credential lacks transaction_intents:read or cannot read fees for the requested account.

/provider-settings

get/provider-settings/publicRead the active provider environment and route-safe public summary.

Powers the web buy widget's runtime sandbox/production switch and safe route labels. Exposes only non-secret summaries โ€” never versions, audit metadata, or credentials.

Responses

  • 200Active environment, routing strategy, and enabled provider summaries.

/platform-identity

get/platform-identityRead the public whitelabel platform identity without authentication.

Returns the operator identity facts (brand name, legal entity, register/tax identifiers, registered address, contact channels) plus the versioned logo URL when a logo is stored. Cacheable for 60 seconds; never exposes audit metadata.

Responses

  • 200Public platform identity facts and logo URL.
get/platform-identity/logoServe the platform brand logo bytes without authentication.

Immutable-cacheable logo serving with ETag support; clients reference it through versioned ?v=<sha256> URLs from /platform-identity.

Parameters

v querystring (64โ€“64 chars)

Responses

  • 200Logo bytes with content-type and ETag.
  • 304Not modified (If-None-Match matched the stored sha256 ETag).
  • 404No platform logo is stored.

/provider-cashout

get/provider-cashout/onramperBind an Onramper sell cashout provider wallet to a managed settlement.

Public provider redirect endpoint protected by signed partnerContext. It binds the provider deposit wallet returned by Onramper Wallet Initiation Flow before MonaxPay sweeps the net crypto amount to that provider.

Parameters

partnerContext query ยท requiredstring (3โ€“500 chars)
providerWalletAddress query ยท requiredstring (24โ€“128 chars)
transactionId query ยท requiredstring (3โ€“160 chars)
inAmount querynumber (0โ€“โˆž)

Responses

  • 303Cashout target bound; user redirected to checkout status.
  • 401partnerContext signature is invalid.
  • 404Transaction intent was not found.
  • 409Cashout target cannot be bound safely.
  • 422Provider wallet is not a valid Solana address.

/webhooks

post/webhooks/onramperVerify, deduplicate, and apply a signed Onramper webhook event to transaction state.

Parameters

X-Onramper-Webhook-Signature header ยท requiredstring

Responses

  • 200Webhook accepted idempotently.
  • 401Webhook signature is invalid.
post/webhooks/sumsubVerify and store a Sumsub applicant verification webhook event.

Parameters

X-Payload-Digest header ยท requiredstring
X-Payload-Digest-Alg header ยท required"HMAC_SHA256_HEX" | "HMAC_SHA512_HEX"

Responses

  • 200Webhook accepted idempotently.
  • 401Webhook signature or digest algorithm is invalid.
post/webhooks/heliusVerify, deduplicate, and apply Helius Solana settlement webhooks to transaction state.

Parameters

Authorization header ยท requiredstring

Responses

  • 200Webhook batch accepted idempotently.
  • 401Webhook authorization header is invalid.
  • 503Webhook authorization token is not configured.