SW SwiftWallet
Base URL https://swiftwallet.co.ke/v3

Error handling

Every error uses one envelope. Branch on error_code, not on the message text.

{
  "success": false,
  "error": "Human-readable message",
  "error_code": "MACHINE_CODE",
  "details": {}
}

Validation failures return 400 VALIDATION_ERROR with details.fields, for example {"fields": {"amount": ["The amount field is required."]}}.

error_codeHTTPWhen
API_KEY_NOT_IN_HEADER401An api_key was sent in the query string or body. Only the Authorization header is accepted.
INVALID_API_KEY401No Bearer token, or the key is unknown, inactive or revoked.
API_KEY_EXPIRED401The key is past its expiry date.
USER_INACTIVE403The account is suspended.
ACCOUNT_NOT_VERIFIED403The account email is not verified (and not waived by support).
IP_NOT_ALLOWED403The key has an IP allowlist and the caller is not on it.
RATE_LIMIT_EXCEEDED429Over the subscription tier's per-minute limit. See Rate limiting.
SERVICE_NOT_PERMITTED403The key lacks the route's scope (details.required_scope), or a reversal targets a product the key cannot reverse.
VALIDATION_ERROR400Bad input. details.fields lists messages per field when the request validator rejected it.
NOT_FOUND404Unknown route, or the resource does not exist on your account.
METHOD_NOT_ALLOWED405The path exists but not for this HTTP method.
ENDPOINT_REMOVED410POST /v3/account/ (signup) and SwiftPay were removed.
DUPLICATE_REFERENCE409external_reference was already used on your account.
URL_NOT_ALLOWED400callback_url is not HTTPS, has credentials or a non-standard port, or resolves to a private address.
INSUFFICIENT_SERVICE_BALANCE402The service wallet cannot cover the fee.
INSUFFICIENT_PAYMENT_BALANCE402The payments wallet cannot cover the send amount.
INSUFFICIENT_BALANCE402A wallet without a specific type cannot cover the movement.
PERSONAL_KYC_VERIFICATION_REQUIRED403Personal KYC must be approved (sending money, or collecting after the KYC deadline).
CHANNEL_KYC_VERIFICATION_REQUIRED403The channel requires business KYC that is not approved.
WALLET_ACTIVATION_REQUIRED403The wallet channel has not been activated.
CHANNEL_UNAVAILABLE403The channel is inactive or suspended by SwiftWallet.
TRANSACTION_QUALITY_BELOW_THRESHOLD403This month's success rate is below the platform threshold.
LIMIT_EXCEEDED422A daily payout limit was reached.
REVERSAL_NOT_ALLOWED422The original transaction cannot be reversed (state, amount mismatch or already reversed).
MPESA_REQUEST_FAILED502M-Pesa rejected the request. No money was moved, or it was refunded.
NO_MERCHANT_AVAILABLE503No M-Pesa shortcode is available for this service right now. Retry with backoff.
INTERNAL_ERROR500Unhandled failure. Retry with backoff and check service status.

On 5xx and network errors, retry with exponential backoff and look the transaction up by external_reference before sending a payment again.