API reference
The server API supports accounts, invoices, secure checkout, statuses and webhooks. OpenAPI describes routes, fields and errors. Starting a payment requires a configured gateway, an approved merchant and supported invoice terms.
On this page
Base URL and format#
The base URL is https://kevmi.one. Request and response bodies use JSON. Money values are integer minor units. Account and support dates are Unix timestamps in milliseconds.
API responses use Cache-Control: no-store. The public /openapi.json can be cached for five minutes. Do not place cookies or secrets in a URL.
curl 'https://kevmi.one/api/config'
curl 'https://kevmi.one/openapi.json'Request authorization#
The web account uses an HttpOnly session cookie. GET /api/auth/me returns the current user and csrfToken. Mutations require X-CSRF-Token and a same-origin request.
Scoped Kevmi merchant keys authorize /api/v1/payments, /api/v1/payment-links and /api/v1/events. They do not replace the session cookie for account settings or administrative routes.
const me = await fetch('/api/auth/me').then(r => r.json());
if (!me.authenticated) throw new Error('Sign in required');
const response = await fetch('/api/account/settings', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': me.csrfToken },
body: JSON.stringify({ vatPayer: 'merchant' })
});
if (!response.ok) throw new Error('Settings were not saved');
const updated = await response.json();Endpoint groups#
GET /api/config reports the presence of server configuration. GET /api/checkout/{token} returns invoice.availability for the selected method, including merchant approval and saved terms. These checks do not establish provider connectivity or payment success: the result comes from the verified gateway operation.
| Group | Purpose |
|---|---|
| Config and health | Public service and storage readiness |
| Authentication | Telegram challenges and sessions |
| Account | Settings and the private merchant app |
| /api/v1/payments | Scoped server invoice creation and reads; does not initiate a charge |
| /api/v1/events | Server event log with events:read |
| Integrations | Session-authenticated key and webhook endpoint administration |
| Applications and moderation | Owned submissions, status tracking and separate moderator permissions |
| Checkout | Public invoice, encrypted card request, concrete operation, bank code, status and reconciliation |
| Gateway ingress | Signed v3 notifications and authenticated operation verification |
| Support and notifications | Questions, private requests, events and read state |
| Telegram | Verified bot webhook |
| Unsupported money routes | Legacy direct /api/payments and /api/payouts do not create a charge or payout |
A public knowledge request#
The answer includes mode, answer, sources, knowledgeVersion and needsHuman. A supplied Origin must match the application origin. A server-side documentation agent can omit Origin.
curl 'https://kevmi.one/api/support/ask' \
-H 'Content-Type: application/json' \
--data '{"question":"Who pays VAT?","locale":"en"}'Errors and limits#
An error includes a machine-readable code and a message. Unknown request fields are rejected. Standard JSON bodies allow 16,384 bytes; /api/support/ask and the Telegram webhook allow 65,536.
429 indicates a rate limit. 503 can indicate an unavailable integration, not a declined payment. Read error.code and do not change a financial status from an HTTP status alone.
API endpoints #
Open an endpoint to see its fields, authorization and responses. These schemas use the same OpenAPI document available at the public URL.
Service
Public service status.
GET/api/config
Current integration readiness
Responses
200Configuration without secrets.
telegramobjectrequiredsupportobjectrequiredgatewayobjectrequiredcapabilitiesobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/health
API and D1 table status
not_configured can have status=ok: public pages and search can run without DB. A configured DB with unavailable tables returns 503/degraded. This response does not test Telegram or model network connectivity.
Responses
200Storage is ready or not_configured.
telegramobjectrequiredsupportobjectrequiredgatewayobjectrequiredcapabilitiesobjectrequiredstatusok | degradedrequiredstorageready | not_configured | unavailablerequired503D1 is unavailable or an unexpected service error occurred.
Variant 1
telegramobjectrequiredsupportobjectrequiredgatewayobjectrequiredcapabilitiesobjectrequiredstatusok | degradedrequiredstorageready | not_configured | unavailablerequiredVariant 2
errorobjectrequiredGET/openapi.json
Public machine-readable contract
Read only. Contains no secrets, sessions, user records or operational payment-provider contract.
Responses
200This OpenAPI 3.1 document.
object
POST/api/jobs/dispatch
Run due delivery and application jobs
Server scheduler entrypoint. Requires JOBS_SECRET, not a browser session or merchant key. Does not accept job IDs or arbitrary outbound URLs.
Responses
200Completed without a background context.
object
202Accepted in a background execution context.
acceptedtruerequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredAuth
Registration and sign-in share the verified Telegram flow.
GET/api/auth/me
Current session and CSRF
Responses
200authenticated=false when no valid session exists.
Variant 1
authenticatedfalserequiredVariant 2
authenticatedtruerequireduserobjectrequiredcsrfTokenstringrequiredexpiresAtintegerrequiredUnix timestamp in milliseconds, UTC.
503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/auth/telegram/start
Start sign-in or registration
Creates a 300-second challenge and an HttpOnly browser-proof cookie; at most six starts per minute per hashed address. Compare the six-digit code on the website and in the private bot chat.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
Responses
201Sign-in request created; the proof cookie binds it to the original browser.
challengeIdstringrequiredcodestringrequiredexpiresAtintegerrequiredUnix timestamp in milliseconds, UTC.
telegramUrlstringrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/auth/telegram/complete
Complete a verified sign-in
Requires the proof cookie from start and the same browser. Pending returns 202. After bot confirmation, the request issues one 24-hour session. Up to 90 checks per minute per challenge. A client-supplied Telegram ID is not accepted.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
challengeIdstringrequiredResponses
200Account created or updated and session issued.
status"authenticated"requireduserobjectrequiredcsrfTokenstringrequiredexpiresAtintegerrequiredUnix timestamp in milliseconds, UTC.
202Awaiting confirmation in Telegram.
status"pending"required400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired410The five-minute sign-in request expired.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/auth/logout
End the current session
No body is required or read. The bot's /logout command separately ends all account sessions.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
Responses
200Session removed and cookie cleared.
loggedOuttruerequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredAccount
Settings for the current user only.
GET/api/account/settings
Current user settings
Responses
200Public fields of the current user's profile.
userobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/account/settings
Change the store name, VAT payer or notifications
All fields are optional: partial patch. Saving vatPayer does not create a financial operation. The payments and payouts switches control preferences, not gateway availability.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
storeNamestringSurrounding spaces are trimmed. Length after trim: 1–80 characters. Control characters except tabs and line breaks are forbidden.
vatPayercustomer | merchantnotificationsobjectResponses
200Updated profile.
userobjectrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPayment links
Server invoices for the current store. The price, currency, VAT payer, seller name and calculation are immutable.
GET/api/payment-links
List owned payment links
Sorted by createdAt DESC, id DESC. Public links work across devices; listing requires an account.
Headers and parameters
limitquerycursorquerynextCursor from the previous response. The service uses base64 JSON [createdAt,id]; pass it unchanged through URLSearchParams.
Responses
200A page of owned payment links.
linksarray<object>requirednextCursorstring | nullrequiredOpaque next-page cursor. Pass as a URL-encoded query parameter; null marks the end.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/payment-links
Create an invoice with immutable terms
Create an immutable invoice and immediately receive checkoutUrl; this does not charge the buyer. USD: card/Alipay; RUB: SBP; USDT: crypto. USD crypto remains accepted for compatibility but cannot be paid without a USDT invoice. Fee and VAT customer shares are independent integers from 0 to 100; current live card/Alipay supports VAT customer=100 and fee customer=0. The customer total is never silently changed. Latest website application must be approved before a new live charge. Invoice creation and its merchant event commit atomically.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
Idempotency-KeyheaderrequiredOne key per logical request. A repeat with identical canonical input returns the original record; different input with the same key returns 409.
JSON body
Currency USD
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USD"requiredmethodsarray<card | alipay | crypto>requiredNew USD checkout supports card and Alipay. USD crypto invoices are accepted only for compatibility and return crypto_requires_usdt at live checkout; use USDT for crypto.
vatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency RUB
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"RUB"requiredmethodsarray<"sbp">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency USDT
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USDT"requiredmethodsarray<"crypto">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Responses
200Idempotent replay; replayed=true.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
201Invoice created; replayed=false.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/payment-links/{id}
Owned link and saved calculation
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
Responses
200Another user's ID and a missing ID both return 404.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/payment-links/{id}
Pause, resume or cancel a link
Changes only status. The update and immutable invoice.updated event commit atomically. Concurrent changes use a version check; refresh and retry on LINK_CHANGED. cancelled is terminal, expiration is never extended, and price, methods, cost shares and description stay frozen. Repeating the saved status returns the current invoice.
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
statusactive | paused | cancelledrequiredResponses
200Current state of the owned link.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredCheckout
Read one invoice without an account. Payment availability is checked separately.
GET/api/checkout/{token}
Public invoice details for the customer
Read the immutable public invoice quote and its persisted payment snapshot. method must belong to the invoice. No account is required. Does not expose owner identity, private metadata or merchant proceeds. The token grants access only to this checkout. availability reflects configuration, allocation, technical limits and merchant approval; payment confirmation is separate.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
methodqueryMust be present in the invoice's saved methods.
Responses
200Public invoice and the existing payment, if dispatched.
invoiceobjectrequiredpaymentoneOfrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/checkout/{token}/pay
Start or recover the invoice payment
Same-origin buyer operation; no account or CSRF token required. The server reserves one operation and a stable idempotency key before gateway dispatch. A repeat recovers the same operation; a lost response must be resolved through status. The payment method locks after dispatch. Card data must be browser-encrypted with a fresh payment intent. SBP/crypto send the saved customer total; card/Alipay use the supported immutable tax configuration. New charges require an approved merchant application. Existing dispatched payments can be recovered after invoice expiration, pause or approval changes. No /v2 or hosted-card route is used.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
Variant 1
method"card"requiredsealedobjectrequiredVariant 2
method"alipay"requirednamestringrequiredcountry"CN"requiredemailstringVariant 3
method"sbp"requiredVariant 4
method"crypto"requiredpayerCurrencystringrequirednetworkstringrequiredResponses
200Existing operation recovered; no second payment.
paymentoneOfrequiredreplayedboolean202Operation dispatched; completion is asynchronous.
paymentoneOfrequiredreplayedboolean400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired410The gateway encryption intent or bank challenge expired. Obtain a fresh intent for the same operation; do not create a replacement payment.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/checkout/{token}/status
Read and refresh the same payment
No account is required. Refreshes an existing operation over authenticated gateway transport, with server-side throttling. No new payment is created. Returns null if nothing was dispatched. Confirm an order only when fulfillmentReady is true.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
Responses
200Current sanitized payment state.
paymentoneOfrequiredreplayedboolean400Invalid JSON, unknown field or invalid value.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/checkout/{token}/reconcile
Request an authoritative status reconciliation
Reads the existing operation and asks the gateway to reconcile its provider status. Does not create a payment. At most 3 requests per invoice per minute. Available for already-dispatched payments even if the invoice is no longer active.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
Responses
200Reconciled payment or null.
paymentoneOfrequiredreplayedboolean400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired410The gateway encryption intent or bank challenge expired. Obtain a fresh intent for the same operation; do not create a replacement payment.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/checkout/{token}/card-intent
Obtain a gateway public key and a bound encryption intent
The gateway alone owns the private key. An intent expires within five minutes and binds the merchant order, currency, base/total amounts, operation idempotency key and purpose. payment intents require an active invoice and approved merchant; code intents require an existing, current bank challenge. No PAN, CVV, bank code, or private JWK fields are accepted by this endpoint. At most 8 intents per invoice and 12 per client per minute. The encrypted plaintext is {intent,name,country,email?,card:{number,expiration,cvv,holder}} for payment or {intent,code} for code. Plaintext is assembled only inside the browser before JWE encryption.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
purposepayment | codeResponses
200Short-lived intent and public RSA key only.
intentstringrequiredintentIdstringrequiredexpiresAtintegerrequiredUnix timestamp in milliseconds, UTC.
keyobjectrequiredalgorithm"RSA-OAEP-256"requiredencryption"A256GCM"requiredprotocol"kevmi-card-v1"required400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired410The gateway encryption intent or bank challenge expired. Obtain a fresh intent for the same operation; do not create a replacement payment.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/checkout/{token}/code
Relay an encrypted code for the current bank challenge
Obtain a purpose=code intent and encrypt {intent,code} in the browser. The gateway validates the current challenge and consumes the sealed intent once. Kevmi never receives plaintext code. At most 5 submissions per invoice per minute; refresh status after an uncertain response.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
sealedobjectrequiredResponses
202Code sent; current payment state.
paymentoneOfrequiredreplayedboolean400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired410The gateway encryption intent or bank challenge expired. Obtain a fresh intent for the same operation; do not create a replacement payment.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/checkout/{token}/crypto-services
Read the current coin and network catalog
Only for a USDT invoice that allows crypto. The invoice remains denominated in USDT; the gateway quotes the chosen payer coin. Never assume USD equals USDT or convert the transfer amount to a floating-point number. At most 10 catalog reads per invoice per minute.
Headers and parameters
tokenpathrequiredRandom public identifier from the checkout URL. Grants read access to this invoice only.
Responses
200Gateway-provided catalog, with current availability and transfer limits.
servicesarray<object>requiredfetchedAtintegerrequiredUnix timestamp in milliseconds, UTC.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredSupport
Public knowledge base and the current user's support requests.
POST/api/support/ask
Answer from the complete public knowledge base
Public question without a session or CSRF. A supplied Origin must match APP_ORIGIN; agents can omit it. In AI mode, the server sends all published articles, facts, page catalog and feature readiness. Optional history and pageContext are untrusted question context. The model cannot access accounts, money, private requests or tools. With D1, the limit is 12 questions per minute per hashed address. AI requires D1, valid provider configuration and quota: 60 generations per hour service-wide by default. Configuration readiness does not prove external API availability. Provider errors, quota exhaustion or invalid output return search with aiUnavailable=true and HTTP 200. Without generation configuration, regular search is returned.
Headers and parameters
OriginheaderMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
JSON body
questionstringrequiredSurrounding spaces are trimmed. Length after trim: 2–2,000 characters. Control characters except tabs and line breaks are forbidden.
localeru | en | es | de | frResponse language. If omitted, supported Accept-Language preferences are used; otherwise English. Articles for ES/DE/FR currently link to the English documentation edition.
historyarray<oneOf>Up to the latest three question-and-answer pairs. Optional. Untrusted context, not provider system-role messages.
pageContextstringShort section label after trim, 1–80 characters. Allows letters, digits, spaces and ·.,—–-:(). Line breaks, URLs, query parameters and HTML are forbidden. Do not include tokens or secrets.
Responses
200An answer or matching documentation with validated article links.
Variant 1
mode"search"requiredanswerstringrequiredsourcesarray<object>requiredknowledgeVersionstring | nullrequiredneedsHumanbooleanrequiredaiUnavailabletrueVariant 2
mode"ai"requiredanswerstringrequiredPlain text only; URLs and HTML are rejected. Links are returned only in sources.
sourcesarray<object>requiredknowledgeVersionstringrequiredneedsHumanbooleanrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/support/tickets
The latest 30 owned support requests
Responses
200Newest first by createdAt; returns the latest 30 records.
ticketsarray<object>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/support/tickets
Save a support request
Up to six requests per user per hour, shared by the website and bot. Saving creates an account record. Keep its reference to ask about status.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
subjectstringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
messagestringrequiredSurrounding spaces are trimmed. Length after trim: 5–4,000 characters. Control characters except tabs and line breaks are forbidden.
Responses
201Support request saved.
ticketobjectrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/support/tickets/{id}
Read an owned support request
Headers and parameters
idpathrequiredIdentifier of an owned support request.
Responses
200Another user's request and a missing request both return 404.
ticketobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/support/tickets/{id}
Close an owned support request
The only allowed change is status=closed. This API does not reopen requests, edit messages or submit operator replies.
Headers and parameters
idpathrequiredIdentifier of an owned support request.
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
status"closed"requiredResponses
200Support request closed.
closedtruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredNotifications
Account event center, website read state and independent Telegram delivery status.
GET/api/notifications
A page of owned notifications
Up to 30 records, sorted by createdAt DESC then id DESC. Listing does not change readAt or trigger delivery. unreadCount is the current user's total unread count across pages. Owner fields, Telegram ID and secrets are excluded.
Headers and parameters
unreadquery1 selects unread only; 0 or an omitted value selects all events.
cursorquerynextCursor from the previous response. Pass unchanged through URLSearchParams; format createdAt:id, with createdAt a safe integer in milliseconds.
Responses
200Events with independent read and delivery states.
notificationsarray<object>requiredunreadCountintegerrequirednextCursorstring | nullrequiredNext-page cursor; null if no further records remain.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/notifications/read
Mark owned notifications as read
Accepts either ids, or all:true together with before. before is the time of the last observed event and cannot exceed server time. Newer events remain unread. The request is idempotent: existing readAt values do not change. Other users' and missing IDs are neither modified nor disclosed. Telegram status and sentAt remain unchanged.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Variant 1
idsarray<string>requiredDuplicates are allowed and counted once.
Variant 2
alltruerequiredbeforeintegerrequiredcreatedAt of the last displayed event. The server also requires before <= Date.now().
Responses
200The number of newly read events, operation time and current unread count.
updatedintegerrequiredreadAtintegerrequiredUnix timestamp in milliseconds, UTC.
unreadCountintegerrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/notifications/test
Send a test notification to the account's Telegram
Queues a message and attempts delivery. At most three per user per hour. The test is not a payment notification and does not change a balance. HTTP 202 does not confirm delivery; check the notification list.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Responses
202Queueing result.
queuedbooleanrequiredidstring | null400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredTelegram
Bot webhook; not a payment webhook.
POST/api/telegram/webhook
Receive a Telegram Bot API event
Requires only the Telegram secret header, without session, CSRF or Origin. Additional Update fields are allowed. Handles message and callback_query; personal actions require the verified sender's private chat. Other updates are skipped. update_id is deduplicated; an in-progress update returns 503 for retry. This is not a payment-provider webhook.
JSON body
update_idintegerrequiredmessageobjectTelegram Message: the handler uses message_id, text, from and chat.
callback_queryobjectTelegram CallbackQuery: the handler uses id, from, data and message.chat.
Responses
200Processed, skipped or already handled.
oktruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired502Telegram request failed.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredUnsupported money routes
Unsupported legacy money routes and payout execution. The public checkout flow has its own documented endpoints.
POST/api/payments
Financial operation unavailable
Returns 503 GATEWAY_NOT_CONNECTED. Financial operations are unavailable. The body is not processed and no gateway request is made.
Responses
503Financial operations are unavailable.
errorobjectrequiredPOST/api/payouts
Financial operation unavailable
Returns 503 GATEWAY_NOT_CONNECTED. Financial operations are unavailable. The body is not processed and no gateway request is made.
Responses
503Financial operations are unavailable.
errorobjectrequiredMerchant API
Scoped server-to-server invoices and immutable event history.
GET/api/v1/payments
List owned payment links
Sorted by createdAt DESC, id DESC. Public links work across devices; listing requires an account.
Headers and parameters
limitquerycursorquerynextCursor from the previous response. The service uses base64 JSON [createdAt,id]; pass it unchanged through URLSearchParams.
Responses
200A page of owned payment links.
linksarray<object>requirednextCursorstring | nullrequiredOpaque next-page cursor. Pass as a URL-encoded query parameter; null marks the end.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/v1/payments
Create an invoice with immutable terms
Create an immutable invoice and immediately receive checkoutUrl; this does not charge the buyer. USD: card/Alipay; RUB: SBP; USDT: crypto. USD crypto remains accepted for compatibility but cannot be paid without a USDT invoice. Fee and VAT customer shares are independent integers from 0 to 100; current live card/Alipay supports VAT customer=100 and fee customer=0. The customer total is never silently changed. Latest website application must be approved before a new live charge. Invoice creation and its merchant event commit atomically.
Headers and parameters
Idempotency-KeyheaderrequiredOne key per logical request. A repeat with identical canonical input returns the original record; different input with the same key returns 409.
JSON body
Currency USD
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USD"requiredmethodsarray<card | alipay | crypto>requiredNew USD checkout supports card and Alipay. USD crypto invoices are accepted only for compatibility and return crypto_requires_usdt at live checkout; use USDT for crypto.
vatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency RUB
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"RUB"requiredmethodsarray<"sbp">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency USDT
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USDT"requiredmethodsarray<"crypto">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Responses
200Idempotent replay; replayed=true.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
201Invoice created; replayed=false.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/v1/payments/{id}
Owned link and saved calculation
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
Responses
200Another user's ID and a missing ID both return 404.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/v1/payments/{id}
Pause, resume or cancel a link
Changes only status. The update and immutable invoice.updated event commit atomically. Concurrent changes use a version check; refresh and retry on LINK_CHANGED. cancelled is terminal, expiration is never extended, and price, methods, cost shares and description stay frozen. Repeating the saved status returns the current invoice.
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
JSON body
statusactive | paused | cancelledrequiredResponses
200Current state of the owned link.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/v1/payment-links
List owned payment links
Sorted by createdAt DESC, id DESC. Public links work across devices; listing requires an account.
Headers and parameters
limitquerycursorquerynextCursor from the previous response. The service uses base64 JSON [createdAt,id]; pass it unchanged through URLSearchParams.
Responses
200A page of owned payment links.
linksarray<object>requirednextCursorstring | nullrequiredOpaque next-page cursor. Pass as a URL-encoded query parameter; null marks the end.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/v1/payment-links
Create an invoice with immutable terms
Create an immutable invoice and immediately receive checkoutUrl; this does not charge the buyer. USD: card/Alipay; RUB: SBP; USDT: crypto. USD crypto remains accepted for compatibility but cannot be paid without a USDT invoice. Fee and VAT customer shares are independent integers from 0 to 100; current live card/Alipay supports VAT customer=100 and fee customer=0. The customer total is never silently changed. Latest website application must be approved before a new live charge. Invoice creation and its merchant event commit atomically.
Headers and parameters
Idempotency-KeyheaderrequiredOne key per logical request. A repeat with identical canonical input returns the original record; different input with the same key returns 409.
JSON body
Currency USD
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USD"requiredmethodsarray<card | alipay | crypto>requiredNew USD checkout supports card and Alipay. USD crypto invoices are accepted only for compatibility and return crypto_requires_usdt at live checkout; use USDT for crypto.
vatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency RUB
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"RUB"requiredmethodsarray<"sbp">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Currency USDT
titlestringrequiredSurrounding spaces are trimmed. Length after trim: 1–120 characters. Control characters except tabs and line breaks are forbidden.
descriptionstringOptional; an empty string is allowed. Up to 500 characters after trim.
amountMinorintegerrequiredTechnical integer boundary, not a commercial provider limit. A negative merchant credit is rejected.
vatPayercustomer | merchantWhen omitted, the current store's rule is saved.
expiresAtintegerA future time, at most 90 days after creation. Defaults to seven days. Saved in the invoice snapshot.
currency"USDT"requiredmethodsarray<"crypto">requiredvatCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything. Default: the store’s legacy VAT preference.
feeCustomerPercentintegerCustomer share, as a whole percentage. 0 means the merchant covers everything; 100 means the customer covers everything.
orderIdstringBuyer-visible order reference.
metadataobjectPrivate merchant metadata. At most 3000 UTF-8 bytes after JSON serialization. Never exposed in public checkout.
Responses
200Idempotent replay; replayed=true.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
201Invoice created; replayed=false.
linkobjectrequiredreplayedbooleanrequiredcheckoutUrlstringrequiredThe payment link is available immediately; no polling is required.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/v1/payment-links/{id}
Owned link and saved calculation
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
Responses
200Another user's ID and a missing ID both return 404.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/v1/payment-links/{id}
Pause, resume or cancel a link
Changes only status. The update and immutable invoice.updated event commit atomically. Concurrent changes use a version check; refresh and retry on LINK_CHANGED. cancelled is terminal, expiration is never extended, and price, methods, cost shares and description stay frozen. Repeating the saved status returns the current invoice.
Headers and parameters
idpathrequiredOwned link identifier, not the public token.
JSON body
statusactive | paused | cancelledrequiredResponses
200Current state of the owned link.
linkobjectrequiredcheckoutUrlstringIncluded in status-update responses; the nested link always contains its checkoutUrl.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/api-keys
List own key metadata
Responses
200Secrets and secret hashes are omitted.
keysarray<object>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/api-keys
Create a scoped key; reveal its secret once
Maximum 10 active keys. At most 5 creations/hour/user. Keys expire, can be revoked and are rate-limited to 90 API requests/minute/key.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
namestringrequiredscopesarray<invoices:read | invoices:write | events:read>expiresInDaysintegerResponses
201Store the secret securely on your server.
keyobjectrequiredsecretstringrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredDELETE/api/api-keys/{id}
Revoke own key
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
Responses
200Future uses of the key are rejected.
revokedtruerequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/events
Read own immutable event history
Headers and parameters
beforequeryLegacy exclusive timestamp boundary. Cannot be combined with cursor. Use nextCursor for lossless pagination.
cursorqueryOpaque nextCursor returned by the previous page. Encodes [createdAt,id] and preserves events sharing one timestamp.
Responses
200Newest first; up to 50 events. Follow nextCursor until null.
eventsarray<object>requirednextCursorstring | nullrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/v1/events
Read own immutable event history
Headers and parameters
beforequeryLegacy exclusive timestamp boundary. Cannot be combined with cursor. Use nextCursor for lossless pagination.
cursorqueryOpaque nextCursor returned by the previous page. Encodes [createdAt,id] and preserves events sharing one timestamp.
Responses
200Newest first; up to 50 events. Follow nextCursor until null.
eventsarray<object>requirednextCursorstring | nullrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredWebhooks
Verified HTTPS endpoints, signed events, delivery attempts and retries.
GET/api/webhooks
List endpoints and last 30 deliveries
Responses
200No signing secrets are returned.
endpointsarray<object>requireddeliveriesarray<object>requiredavailablebooleanrequiredeventTypesarray<invoice.created | invoice.updated | payment.succeeded | payment.failed | payment.refunded | payment.partially_refunded | payment.disputed | payment.review_required>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/webhooks
Register a public HTTPS destination
Up to 5 endpoints and 6 creations/hour/user. Public HTTPS domains only; no credentials, IP literals or custom ports. A newly created endpoint receives no live deliveries until its challenge succeeds.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
urlstringrequireddescriptionstringeventsarray<invoice.created | invoice.updated | payment.succeeded | payment.failed | payment.refunded | payment.partially_refunded | payment.disputed | payment.review_required>Responses
201Save the one-time signing secret.
endpointobjectrequiredsecretstringrequiredShown only on create/rotate. Stored encrypted server-side.
400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/webhooks/{id}
List endpoints and last 30 deliveries
Headers and parameters
idpathrequiredResponses
200No signing secrets are returned.
endpointsarray<object>requireddeliveriesarray<object>requiredavailablebooleanrequiredeventTypesarray<invoice.created | invoice.updated | payment.succeeded | payment.failed | payment.refunded | payment.partially_refunded | payment.disputed | payment.review_required>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPATCH/api/webhooks/{id}
Pause or resume a verified endpoint
Paused verified endpoints keep eligible events in the queue; resuming processes due deliveries.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
statusactive | pausedrequiredResponses
200Status saved.
updatedtruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredDELETE/api/webhooks/{id}
Remove endpoint and cancel undelivered jobs
Cancels pending, failed and leased jobs. A request already sent across the network cannot be recalled.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
Responses
200Endpoint removed.
deletedtruerequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/webhooks/{id}/verify
Send a signed endpoint.verification challenge
Maximum 5 verification attempts/hour/user. Your server must validate Kevmi-Signature and return 2xx JSON {"challenge":"<data.challenge>"}. Request timeout: 8 seconds; response cap: 8192 bytes. Redirects are not followed. Verification activates the endpoint.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Responses
200Verified and active.
verifiedtruerequiredendpointobjectrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired422Destination could not be verified.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/webhooks/{id}/rotate
Replace signing secret and require verification again
Maximum 3 rotations/hour/user. Update your server and verify the endpoint again. An already in-flight request may still carry the previous signature.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Responses
200New secret shown once.
secretstringrequiredShown only on create/rotate. Stored encrypted server-side.
requiresVerificationtruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/webhooks/{id}/deliveries/{deliveryId}/retry
Retry a failed delivery to an active endpoint
Retains event ID and payload; generates a fresh timestamp and signature. Each automatic delivery cycle makes at most 6 attempts, including expired leases, with delays of 1m, 5m, 30m, 2h and 12h. Delivery is at least once; deduplicate event IDs on your server.
Headers and parameters
idpathrequireddeliveryIdpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Responses
202Retry scheduled.
queuedtruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredApplications
Authenticated website applications and individual tracking.
GET/api/applications
List up to 30 own applications
Headers and parameters
X-Kevmi-LocaleheaderTracking URL and system-message language. Without a supported value, same-origin referrer and browser language are considered; fallback is English.
Responses
200Newest first.
applicationsarray<object>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/applications
Submit website information and receive a tracking URL
Requires confirmed Telegram sign-in. Up to 5 new submissions/day/user. Idempotent replay returns 200. The server advances real persisted stages; unavailable or risky automatic results require human review. Approval does not configure the payment gateway. Ownership and state cannot be supplied by the applicant.
Headers and parameters
OriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
Idempotency-KeyheaderrequiredOne key per logical request. A repeat with identical canonical input returns the original record; different input with the same key returns 409.
X-Kevmi-LocaleheaderTracking URL and system-message language. Without a supported value, same-origin referrer and browser language are considered; fallback is English.
JSON body
websiteUrlstringrequiredPublic HTTPS domain without credentials, query parameters, IP literals or custom ports. A fragment is removed during normalization.
businessNamestringrequiredbusinessTypedigital_goods | software | services | physical_goods | education | otherrequireddescriptionstringrequiredcontactTelegramstringrequiredA 5–32 character Telegram username beginning with a letter, then letters/digits/underscores. Optional @ or https://t.me/ prefix; surrounding whitespace is trimmed. Stored as @username.
consenttruerequiredResponses
200Existing submission.
applicationobjectrequiredurlstringrequiredreplayedbooleanrequired202Accepted; processing continues on the server.
applicationobjectrequiredurlstringrequiredreplayedbooleanrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/applications/{id}
Read own review stages and event history
Headers and parameters
idpathrequiredX-Kevmi-LocaleheaderTracking URL and system-message language. Without a supported value, same-origin referrer and browser language are considered; fallback is English.
Responses
200Private applicant projection. Evidence and model output are not exposed.
applicationobjectrequiredeventsarray<object>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/applications/{id}/resume
Resume an eligible background stage
Cannot skip review or approve a stage. A server lease prevents duplicate work. Needs-review and final applications remain unchanged. At most 30 processing-resume requests/minute/user.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
X-Kevmi-LocaleheaderTracking URL and system-message language. Without a supported value, same-origin referrer and browser language are considered; fallback is English.
JSON body
Responses
200No processing needed.
applicationobjectrequired202Processing scheduled.
applicationobjectrequiredscheduledtruerequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredModeration
Allowlisted Telegram moderators; every decision is version-checked.
GET/api/moderation/applications
List up to 100 applications for moderation
Requires the authenticated Telegram identity to be in MODERATOR_TELEGRAM_IDS. Includes all states, ordered needs_review first, processing second, then final states; newest updates first within a group.
Responses
200Moderator queue.
applicationsarray<object>required401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGET/api/moderation/applications/{id}
Read review evidence and stage history
Headers and parameters
idpathrequiredResponses
200Private moderator evidence.
applicationobjectrequiredeventsarray<object>requiredevidenceobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredPOST/api/moderation/applications/{id}/decision
Approve the current review stage or decline with a public reason
Requires a configured moderator; at most 30 decisions/minute/user. expectedVersion is compared atomically. Only the current needs_review stage can be approved; final applications cannot be silently reopened. A rejection requires an editable public reason. The decision, stage history and enabled applicant notification are saved together.
Headers and parameters
idpathrequiredOriginheaderrequiredMust exactly match APP_ORIGIN. Sec-Fetch-Site: cross-site is rejected. The server does not provide CORS access.
X-CSRF-TokenheaderrequiredCurrent session token from GET /api/auth/me or successful sign-in completion.
JSON body
Variant 1
expectedVersionintegerrequiredaction"approve_step"requiredreasonstringVariant 2
expectedVersionintegerrequiredaction"reject"requiredreasonstringrequiredResponses
200Decision saved.
applicationobjectrequired400Invalid JSON, unknown field or invalid value.
errorobjectrequired401No valid session; for a webhook, an invalid secret.
errorobjectrequired403Origin, CSRF or browser-binding validation failed.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409The sign-in request is used or cancelled, identity is not confirmed, or a support request conflicts.
errorobjectrequired429Rate limit exceeded.
errorobjectrequired503An integration or storage is unavailable, an event is being processed, or the service is unavailable.
errorobjectrequiredGateway events
Source-native gateway events are verified, then the authoritative payment is read over authenticated server transport. Merchant-facing webhooks use a separate signature and delivery queue.
POST/api/gateway/webhook
Receive signed source-native gateway events
Native v3: supply X-Gateway-Timestamp (Unix seconds), X-Gateway-Signature and matching X-Gateway-Event-Id. Maximum timestamp skew is 300 seconds. After signature verification, Kevmi fetches the payment through the authenticated gateway API, checks saved order, exact currency/amount, method and provider-confirmed state, then atomically stores the receipt and merchant outbox event. Webhook text and browser observations alone never confirm a payment. Repeated IDs are deduplicated; a changed body for an existing ID is rejected. Delayed events use fresh authoritative state. Partial refunds, full refunds, disputes and review states are supported. Unbound orders are acknowledged and ignored. Legacy normalized events using Kevmi-Signature remain supported separately; only their succeeded/failed/full-refunded transitions apply.
Headers and parameters
X-Gateway-TimestampheaderRequired for native v3 events.
X-Gateway-Event-IdheaderRequired for native v3; must match body.id.
JSON body
Variant 1
idstringrequiredapi_version"3"requiredmode"live"requiredtypestringrequireddataobjectrequiredVariant 2
eventIdstringrequiredpaymentIdstringrequiredinvoiceIdstringrequiredstatussucceeded | failed | refundedrequiredamountMinorintegerrequiredInteger amount in minor currency units.
currencyUSD | RUB | USDTrequiredInvoice units: USD cents, RUB kopecks, or hundredths of USDT. No automatic currency conversion.
methodcard | alipay | sbp | cryptorequiredoccurredAtintegerrequiredUnix timestamp in milliseconds, UTC.
Responses
200Received, deduplicated, or safely ignored.
receivedtruerequiredreplayedbooleanignoredbooleanappliedboolean400Invalid JSON, unknown field or invalid value.
errorobjectrequired401The gateway signature is missing, invalid or outside the accepted time window.
errorobjectrequired404The record is missing, the public token is invalid, or the requested record belongs to another user.
errorobjectrequired409An event ID was reused with changed content or a payment ID conflicts with the saved invoice binding.
errorobjectrequired413Body exceeds 16,384 bytes; the limit is 65,536 bytes for /api/support/ask and the Telegram webhook.
errorobjectrequired415Content-Type: application/json is required.
errorobjectrequired429The gateway is busy; retry webhook delivery with the same event ID.
errorobjectrequired502Gateway response unavailable, malformed, or not verifiable. Read the existing payment status before attempting any retry.
errorobjectrequired503The gateway configuration or signing secret is missing.
errorobjectrequired