Error codes

Every error has the same envelope. Read error.code in your code, show error.message to people, and quote error.request_id to support.

json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "param": "amount",
    "request_id": "6f1c0e8a-2d1b-4c5e-9f7a-3b2d1c0e8a6f",
    "doc_url": "https://docs.watenga.africa/developers/errors#VALIDATION_ERROR",
    "details": { "issues": [{ "path": "amount", "message": "Amount must be a decimal string" }] }
  }
}
  • request_id is also the X-Request-ID response header. The SDKs put it on their error object (requestId / request_id).
  • param names the request field a validation error is about (snake_case in API version 2026-10-29); every issue is in details.issues.
  • doc_url links to the code's row below.
Retry only what is safe to retry: 429, 5xx and network errors, with the same Idempotency-Key. The SDKs do this for you. See Idempotency and Rate limits.

Error reference

All 198 codes the API answers, generated from the API itself. HTTP statuses are the ones the code is answered with.

CodeHTTPMessage and what to do
ACCOUNT_IN_USE409Account is referenced by a pending payout
ACCOUNT_LOCKED403Account temporarily locked after too many attempts
ACCOUNT_SUSPENDED403This account is suspendedContact Watenga support.
AI_NOT_CONFIGURED409The AI assistant is not available yet on this platform
ALREADY_INVITED409This email already has a pending invitation
ANOTHER_REVISION_ACCEPTED409The customer has already accepted another revision of this quotation
API_KEY_REQUIRED400Call this with an API key
ASSIGNEE_NOT_IN_TEAM400Assign the conversation to someone on your team
BACKPRESSURE503Admission store unavailable. Try again shortly.
BALANCE_IN_FLIGHT409A payment for this invoice is still being processed. Try again once it settles.
BRAND_NOT_ENABLED400This card brand is not enabled for your account
CHANNEL_REVOKED403Watenga switched this channel off for your business. Contact support.
CHARGEBACK_HOLD403A pending chargeback is on your account. Please resolve before requesting a payout.
CHECKOUT_DESIGN_INVALID400Checkout design failed validation
CHECKOUT_NOT_PENDING409This checkout is already complete
CHECKOUT_REQUIRED400This link is taxed; use Watenga.js checkout
CHECKOUT_SESSION_IN_PROGRESS409A payment for this checkout session is under way; it cannot be expired now.A payment for this session is under way: it cannot be expired now.
CHECKOUT_SESSION_NOT_OPEN409This checkout session is … and cannot be expired.
CLAWBACK_FAILED500Could not process balance adjustment. Contact support.
CLIENT_SECRET_REQUIRED403A publishable key pays a checkout session created by your server (POST /v1/checkout/sessions with a secret key): pass its clientSecret.Create a checkout session on your server (POST /v1/checkout/sessions) and pay it with its client secret.
CODE_TAKEN409A coupon with this code already exists
COMMERCE_MANAGEMENT_INVALID_RESPONSE502Shop management returned an invalid response
COMPLIANCE_RESTRICTED403Payments are restricted pending compliance review
CONCURRENCY_LIMIT_EXCEEDED429Too many in-flight requests
CONFIRMATION_REQUIRED400Sensitive scopes require explicit confirmation
CONFLICT409A saved invoice template already uses this name
CONTACT_REQUIRED409Verify an email or phone number first
CREATE_FAILED500Could not create quotation
CURRENCY_MISMATCH400Invoice currency does not match the payment currency
CURRENCY_NOT_OFFERED400This plan is not offered in that currency
CURRENCY_NOT_SUPPORTED400Provider … does not support …
CURRENCY_REQUIRED400Payment link is missing a currency
DELIVERY_UNAVAILABLE503We could not send a code right now. Try again later.
DEPRECATED_PAGINATION400Offset pagination is deprecated for payment methods; use starting_after cursor pagination
DESCRIPTOR_LOCKED403The statement descriptor cannot be changed after the first card transaction. Contact Watenga support.
DESCRIPTOR_TAKEN409That statement descriptor is already in use
DESTINATION_INVALID400Mobile money destination is missing a configured provider
DESTINATION_NOT_VERIFIED400Destination not verified
DESTINATION_REQUIRED400A verified settlement destination is required
DESTINATION_UNVERIFIED409Only a verified settlement destination can receive funds
DISBURSEMENTS_DISABLED403Disbursements are not enabled for this merchant
DOCUMENTS_INCOMPLETE400Required KYC documents are missing
DUPLICATE409This link already has that code
DUPLICATE_EMAIL409A customer with this email already exists
DUPLICATE_REQUEST409A request with this Idempotency-Key is already in progressThe first request with this Idempotency-Key is still running: wait and retry with the same key.
ELEMENTS_UNAVAILABLE503Watenga Elements is not configured on this platform
EMAIL_NOT_VERIFIED403Verify your email before signing in. Check your inbox for the activation link.
EMAIL_TAKEN409An account with this email already exists
EMAIL_UNAVAILABLE503Verification email is temporarily unavailable. Please try again later or contact support.
EMERGENCY_FREEZE503Disbursements are temporarily suspended
ENDPOINT_RETIRED410Use Watenga.js checkout (POST /v1/checkout/create)
EXPIRED409, 410Choose a future expiry date before issuing
EXPORT_TOO_LARGE400Export has … rows (limit …). Use POST /v1/merchant/reports/export with reportType "transactions" for async export.
FEATURE_DISABLED403The '…' feature is not enabledSwitch the product on for your API app (developer console) or your account.
FEE_RULE_NOT_FOUND400No fee rule configured for this payment method
FORBIDDEN403Metrics access denied
FX_RATE_STALE422The FX rate for this currency pair is out of date. Try again once it has been updated.
GATEWAY_ERROR502Could not start checkout with the payment providerThe payment provider failed: retry later with the same Idempotency-Key.
HANDOFF_EXPIRED401Handoff token expired or invalid
HANDOFF_USED401Handoff token already used
HOST_REJECTED404That hostname is not a public product host
IDEMPOTENCY_KEY_REQUIRED400Live API financial mutations require an Idempotency-Key headerSend an Idempotency-Key header on live money-moving writes.
IDEMPOTENCY_KEY_REUSED422This Idempotency-Key was already used for a different requestUse a new Idempotency-Key for a different request; reuse a key only to retry the same request.
IDEMPOTENCY_UNAVAILABLE503Idempotency storage is temporarily unavailable. Retry shortly with the same Idempotency-Key.Retry shortly with the same Idempotency-Key.
IMPERSONATION_READ_ONLY403Write operations are blocked during impersonation
INSUFFICIENT_FUNDS400, 409Insufficient balance for this conversionYour available balance cannot cover this refund now.
INTENT_MODE_MISMATCH400This checkout session was created in … mode; pay it with a … key.Pay a checkout session with a key of the same mode as the key that created it.
INTENT_NOT_FOUND404Checkout not found
INTERNAL_ERROR500An unexpected error occurredRetry with the same Idempotency-Key; if it persists, contact support with the request_id.
INVALID_AMOUNT400Amount must be greater than zeroSend the amount as a decimal string in the currency’s minor unit (USD "10.00", UGX "1500"), greater than zero.
INVALID_API_VERSION400Unknown Watenga-Version "…". Use one of: ….Send a Watenga-Version the API knows (see the changelog), or none to use your app’s pinned version.
INVALID_AUTHORITY400That tax authority is not available for …
INVALID_CLIENT400Unknown or inactive client
INVALID_CODE400Invalid or expired verification code
INVALID_COMMAND422Invalid payment session command
INVALID_CREDENTIALS401Invalid email or password
INVALID_DEPOSIT400Deposit cannot exceed the quotation total
INVALID_DOCUMENT_TYPE400Document type not required for your market
INVALID_GATEWAY400Specify ?gateway=ecocash|innbucks|onemoney or POST /:gateway
INVALID_GRANT400Invalid or expired authorization code
INVALID_JSON400Malformed JSON payload
INVALID_KEY401Invalid or expired API keyThe key is wrong, revoked or expired: copy it again from the developer console.
INVALID_PAGE400Add at least one active service before publishing
INVALID_QUANTITY400Quantity must be positive
INVALID_REDIRECT400redirect_uri not registered
INVALID_REQUEST400Canonical path without query parameters required
INVALID_SCOPE400Invalid scope request
INVALID_SEGMENT409This segment uses rules that are no longer supported; edit it
INVALID_STATE400, 409Drafts were never issued: cancel them instead of voiding
INVALID_STATUS409Only the sandbox provider runs in sandbox, outside production
INVALID_TOKEN400, 401Invalid or expired access tokenThe dashboard session ended: sign in again.
INVALID_TOTAL400Discount cannot exceed the invoice total
INVALID_URL400Use a public https address
INVITE_EXPIRED400This invitation has expired
INVITE_INVALID400This invitation is no longer valid
INVOICE_HAS_PAYMENTS409This invoice has payments made through Watenga. Refund them before voiding it.
JWT_REQUIRED403This action requires dashboard sign-in with two-factor authentication.This action is dashboard-only (for example payouts, bank accounts, keys): do it in the dashboard with two-step verification.
KYC_REJECTED403Your application could not be approved based on automated risk checks. Contact support@watenga.africa.
KYC_REQUIRED403KYC approval is required before processing paymentsFinish business verification in the dashboard before taking payments.
LIMIT_REACHED409You can keep up to 20 addresses
LISTEN_SESSION_EXPIRED410This listen session expired; start watenga listen again
MARKET_MISMATCH400Settlement destination is not valid for this merchant market
MARKET_NOT_LIVE403Payments are not yet available in your market. Complete onboarding to be ready when we launch.
MARKET_REQUIRED400Merchant market is not configuredSet the business’s market in the dashboard.
MCC_NOT_AVAILABLE400This business type is not offered in your market
MCC_PROHIBITED403This merchant category is not supported.
MERCHANT_NOT_FOUND404Unknown merchant
META_NOT_CONFIGURED503WhatsApp is not available yet on this platform
METER_EXISTS409A meter with this event name already exists
MISCONFIGURED503CAPACITY_HARNESS_MOBILE_HMAC_SECRET is not set
MISSING_AUTH401Authorization header is requiredSend Authorization: Bearer <your secret key>.
NO_CHANGES409This campaign has no unpublished changes
NO_FX_RATE422No FX rate is configured for this currency pair
NO_MERCHANT403No business is linked to this account. Register at /register or use the admin console for team access.
NOT_ALLOWED403Contact the business to cancel this subscription
NOT_CONNECTED409WhatsApp is not connected
NOT_FOUND404Resource not foundCheck the id, and that it belongs to this key’s mode (test keys see test objects only).
NOT_LINKED404This account no longer exists
NOT_MOBILE_MONEY400This transaction is not a mobile money payment
NOT_READY409Export is not ready for download
NOT_REGISTERED404Unknown or unregistered host
NOT_RETRYABLE409Only blocked, failed or rejected documents can be retried
NUMBER_IN_USE409This WhatsApp number is connected to another business
OFFER_EXPIRED400This offer has expired
OFFER_NOT_PENDING400, 409Only a pending offer can be accepted
ONBOARDING_STATE_INVALID400, 409Total UBO ownership across all owners cannot exceed 100%
PAGE_IN_USE409This Page or Instagram account is connected to another business
PAGE_UNAVAILABLE404This page is not available
PASSWORD_BREACHED400This password has appeared in a data breach. Choose a different password.
PASSWORD_REQUIRED400Password is required for new accounts
PAUSED409Resume the catalog sync first
PAYLOAD_TOO_LARGE413Request body must be 1 MiB or smaller
PAYMENT_FAILED402Subscription retry did not complete
PAYMENT_METHOD_NOT_AVAILABLE400This payment method is not offered in the merchant’s market
PAYOUT_NOT_CANCELLABLE400, 409This payout was cancelled before it was processed
PHONE_REQUIRED400customerPhone is required for mobile money payments
PKCE_REQUIRED400Public clients must send code_challenge (S256)
PLAN_HAS_SUBSCRIBERS400Deactivate subscribers before deactivating plan.
PLAN_IN_USE409Another membership already uses this plan
PROVIDER_UNAVAILABLE409, 503That fiscal provider is not available for your business
PROXY_ERROR502Failed to execute explorer request
PUBLISHABLE_KEY_WRITE_FORBIDDEN403Publishable keys cannot perform write operations. Use a secret key.Publishable keys only pay checkout sessions your server created: call this from your server with a secret key.
RATE_LIMIT_EXCEEDED429Too many requestsBack off: retry after the Retry-After seconds.
RATE_LIMIT_UNAVAILABLE503Rate limiting is temporarily unavailable. Try again shortly.
RATE_LIMITED429Too many explorer requests. Try again in a minute.Back off: retry after the Retry-After seconds.
RAW_CARD_DATA_REJECTED400Card details are entered only in Watenga secure fields or hosted checkout. Use watenga.mount() or secure Elements.
RECURRENCE_OFF409Repeat bookings are switched off for this service
RECURRING_DISABLED403Recurring giving is disabled for this merchant
REVIEW_REQUIRED403Campaign publication requires admin review
SAVED_DESIGN_LIMIT409You can keep up to … saved designs; delete one first
SCOPE_FORBIDDEN403Restricted key lacks … access to refundsThe restricted key lacks the scope this route needs (see the route’s restricted-key scope): use a key with that scope.
SEARCH_ERROR500Search failed
SECRET_KEY_REQUIRED403Read checkout sessions with a secret keyCall this with a secret key from your server.
SELF_APPROVAL_FORBIDDEN403Approver must differ from requester
SESSION_EXPIRED401This view-as session has ended
SESSION_IDLE_TIMEOUT401Session expired due to inactivity
SESSION_REFRESH_RACE409Your session was just refreshed; try again
SLUG_TAKEN409This slug is already used in the marketplace
STEP_UP_REQUIRED403Confirm it is you with a new code first
STORAGE_UNAVAILABLE503Profile photo storage is temporarily unavailableRetry shortly.
STORE_NOT_FOUND404Shop not found
SUBMERCHANT_INACTIVE403This sub-merchant cannot vault cards
TAX_UNAVAILABLE422, 503Tax for this payment link cannot be calculated right now
TEST_EVENTS_TEST_APPS_ONLY400Simulated events are sent to test apps only. Choose your test app.
TEST_MODE_LIVE_OBJECT400A test key cannot pay a live invoice, payment link or checkout. Use a live key.A test key cannot pay a live object: use a live key, or test objects.
TEST_MODE_ONLY400watenga listen and trigger work with test apps only
TICKET_INVALID400This sign-in link has expired. Go back to the shop and try again.
TOTP_ALREADY_ENABLED4092FA is already enabled
TOTP_ENROLLMENT_REQUIRED403Enable two-factor authentication in Security settings before this action.
TOTP_INVALID400, 401, 403Invalid or expired 2FA codeThe 2FA code is wrong or expired: enter a fresh one.
TOTP_NOT_ENROLLED400Start enrolment first
TOTP_REQUIRED401, 403A 2FA code is required to change your webhook URLSend the 6-digit code from the authenticator app in X-TOTP-Code (dashboard actions).
TRUSTPAY_CHECKOUT_REQUIRED400Please use the TrustPay checkout for this protected payment
TRUSTPAY_NOT_ENABLED400TrustPay is not enabled for this link
UBO_NOT_FOUND404Beneficial owner not found
UNAUTHENTICATED401Authentication required
UNAUTHORIZED401Invalid service signature
UNSUPPORTED_GRANT400Unsupported grant_type
UNSUPPORTED_MEDIA_TYPE415application/json required
UPLOAD_MISSING400Upload was not found in storage
UPLOAD_NOT_FOUND400Uploaded profile photo was not found
VALIDATION_ERROR400A request identifier is not validFix the field named in error.param (all issues are in error.details.issues).
VERSION_EXISTS409Version … already exists for this app
VIRTUAL_ACCOUNT_CREATE_FAILED500Unable to create virtual account
WAITLIST_DISABLED409This service does not take a waitlist
WALLET_NOT_AVAILABLE503… is not enabled for live payments yet
WEBAUTHN_FAILED401Could not verify the security key
WEBAUTHN_REQUIRED401, 403Passkey enrollment is required for this admin role. Register a passkey under Security settings.
WEBHOOK_ENDPOINT_DISABLED409Switch the endpoint back on before replaying its events
WEBHOOK_ENDPOINT_LIMIT409An app can have at most … webhook endpoints
WEBHOOK_MISCONFIGURED503Mobile webhook secret is not configured