{"openapi":"3.1.0","info":{"title":"MonaxPay API","version":"0.1.0","summary":"Dashboard-created API keys for payment links, transaction status, webhooks, customers, settlements, and reporting."},"servers":[{"url":"https://api.monaxpay.com/v1"}],"security":[{"ApiKeyAuth":[],"HmacSignature":[]}],"paths":{"/api-credentials":{"get":{"operationId":"listApiCredentials","summary":"List redacted API credentials for the authenticated or delegated account.","description":"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":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Must match the credential account unless the caller is the configured platform credential."}],"responses":{"200":{"description":"Redacted API credentials. Secret hashes and raw secrets are never returned."},"403":{"description":"Credential does not have api_credentials:read scope or cannot read credentials for the requested account."}}},"post":{"operationId":"createApiCredential","summary":"Create a scoped API credential and return the raw API secret once.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["scopes"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can mint credentials for merchant accounts."},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"scopes":{"type":"array","items":{"type":"string"},"minItems":1},"prefix":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,24}$","default":"mp_live"},"expiresAt":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"Credential created. The raw API secret is returned once and is not available from list APIs."},"400":{"description":"Invalid scope, prefix, or expiry."},"403":{"description":"Credential cannot manage API credentials for the requested account."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/api-credentials/{credentialKey}/rotate":{"post":{"operationId":"rotateApiCredential","summary":"Rotate an active API credential with a bounded overlap window.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"credentialKey","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can rotate merchant credentials."},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"prefix":{"type":"string","pattern":"^[a-z][a-z0-9_]{2,24}$","default":"mp_live"},"overlapMinutes":{"type":"integer","minimum":1,"maximum":10080,"default":60}}}}}},"responses":{"201":{"description":"New credential created and the replaced credential moved to rotating state."},"403":{"description":"Credential cannot manage API credentials for the requested account."},"404":{"description":"Credential not found for the target account."},"409":{"description":"Credential is not active, idempotency mismatch, or replayed signature."}}}},"/api-credentials/{credentialKey}/revoke":{"post":{"operationId":"revokeApiCredential","summary":"Revoke an API credential for the authenticated or delegated account.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"credentialKey","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can revoke merchant credentials."},"requestedBy":{"type":"string","minLength":3,"maxLength":120}}}}}},"responses":{"200":{"description":"Credential revoked or idempotent replay returned."},"403":{"description":"Credential cannot manage API credentials for the requested account."},"404":{"description":"Credential not found for the target account."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/api-credentials/{credentialKey}/policy":{"post":{"operationId":"updateApiCredentialPolicy","summary":"Update source IP allowlist and per-scope max-age policy for an API credential.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"credentialKey","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can update merchant credential policies."},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"ipAllowlist":{"type":"array","items":{"type":"string","minLength":2,"maxLength":64},"maxItems":50,"default":[]},"scopeMaxAgeDays":{"type":"object","additionalProperties":{"type":"integer","minimum":1,"maximum":365},"default":{}}}}}}},"responses":{"200":{"description":"Credential policy updated or idempotent replay returned."},"400":{"description":"Invalid IP/CIDR allowlist or scope max-age policy."},"403":{"description":"Credential cannot manage API credentials for the requested account."},"404":{"description":"Credential not found for the target account."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/api-credentials/{credentialKey}/status":{"post":{"operationId":"updateApiCredentialStatus","summary":"Suspend or mark an API credential as compromised.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"credentialKey","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can update merchant credential status."},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"status":{"type":"string","enum":["suspended","compromised"]},"reason":{"type":"string","minLength":6,"maxLength":240}}}}}},"responses":{"200":{"description":"Credential status updated or idempotent replay returned."},"403":{"description":"Credential cannot manage API credentials for the requested account."},"404":{"description":"Credential not found for the target account."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/auth/replay-consumptions":{"post":{"operationId":"consumeAuthReplayKey","summary":"Consume a dashboard authentication replay key exactly once.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Replay key consumed."},"400":{"description":"Invalid replay type, hash, expiry, or metadata."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Replay key was already consumed or signed nonce was replayed."}}}},"/auth/recovery-codes/rotate":{"post":{"operationId":"rotateDashboardRecoveryCodes","summary":"Rotate dashboard recovery-code hashes for an account audience.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Recovery-code hash batch activated."},"400":{"description":"Invalid audience, hash list, delivery metadata, or idempotency key."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Idempotency payload mismatch or signed nonce replay."}}}},"/auth/recovery-codes/consume":{"post":{"operationId":"consumeDashboardRecoveryCodeHash","summary":"Consume one dashboard recovery-code hash exactly once.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recovery-code hash consumed."},"400":{"description":"Invalid audience, hash, or metadata."},"401":{"description":"Recovery code was not found in the active batch."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Recovery code was already consumed or signed nonce was replayed."}}}},"/auth/dashboard-sessions":{"post":{"operationId":"registerDashboardSession","summary":"Register an issued dashboard session in the canonical session registry.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Dashboard session registered."},"400":{"description":"Invalid session hash, role set, expiry, or metadata."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Signed request nonce was replayed."}}}},"/auth/dashboard-sessions/verify":{"post":{"operationId":"verifyDashboardSession","summary":"Verify that a dashboard session hash is still active.","description":"Used by production dashboard API routes before privileged operations. Inactive, expired, revoked, or unknown sessions return dashboard_session_inactive.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dashboard session is active."},"400":{"description":"Invalid session hash or metadata."},"401":{"description":"Dashboard session is inactive, expired, revoked, or unknown."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Signed request nonce was replayed."}}}},"/auth/dashboard-sessions/list":{"post":{"operationId":"listDashboardSessions","summary":"List canonical dashboard session hashes for the authenticated account.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dashboard sessions returned."},"400":{"description":"Invalid status filter, limit, account, or metadata."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Signed request nonce was replayed."}}}},"/auth/dashboard-sessions/revoke":{"post":{"operationId":"revokeDashboardSession","summary":"Revoke a dashboard session hash.","description":"Used by dashboard logout and incident-response flows. Revocation is account-scoped and returns whether a matching active registry row was updated.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Dashboard session revocation processed."},"400":{"description":"Invalid session hash or reason."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Signed request nonce was replayed."}}}},"/auth/self-serve/password-reset/request":{"post":{"operationId":"requestSelfServePasswordReset","summary":"Request a self-serve dashboard password reset code.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"audience":{"type":"string","enum":["merchant"],"default":"merchant"},"locale":{"type":"string","enum":["en","de","tr"]}}}}}},"responses":{"202":{"description":"Reset request accepted ({ data: { accepted: true } })."},"403":{"description":"Credential is not the configured platform bridge credential."},"409":{"description":"Signed request nonce was replayed."},"429":{"description":"Too many reset requests for this email."}}}},"/auth/self-serve/password-reset/confirm":{"post":{"operationId":"confirmSelfServePasswordReset","summary":"Confirm a password reset code and set a new dashboard password.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","code","newPassword"],"additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"audience":{"type":"string","enum":["merchant"],"default":"merchant"},"code":{"type":"string","pattern":"^\\d{6}$"},"newPassword":{"type":"string","minLength":12,"maxLength":200}}}}}},"responses":{"200":{"description":"Password updated ({ data: { updated: true } })."},"401":{"description":"Reset code is invalid, expired, or already used (invalid_reset_code)."},"403":{"description":"Credential is not the configured platform bridge credential."},"409":{"description":"Signed nonce replay, or the account cannot reset its password."},"429":{"description":"Too many failed reset attempts for this email."}}}},"/merchant-profile/logo":{"post":{"operationId":"uploadMerchantLogo","summary":"Store the public merchant checkout logo for an account.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contentType","imageBase64"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can store logos for merchant accounts."},"contentType":{"type":"string","enum":["image/png","image/jpeg","image/webp"]},"imageBase64":{"type":"string","minLength":4,"maxLength":1400000,"description":"Standard base64 image payload, at most 1 MB decoded."},"requestedBy":{"type":"string","minLength":3,"maxLength":120}}}}}},"responses":{"201":{"description":"Logo stored. The response returns the content hash used for versioned public URLs and never echoes the image bytes."},"400":{"description":"Image is not valid base64, exceeds 1 MB, or fails magic-byte checks."},"403":{"description":"Credential cannot store logos for the requested account, or the account is not enabled."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/merchant-profile/logo/{accountId}":{"get":{"operationId":"getMerchantLogo","summary":"Read the stored public merchant logo bytes for an account.","description":"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":[{"name":"accountId","in":"path","required":true,"schema":{"type":"string","minLength":6,"maxLength":80}}],"security":[],"responses":{"200":{"description":"Raw logo bytes with image content type, ETag, and cache headers."},"304":{"description":"Logo unchanged for the supplied If-None-Match ETag."},"404":{"description":"No logo is stored for this account."}}}},"/auth/social-identities/resolve":{"post":{"operationId":"resolveSocialIdentity","summary":"Resolve a linked dashboard social identity.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Social identity is linked and active."},"400":{"description":"Invalid account, provider, subject, email, or metadata."},"401":{"description":"Social identity is not linked, inactive, or email-bound to another user."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Signed request nonce was replayed."}}}},"/auth/social-identities":{"post":{"operationId":"upsertSocialIdentity","summary":"Create or update an account-scoped social identity link.","description":"Used by approved admin/operator workflows to bind Google or Telegram provider subjects to a dashboard account/audience. Writes are idempotent and audit logged.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Social identity link created or updated."},"400":{"description":"Invalid account, provider, subject, email, status, or metadata."},"403":{"description":"Credential is not scoped to the submitted account."},"409":{"description":"Idempotency payload mismatch or signed nonce replay."}}}},"/compliance/precheck":{"post":{"operationId":"createCompliancePrecheck","summary":"Check whether a route can create a live transaction intent.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Compliance decision."}}}},"/fee-topups":{"post":{"operationId":"createFeeCreditTopup","summary":"Create a pending prepaid fee-credit top-up intent.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","amountMinor","asset"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"amountMinor":{"type":"integer","minimum":1,"maximum":100000000},"asset":{"type":"string","enum":["USDC","USDT"]},"network":{"type":"string","enum":["solana"],"default":"solana"},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"metadata":{"type":"object"}}}}}},"responses":{"201":{"description":"Pending top-up intent with destination treasury wallet, token mint, exact amount, memo, and expiry."},"402":{"description":"Reserved for future on-chain payment failures."},"409":{"description":"Idempotency payload mismatch or signed nonce replay."},"503":{"description":"Fee-credit treasury wallet or token mint configuration is missing."}}}},"/fee-topups/list":{"post":{"operationId":"listFeeCreditTopups","summary":"List prepaid fee-credit top-up intents for an account.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId"],"additionalProperties":false,"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80}}}}}},"responses":{"200":{"description":"Top-up intents (pending, confirmed, expired, cancelled) without internal treasury metadata."},"403":{"description":"Credential lacks fee_topups:read or cannot act for the requested account."},"409":{"description":"Replayed signed nonce."}}}},"/customers":{"get":{"operationId":"listMerchantCustomers","summary":"List the merchant's customer directory.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Must match the credential account unless the caller is the platform credential."}],"responses":{"200":{"description":"Customers for the resolved account."},"403":{"description":"Credential lacks customers:read or cannot read customers for the requested account."}}},"post":{"operationId":"upsertMerchantCustomer","summary":"Create a customer, or update one by passing its customerId.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["displayName"],"additionalProperties":false,"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"customerId":{"type":"string","minLength":8,"maxLength":80,"description":"Pass an existing customerId to update instead of create."},"displayName":{"type":"string","minLength":2,"maxLength":160},"email":{"type":"string","format":"email","maxLength":254},"companyName":{"type":"string","maxLength":160},"billingAddress":{"type":"string","maxLength":500},"country":{"type":"string","minLength":2,"maxLength":2},"taxId":{"type":"string","maxLength":80},"notes":{"type":"string","maxLength":1000},"status":{"type":"string","enum":["active","archived"],"default":"active"}}}}}},"responses":{"200":{"description":"Customer updated (customerId was supplied)."},"201":{"description":"Customer created."},"404":{"description":"customerId was supplied but no such customer exists."},"409":{"description":"Idempotency payload mismatch or replayed signed nonce."}}}},"/customers/{customerId}":{"delete":{"operationId":"deleteMerchantCustomer","summary":"GDPR self-service soft-delete of a customer.","description":"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":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Must match the credential account unless the caller is the platform credential."}],"responses":{"200":{"description":"Customer soft-deleted."},"403":{"description":"Credential lacks customers:write or cannot delete customers for the requested account."},"404":{"description":"No live customer matches the supplied customerId."}}}},"/accounting/documents":{"get":{"operationId":"listAccountingDocuments","summary":"List gross-only accounting documents (proformas, invoices, receipts).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Must match the credential account unless the caller is the platform credential."}],"responses":{"200":{"description":"Accounting documents for the resolved account."},"403":{"description":"Credential lacks accounting:read or cannot read documents for the requested account."}}},"post":{"operationId":"upsertAccountingDocument","summary":"Create an accounting document, or update one by passing its documentId.","description":"Line totals are computed server-side (quantity × unitAmountMinor, gross-only, taxMode none). Optional customerId and transactionPublicId references must exist for the account.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","lineItems"],"additionalProperties":false,"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"documentId":{"type":"string","minLength":8,"maxLength":80,"description":"Pass an existing documentId to update instead of create."},"customerId":{"type":"string","minLength":8,"maxLength":80},"transactionPublicId":{"type":"string","minLength":3,"maxLength":80},"documentNumber":{"type":"string","minLength":3,"maxLength":80},"type":{"type":"string","enum":["proforma","invoice","receipt","credit_note","refund_note","fee_statement"],"default":"proforma"},"status":{"type":"string","enum":["draft","issued","linked","paid","cancelled","void","refunded"],"default":"draft"},"currency":{"type":"string","enum":["USD","EUR","TRY","GBP"],"default":"USD"},"title":{"type":"string","minLength":2,"maxLength":160},"description":{"type":"string","maxLength":1000},"dueAt":{"type":"string","format":"date-time"},"issuedAt":{"type":"string","format":"date-time"},"paidAt":{"type":"string","format":"date-time"},"lineItems":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["description","unitAmountMinor"],"additionalProperties":false,"properties":{"lineItemId":{"type":"string","minLength":6,"maxLength":80},"description":{"type":"string","minLength":2,"maxLength":240},"quantity":{"type":"number","exclusiveMinimum":0,"default":1},"unitAmountMinor":{"type":"integer","minimum":0}}}},"metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"Document updated (documentId was supplied)."},"201":{"description":"Document created."},"404":{"description":"A supplied documentId, customerId, or transactionPublicId does not exist for the account."},"409":{"description":"Idempotency payload mismatch or replayed signed nonce."}}}},"/accounting/statements/{period}":{"get":{"operationId":"getMerchantMonthlyStatement","summary":"Monthly reconciliation statement for confirmed payment activity.","description":"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":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"period","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"},"description":"Calendar month in YYYY-MM form, e.g. 2026-06."},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Must match the credential account unless the caller is the platform credential."}],"responses":{"200":{"description":"Monthly statement for the resolved account and period."},"403":{"description":"Credential lacks accounting:read or cannot read statements for the requested account."}}}},"/transaction-intents":{"post":{"operationId":"createTransactionIntent","summary":"Create a payment, request, buy, sell, swap, or send intent.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountId","rail","payerCountry","recipientCountry","fiatAmountMinor","walletAddress","merchantDisplayName","reference","purpose"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"rail":{"type":"string","enum":["buy","sell","swap","send","request","merchant_payment","fee_collection","refund_manual"]},"payerCountry":{"type":"string","minLength":2,"maxLength":2},"recipientCountry":{"type":"string","minLength":2,"maxLength":2},"fiatCurrency":{"type":"string","enum":["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":{"type":"integer","minimum":1,"maximum":100000000},"targetAsset":{"type":"string","enum":["USDC","USDT","SOL"],"description":"V1 managed settlement assets. Additional assets stay route-gated and are not accepted by this endpoint."},"targetNetwork":{"type":"string","enum":["solana"],"description":"V1 managed settlement network."},"walletAddress":{"type":"string","minLength":24,"maxLength":128},"merchantDisplayName":{"type":"string","minLength":2,"maxLength":80},"payerName":{"type":"string","minLength":1,"maxLength":120},"payerEmail":{"type":"string","format":"email","maxLength":254},"reference":{"type":"string","minLength":3,"maxLength":120},"purpose":{"type":"string","minLength":3,"maxLength":160},"campaignId":{"type":"string","minLength":3,"maxLength":80},"linkMode":{"type":"string","enum":["one_time"],"description":"Reusable links are reserved for a later release with max-use and max-volume enforcement."},"expiresIn":{"type":"string","enum":["24h","72h","7d","manual"]},"expiresAt":{"type":"string","format":"date-time"},"successUrl":{"type":"string","format":"uri","description":"Optional public HTTPS redirect after provider success."},"failureUrl":{"type":"string","format":"uri","description":"Optional public HTTPS redirect after provider failure."},"internalNotes":{"type":"string","maxLength":1000},"metadata":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}}}}}},"responses":{"201":{"description":"Intent created. The response includes authoritative input, fee calculation, checkout URL, receipt URL, and optional signed Onramper URL."},"409":{"description":"Compliance manual review or idempotency payload mismatch."}}},"get":{"operationId":"listTransactionIntents","summary":"List recent transaction intents for the authenticated account.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent intents."}}}},"/transaction-intents/{publicId}":{"get":{"operationId":"getTransactionIntent","summary":"Read one transaction intent by public ID.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Intent found."},"404":{"description":"Intent not found."}}}},"/transaction-intents/{publicId}/receipt":{"get":{"operationId":"getTransactionIntentReceipt","summary":"Read the issued receipt for a confirmed transaction intent.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Receipt found."},"404":{"description":"Receipt not issued or not found."}}}},"/payer/receipts":{"get":{"operationId":"listPayerReceipts","summary":"List receipts for a verified payer email through a platform-scoped bridge.","description":"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":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email","maxLength":254}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Receipts owned by the verified payer email."},"403":{"description":"Credential is not platform-scoped."}}}},"/receipts/{receiptId}":{"get":{"operationId":"getReceipt","summary":"Read one issued receipt by receipt ID.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Receipt found."},"404":{"description":"Receipt not found."}}}},"/receipts/{receiptId}/deliveries":{"get":{"operationId":"listReceiptDeliveries","summary":"List delivery attempts for one receipt.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Receipt delivery attempts."},"404":{"description":"Receipt not found."}}},"post":{"operationId":"createReceiptDelivery","summary":"Record an email delivery or failed resend attempt for one receipt.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Receipt delivery recorded."},"404":{"description":"Receipt not found."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/partner-webhook-endpoints":{"post":{"operationId":"createPartnerWebhookEndpoint","summary":"Create a merchant-owned outbound webhook endpoint and return its signing secret once.","description":"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>`.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Endpoint created and signing secret returned once."},"400":{"description":"Endpoint URL is not allowed."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}},"get":{"operationId":"listPartnerWebhookEndpoints","summary":"List merchant-owned outbound webhook endpoints without secret material.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent outbound webhook endpoints."}}}},"/partner-webhook-endpoints/{endpointId}/status":{"post":{"operationId":"setPartnerWebhookEndpointStatus","summary":"Enable or disable an outbound webhook endpoint.","description":"Signed, nonce-protected. Disabling (status='suspended') stops delivery immediately without losing delivery history; re-enabling restores it.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"additionalProperties":false,"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"status":{"type":"string","enum":["active","suspended"]},"requestedBy":{"type":"string","minLength":3,"maxLength":120}}}}}},"responses":{"200":{"description":"Endpoint status updated."},"403":{"description":"Credential cannot manage webhook endpoints for the requested account."},"404":{"description":"Endpoint not found."}}}},"/partner-webhook-endpoints/{endpointId}/delete":{"post":{"operationId":"deletePartnerWebhookEndpoint","summary":"Soft-delete an outbound webhook endpoint.","description":"Signed, nonce-protected. The endpoint is excluded from listings and never delivered to, while its delivery audit trail is preserved.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Endpoint soft-deleted."},"403":{"description":"Credential cannot manage webhook endpoints for the requested account."},"404":{"description":"Endpoint not found."}}}},"/partner-webhook-endpoints/{endpointId}/rotate-secret":{"post":{"operationId":"rotatePartnerWebhookEndpointSecret","summary":"Rotate an endpoint's signing secret and return the new secret once.","description":"Signed, nonce-protected. The new secret is returned exactly once; the old secret stops verifying immediately, so partners must update their verifier.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Secret rotated; new signing secret returned once."},"403":{"description":"Credential cannot manage webhook endpoints for the requested account."},"404":{"description":"Endpoint not found."}}}},"/partner-webhook-deliveries":{"get":{"operationId":"listPartnerWebhookDeliveries","summary":"List recent outbound webhook delivery attempts for the authenticated account.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","delivered","failed"]},"description":"Optional delivery status filter."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":100},"description":"Maximum delivery rows to return."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Delivery ID cursor returned as pagination.nextCursor."}],"responses":{"200":{"description":"Recent outbound webhook delivery attempts."}}}},"/partner-webhook-deliveries/{deliveryId}/replay":{"post":{"operationId":"replayPartnerWebhookDelivery","summary":"Replay one outbound webhook delivery with the original signed event payload.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"accountId":{"type":"string","minLength":6,"maxLength":80,"description":"Optional delegation target. The platform credential can replay merchant deliveries."},"requestedBy":{"type":"string","minLength":3,"maxLength":120}}}}}},"responses":{"202":{"description":"Delivery replay attempted and recorded."},"403":{"description":"Credential cannot replay webhook deliveries for the requested account."},"404":{"description":"Delivery not found."},"409":{"description":"Idempotency payload mismatch, replayed signature, or inactive endpoint."}}}},"/transaction-intents/{publicId}/cancel":{"post":{"operationId":"cancelTransactionIntent","summary":"Cancel a cancellable transaction intent.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Intent cancelled or idempotent replay."},"409":{"description":"Intent state cannot be cancelled."}}}},"/analytics/overview":{"get":{"operationId":"getAnalyticsOverview","summary":"Read merchant analytics overview.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}}]}},"/refund-cases":{"get":{"operationId":"listRefundCases","summary":"List account-scoped refund and dispute cases.","description":"Signed read. Merchant credentials read their own refund cases; the platform credential can pass accountId to inspect a merchant account for admin support.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"query","required":false,"schema":{"type":"string","minLength":6,"maxLength":80},"description":"Optional delegation target. Requires the configured platform credential when different from the authenticated account."}],"responses":{"200":{"description":"Refund cases for the resolved account."},"403":{"description":"Credential lacks accounting:read or cannot read the requested account."}}},"post":{"operationId":"createOrUpdateRefundCase","summary":"Create or update a refund/dispute case for a settled payment.","description":"Signed, idempotent write. Crypto-settled refunds remain merchant-executed; MonaxPay records instructions, merchant transaction signatures, and optional Helius proof.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["transactionPublicId","requestedAmountMinor","asset","network","reason"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"refundCaseId":{"type":"string","minLength":8,"maxLength":80},"transactionPublicId":{"type":"string","minLength":3,"maxLength":80},"customerId":{"type":"string","minLength":8,"maxLength":80},"requestedAmountMinor":{"type":"integer","minimum":1},"currency":{"type":"string","enum":["USD","EUR","TRY","GBP"],"default":"USD"},"asset":{"type":"string","enum":["USDC","USDT","SOL"]},"network":{"type":"string","const":"solana"},"destinationWalletAddress":{"type":"string","minLength":24,"maxLength":128},"merchantRefundTransactionId":{"type":"string","minLength":3,"maxLength":180},"reason":{"type":"string","minLength":3,"maxLength":500},"status":{"type":"string","enum":["requested","instructions_sent","merchant_sent","confirmed","rejected","cancelled"],"default":"requested"},"refundProof":{"type":"object","additionalProperties":false,"properties":{"provider":{"type":"string","const":"helius"},"signature":{"type":"string","minLength":12,"maxLength":180},"destinationWalletAddress":{"type":"string","minLength":24,"maxLength":128},"asset":{"type":"string","enum":["USDC","USDT","SOL"]},"matchedTransferKind":{"type":"string","enum":["spl","native"]},"observedAmount":{"type":"number","exclusiveMinimum":0},"amountMatched":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"string"},"maxItems":20},"verifiedAt":{"type":"string","format":"date-time"}}}}}}}},"responses":{"200":{"description":"Refund case updated."},"201":{"description":"Refund case created."},"403":{"description":"Credential lacks accounting:write or cannot write the requested account."},"404":{"description":"Referenced transaction or refund case was not found."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}}},"/operator-actions":{"post":{"operationId":"createOperatorAction","summary":"Create an authenticated operator action for dashboard or back-office workflow.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"required":["accountId","label","context","surface"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"label":{"type":"string","minLength":3,"maxLength":120},"context":{"type":"string","minLength":3,"maxLength":500},"surface":{"type":"string","minLength":3,"maxLength":120},"requestedBy":{"type":"string","minLength":3,"maxLength":120},"metadata":{"type":"object","additionalProperties":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}}}}}},"responses":{"202":{"description":"Operator action accepted and audit logged."},"403":{"description":"Credential cannot create actions for the requested account."},"409":{"description":"Idempotency payload mismatch or replayed signature."}}},"get":{"operationId":"listOperatorActions","summary":"List recent operator actions for the authenticated account.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent operator actions."}}}},"/admin/operator-actions":{"get":{"operationId":"listAdminOperatorActions","summary":"List recent platform-wide operator actions for admin audit.","description":"Signed platform-credential-only read. Returns delegated merchant-account operator actions as well as platform-account actions for the admin audit tab.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent platform-wide operator actions."},"403":{"description":"Credential lacks operator_actions:read or is not the configured platform credential."}}}},"/admin/operator-actions/page":{"get":{"operationId":"listAdminOperatorActionsPage","summary":"Keyset-paged operator-action audit feed with surface + date filters.","description":"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).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of operator actions plus a nextCursor."},"403":{"description":"Credential lacks operator_actions:read or is not the configured platform credential."}}}},"/admin/accounts":{"get":{"operationId":"listAdminAccounts","summary":"Keyset-paged merchants directory across all accounts.","description":"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).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of merchant summaries plus a nextCursor."},"400":{"description":"The supplied directory cursor is no longer valid."},"403":{"description":"Credential lacks accounts:read or is not the configured platform credential."}}}},"/admin/analytics":{"get":{"operationId":"getAdminPlatformAnalytics","summary":"Platform-wide payment activity analytics from persisted data.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Platform analytics for the requested window."},"403":{"description":"Credential lacks analytics_platform:read or is not the configured platform credential."}}}},"/admin/refund-cases":{"get":{"operationId":"listAdminRefundCases","summary":"Cross-merchant refund-case queue.","description":"Signed platform-credential-only read. Lists refund cases across every merchant, filterable by status; keyset paging anchored on (updated_at, refund_case_id).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of refund cases plus a nextCursor."},"403":{"description":"Credential lacks accounting:read or is not the configured platform credential."}}}},"/admin/managed-settlements":{"get":{"operationId":"listAdminManagedSettlements","summary":"Cross-merchant managed-settlement queue.","description":"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).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"A page of managed settlements plus a nextCursor."},"403":{"description":"Credential lacks settlements:read or is not the configured platform credential."}}}},"/maintenance/prune":{"post":{"operationId":"pruneExpiredOperationalRecords","summary":"Delete expired operational rows in capped batches.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deletion counts per pruned table."},"403":{"description":"Credential lacks maintenance:write or is not the configured platform credential."},"409":{"description":"Signed request nonce was replayed."}}}},"/account-provisioning/apply":{"post":{"operationId":"applyAccountProvisioningReview","summary":"Apply an account provisioning review package.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["accountId","reviewActionId","requestedAccountId","reviewPackageRef","secondApproverId"],"properties":{"accountId":{"type":"string","minLength":6,"maxLength":80},"reviewActionId":{"type":"string","minLength":3,"maxLength":80},"requestedAccountId":{"type":"string","minLength":6,"maxLength":80},"reviewPackageRef":{"type":"string","minLength":6,"maxLength":120},"secondApproverId":{"type":"string","minLength":3,"maxLength":120}}}}}},"responses":{"200":{"description":"Provisioning applied or safely recognized as already applied."},"403":{"description":"Credential is not scoped to the submitted platform account."},"404":{"description":"Review operator action was not found."},"409":{"description":"Idempotency mismatch, invalid review package, review mismatch, or same approver attempted to apply."}}}},"/team-members":{"get":{"operationId":"listTeamMembers","summary":"List account-scoped dashboard team members.","description":"Returns redacted dashboard team member state for settings and admin surfaces. Requires team_members:read scope.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Recent team members returned."},"403":{"description":"Credential does not have team_members:read scope."}}},"post":{"operationId":"mutateTeamMember","summary":"Invite, resend, suspend, or require TOTP for dashboard team members.","description":"Signed, nonce-protected, idempotent endpoint used by the web dashboard bridge. Owner access is protected and cross-account bodies are rejected.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Team member operation applied or idempotent replay returned."},"201":{"description":"Team member invite accepted."},"400":{"description":"Invalid action, role, email, or metadata."},"403":{"description":"Credential is not scoped to the submitted account."},"404":{"description":"Team member was not found."},"409":{"description":"Idempotency payload mismatch, owner protection, suspended invite resend, or replayed signature."}}}},"/team-members/accept":{"post":{"operationId":"acceptTeamMemberInvite","summary":"Accept a one-time dashboard team invite.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Team invite accepted and member activated with TOTP required."},"400":{"description":"Invalid account, email, or invite token hash."},"403":{"description":"Credential is not scoped to the submitted account."},"404":{"description":"Team invite was not found."},"409":{"description":"Invite was already accepted, member is suspended, or signature replayed."},"410":{"description":"Team invite has expired."}}}},"/team-members/accept/begin":{"post":{"operationId":"beginTeamMemberInviteAcceptance","summary":"Start loginable invite acceptance: set a password and begin TOTP enrollment.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Password accepted and TOTP enrollment started; setup token returned."},"403":{"description":"Credential is not scoped to the submitted account."},"404":{"description":"Team invite was not found."},"409":{"description":"Email already has a merchant dashboard account elsewhere, member is suspended, owner-protected, or already active."},"410":{"description":"Team invite has expired."}}}},"/team-members/accept/confirm":{"post":{"operationId":"confirmTeamMemberInviteAcceptance","summary":"Confirm TOTP and finalize loginable invite acceptance.","description":"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.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Invite accepted and member dashboard access activated."},"401":{"description":"Authenticator code or setup token could not be verified."},"403":{"description":"Credential is not scoped to the submitted account."},"404":{"description":"Team invite was not found."},"409":{"description":"TOTP enrollment is not active, invite was already accepted, member suspended, or signature replayed."},"410":{"description":"Team invite has expired."}}}},"/admin/provider-settings":{"get":{"operationId":"getProviderSettings","summary":"Read the active admin-configured provider settings.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active provider settings with version and audit metadata."},"403":{"description":"Credential lacks provider_settings:read or is not the platform credential."}}},"put":{"operationId":"updateProviderSettings","summary":"Update provider environment, router strategy, route matrix, and country overrides.","description":"Signed, nonce-protected, platform-credential-only endpoint. Appends a new provider-settings version and requires an audit change reason.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["onrampEnvironment","routingStrategy","providers","countryOverrides","changeReason"],"additionalProperties":false,"properties":{"onrampEnvironment":{"type":"string","enum":["sandbox","production"]},"routingStrategy":{"type":"string","enum":["best_price","easiest_kyc","highest_success","manual_priority"]},"providers":{"type":"array","minItems":1,"description":"Provider route configs: enabled flag, priority, buy/sell MonaxPay fee bps, rails, assets, fiats, country allow/block lists, readiness, and managed-wallet support."},"countryOverrides":{"type":"array","description":"Country + rail specific provider allow/order overrides, e.g. DE buy routes first to Onramper."},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"New active provider-settings version with audit metadata."},"403":{"description":"Credential lacks provider_settings:write or is not the platform credential."},"409":{"description":"Replayed signed nonce."}}}},"/admin/platform-settings":{"get":{"operationId":"getPlatformSettings","summary":"Read the whitelabel platform identity settings.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active platform identity settings with audit metadata."},"403":{"description":"Credential lacks platform_settings:read or is not the platform credential."}}},"put":{"operationId":"updatePlatformSettings","summary":"Update the whitelabel platform identity settings.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["changeReason"],"additionalProperties":false,"properties":{"brandName":{"type":"string","minLength":1,"maxLength":80},"legalName":{"type":"string","minLength":1,"maxLength":160},"registrationNo":{"type":"string","minLength":1,"maxLength":160},"taxId":{"type":["string","null"],"minLength":1,"maxLength":80},"vatId":{"type":["string","null"],"minLength":1,"maxLength":80},"registeredAddress":{"type":"string","minLength":1,"maxLength":500},"managingDirector":{"type":["string","null"],"minLength":1,"maxLength":160},"contactEmail":{"type":"string","format":"email","maxLength":254},"supportEmail":{"type":"string","format":"email","maxLength":254},"contactPhone":{"type":["string","null"],"minLength":5,"maxLength":32},"merchantTotpRequired":{"type":"boolean"},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"New active platform identity settings with audit metadata."},"400":{"description":"Validation failed or no identity field was provided."},"403":{"description":"Credential lacks platform_settings:write or is not the platform credential."},"409":{"description":"Replayed signed nonce."}}}},"/admin/platform-settings/logo":{"put":{"operationId":"updatePlatformLogo","summary":"Upload or replace the platform brand logo.","description":"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).","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contentType","imageBase64","changeReason"],"additionalProperties":false,"properties":{"contentType":{"type":"string","enum":["image/png","image/jpeg","image/webp"]},"imageBase64":{"type":"string","minLength":4,"maxLength":1400000},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"Stored platform logo metadata with its versioned public URL."},"400":{"description":"Logo too large, not valid base64, or magic bytes mismatch."},"403":{"description":"Credential lacks platform_settings:write or is not the platform credential."},"409":{"description":"Replayed signed nonce."}}}},"/admin/fee-policy":{"get":{"operationId":"getPlatformFeePolicy","summary":"Read the active platform fee policy.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active platform fee policy with version and audit metadata."},"403":{"description":"Credential lacks fee_policy:read or is not the platform credential."}}},"put":{"operationId":"updatePlatformFeePolicy","summary":"Immediately update platform fee rates.","description":"Signed, nonce-protected, platform-credential-only endpoint. V1 applies changes immediately, records a new append-only version, and requires an audit change reason.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["paymentLinkBps","onrampBps","offrampBps","changeReason"],"additionalProperties":false,"properties":{"paymentLinkBps":{"type":"integer","minimum":0,"maximum":5000},"onrampBps":{"type":"integer","minimum":0,"maximum":5000},"offrampBps":{"type":"integer","minimum":0,"maximum":5000},"swapBps":{"type":"integer","minimum":0,"maximum":0,"description":"Always 0. Swap has no MonaxPay platform fee; retained for backwards compatibility."},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"New active platform fee policy."},"403":{"description":"Credential lacks fee_policy:write or is not the platform credential."},"409":{"description":"Replayed signed nonce."}}}},"/fee-policy/public":{"get":{"operationId":"getPublicFeePolicy","summary":"Public, non-secret consumer rail rates (buy/sell/swap).","description":"Unauthenticated. Powers client-side 'you receive' estimates. Payment-link rates are merchant-paid and never exposed here. Responses are cacheable for 60 seconds.","security":[],"responses":{"200":{"description":"Current onrampBps, offrampBps, and swapBps=0."}}}},"/accounts/{accountId}/effective-fee":{"get":{"operationId":"getEffectiveAccountFee","summary":"The effective payment-link fee rate the merchant will pay.","description":"Resolution order: per-merchant admin override → platform fee policy → environment default. Own account only, unless the caller is the platform credential.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string","minLength":6,"maxLength":80}}],"responses":{"200":{"description":"Effective feeBps with its source (merchant_override, platform_policy, default), settlement mode, and whether prepaid fee credit is required."},"403":{"description":"Credential lacks transaction_intents:read or cannot read fees for the requested account."}}}},"/admin/compliance-policy":{"get":{"operationId":"getCompliancePolicy","summary":"Read the active admin-configured compliance policy.","description":"Platform-credential only. Version 0 mirrors the code default until an admin override exists.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Active compliance policy with version and audit metadata."},"403":{"description":"Credential lacks compliance_policy:read or is not the platform credential."}}},"put":{"operationId":"updateCompliancePolicy","summary":"Immediately update compliance route-gating policy.","description":"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.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["blockedCategories","highRiskRails","automatedSolanaAssets","walletRiskThreshold","changeReason"],"additionalProperties":false,"properties":{"blockedCategories":{"type":"array","maxItems":200,"items":{"type":"string","minLength":1,"maxLength":120}},"highRiskRails":{"type":"array","maxItems":20,"items":{"type":"string","enum":["buy","sell","swap","send","request","merchant_payment","fee_collection","refund_manual"]}},"automatedSolanaAssets":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string","enum":["USDC","USDT","SOL"]}},"walletRiskThreshold":{"type":"integer","minimum":0,"maximum":100},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"New active compliance policy."},"403":{"description":"Credential lacks compliance_policy:write or is not the platform credential."},"409":{"description":"Replayed signed nonce."}}}},"/admin/accounts/{accountId}/restrictions":{"get":{"operationId":"getMerchantRestrictions","summary":"Read merchant-specific controls and freeze state.","description":"Platform-credential only. Returns asset, country, activity, fee override, API, link, account, and settlement controls for one merchant.","parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string","minLength":6,"maxLength":80}}],"responses":{"200":{"description":"Merchant restrictions, or null if none exist."},"403":{"description":"Credential lacks merchant_restrictions:read or is not the platform credential."}}},"put":{"operationId":"updateMerchantRestrictions","summary":"Update merchant restrictions, fee override, and freeze controls.","description":"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":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-timestamp","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-nonce","in":"header","required":true,"schema":{"type":"string"}},{"name":"x-api-signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"accountId","in":"path","required":true,"schema":{"type":"string","minLength":6,"maxLength":80}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"blockedAssets":{"type":"array","items":{"type":"string","enum":["USDC","USDT","SOL"]}},"blockedPayerCountries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2}},"blockedPurposeTerms":{"type":"array","items":{"type":"string"}},"accountFrozen":{"type":"boolean","default":false},"newLinksFrozen":{"type":"boolean","default":false},"activeLinksFrozen":{"type":"boolean","default":false},"settlementFrozen":{"type":"boolean","default":false},"apiAccessFrozen":{"type":"boolean","default":false},"feeBps":{"type":["integer","null"],"minimum":0,"maximum":5000},"notes":{"type":"string","maxLength":1000},"changeReason":{"type":"string","minLength":6,"maxLength":500}}}}}},"responses":{"200":{"description":"Updated merchant restrictions."},"403":{"description":"Credential lacks merchant_restrictions:write or is not the platform credential."},"404":{"description":"Merchant account was not found."},"409":{"description":"Replayed signed nonce."}}}},"/provider-settings/public":{"get":{"operationId":"getPublicProviderSettings","summary":"Read the active provider environment and route-safe public summary.","description":"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":{"200":{"description":"Active environment, routing strategy, and enabled provider summaries."}}}},"/platform-identity":{"get":{"operationId":"getPlatformIdentity","summary":"Read the public whitelabel platform identity without authentication.","description":"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":{"200":{"description":"Public platform identity facts and logo URL."}}}},"/platform-identity/logo":{"get":{"operationId":"getPlatformLogo","summary":"Serve the platform brand logo bytes without authentication.","description":"Immutable-cacheable logo serving with ETag support; clients reference it through versioned ?v=<sha256> URLs from /platform-identity.","parameters":[{"name":"v","in":"query","required":false,"schema":{"type":"string","minLength":64,"maxLength":64}}],"responses":{"200":{"description":"Logo bytes with content-type and ETag."},"304":{"description":"Not modified (If-None-Match matched the stored sha256 ETag)."},"404":{"description":"No platform logo is stored."}}}},"/provider-cashout/onramper":{"get":{"operationId":"handleOnramperProviderCashout","summary":"Bind an Onramper sell cashout provider wallet to a managed settlement.","description":"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":[{"name":"partnerContext","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":500}},{"name":"providerWalletAddress","in":"query","required":true,"schema":{"type":"string","minLength":24,"maxLength":128}},{"name":"transactionId","in":"query","required":true,"schema":{"type":"string","minLength":3,"maxLength":160}},{"name":"inAmount","in":"query","required":false,"schema":{"type":"number","minimum":0}}],"responses":{"303":{"description":"Cashout target bound; user redirected to checkout status."},"401":{"description":"partnerContext signature is invalid."},"404":{"description":"Transaction intent was not found."},"409":{"description":"Cashout target cannot be bound safely."},"422":{"description":"Provider wallet is not a valid Solana address."}}}},"/webhooks/onramper":{"post":{"operationId":"ingestOnramperWebhook","summary":"Verify, deduplicate, and apply a signed Onramper webhook event to transaction state.","parameters":[{"name":"X-Onramper-Webhook-Signature","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook accepted idempotently."},"401":{"description":"Webhook signature is invalid."}}}},"/webhooks/sumsub":{"post":{"operationId":"ingestSumsubWebhook","summary":"Verify and store a Sumsub applicant verification webhook event.","parameters":[{"name":"X-Payload-Digest","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Payload-Digest-Alg","in":"header","required":true,"schema":{"type":"string","enum":["HMAC_SHA256_HEX","HMAC_SHA512_HEX"]}}],"responses":{"200":{"description":"Webhook accepted idempotently."},"401":{"description":"Webhook signature or digest algorithm is invalid."}}}},"/webhooks/helius":{"post":{"operationId":"ingestHeliusWebhook","summary":"Verify, deduplicate, and apply Helius Solana settlement webhooks to transaction state.","parameters":[{"name":"Authorization","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook batch accepted idempotently."},"401":{"description":"Webhook authorization header is invalid."},"503":{"description":"Webhook authorization token is not configured."}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"},"HmacSignature":{"type":"apiKey","in":"header","name":"x-api-signature"}}}}