Sandbox mode — Use https://wallet.e-mazad.store/api/v1 as your base URL

Error Codes

When a request fails, Mazad returns a consistent JSON error body with a machine-readable error code, an HTTP status, and a human-readable message. Use the error code (not the HTTP status) to determine what went wrong and how to recover.

Error Response Structure

Every error response follows this shape. The code field is the stable identifier you should match against in your code.

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient available balance for this transaction."
  }
}

Authentication Errors

Returned when Gateway HMAC credentials are missing, invalid, or expired.

CodeHTTPDescriptionDeveloper Action
HMAC_HEADERS_MISSING401X-Api-Key, X-Api-Signature, or X-Api-Timestamp header is absent.Include all three headers on every gateway request.
HMAC_TIMESTAMP_EXPIRED401The X-Api-Timestamp is more than 90 seconds old.Regenerate a fresh timestamp and recompute the signature. Ensure server clock is NTP-synced.
HMAC_KEY_INVALID401The X-Api-Key does not exist or has been revoked.Check the key ID. If revoked, rotate keys in the admin panel.
HMAC_SIGNATURE_INVALID401The HMAC signature does not match. Canonical string mismatch.Verify the signing formula: HMAC-SHA256(secret, timestamp.METHOD.path.body)
MERCHANT_NOT_FOUND403The API key is not linked to any merchant account.Ensure the merchant account is fully provisioned.
MERCHANT_NOT_APPROVED403Merchant account is Pending, Rejected, or Suspended.Contact support to approve or reactivate the merchant account.
FORBIDDEN403The authenticated user does not have permission for this action.Verify your account has the required role or permission.
TOKEN_EXPIRED401The authentication token (JWT) has expired.Refresh the token or re-authenticate.

PIN Errors

Returned during financial operations that require PIN verification (transfers, FX, cashout).

CodeHTTPDescriptionDeveloper Action
INVALID_PIN401The PIN provided is incorrect. The error message includes attempts remaining.Show attempts remaining from the error message. Do not auto-retry — each attempt counts toward the 5-attempt block.
PIN_BLOCKED401Five consecutive wrong PINs. Account is blocked for financial operations.Direct the user to Security settings to reset PIN via OTP. Do not prompt for PIN again until reset.
PIN_NOT_SET401The user has not set a transaction PIN yet.Redirect user to the PIN setup flow before allowing financial operations.
PIN_REQUIRED422A PIN is required for this operation but was not provided in the request body.Include the pin field in the request body.

Balance & Wallet Errors

Returned when a wallet or account cannot fulfil the requested operation.

CodeHTTPDescriptionDeveloper Action
INSUFFICIENT_BALANCE422The account does not have enough available balance.Check the available balance before initiating the transaction. The details object includes available and required amounts.
WALLET_NOT_FOUND404No wallet exists for the given user or wallet ID.Call POST /users/sync first to auto-create the wallet.
ACCOUNT_NOT_FOUND404The specified currency account was not found in the wallet.Ensure the user has an account in the requested currency.
WALLET_BUSY409Another transaction on this wallet is still being processed.Retry the request after a short delay (1-2 seconds).
CURRENCY_MISMATCH422The transaction currency does not match the account currency.Send the correct currency code or use the FX endpoint for cross-currency transfers.
UNSUPPORTED_CURRENCY422The specified currency is not supported by Mazad.Use one of the supported currencies: IQD, USD.
ACCOUNT_FROZEN403The account has been frozen by an admin or compliance action.Contact support to resolve the account freeze.

Payment & State Errors

Returned when a payment operation is invalid for the current payment state.

CodeHTTPDescriptionDeveloper Action
PAYMENT_NOT_FOUND404No payment exists with the given ID.Verify the payment ID. Payment IDs start with pay_.
PAYMENT_ALREADY_CAPTURED409The payment has already been captured.This is typically safe to ignore -- the payment was already processed.
PAYMENT_ALREADY_VOIDED409The payment has already been voided.The hold has been released. Create a new checkout session if needed.
PAYMENT_EXPIRED422The payment checkout session has expired (default: 30 minutes). The customer did not complete payment in time.Create a new payment and send the customer a fresh checkout_url.
INVALID_PAYMENT_STATUS422The payment is not in the correct status for this operation.Check the current status via GET /payments/:id before operating.
REFUND_EXCEEDS_AMOUNT422The refund amount exceeds the captured amount.Ensure total refunds do not exceed the captured amount.
MERCHANT_NOT_FOUND404The specified merchant was not found.Verify your merchant ID or check that your account is fully onboarded.

Transfer Errors

Returned when wallet-to-wallet transfers fail.

CodeHTTPDescriptionDeveloper Action
TRANSFER_LIMIT_EXCEEDED422The transfer amount exceeds the per-transaction limit.Split the transfer into smaller amounts or request a higher limit.
DAILY_LIMIT_EXCEEDED422The daily transaction limit has been exceeded.Wait until the next day or request a limit increase.
SELF_TRANSFER_NOT_ALLOWED422The sender and recipient are the same account.Provide a different recipient external_user_id.
RECIPIENT_NOT_FOUND404The recipient account was not found.Sync the recipient via POST /users/sync before transferring.
RECIPIENT_UNAVAILABLE422The recipient account is suspended or closed.Contact the recipient to resolve their account status.

Rate Limiting

Mazad enforces rate limits to protect the platform. When you exceed a limit, back off using the Retry-After header.

CodeHTTPDescriptionDeveloper Action
RATE_LIMIT_EXCEEDED429Too many requests in a short period.Implement exponential backoff. Check the Retry-After header for the wait time in seconds.
VELOCITY_LIMIT_EXCEEDED422Too many transactions for this user in a short period.This is a per-user safety limit. Wait a few minutes before retrying.
OTP_RATE_LIMITED422Too many OTP requests for this phone number.Wait at least 60 seconds before requesting another OTP.

Rate limit headers

Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers so you can proactively throttle before hitting the limit.

Idempotency Errors

Returned when the idempotency key header is missing or conflicts with a previous request.

CodeHTTPDescriptionDeveloper Action
IDEMPOTENCY_KEY_REQUIRED422A POST/PATCH request was made without an Idempotency-Key header.Generate a UUID v4 and include it in the Idempotency-Key header.
IDEMPOTENCY_KEY_REUSED409The idempotency key was previously used with a different request body.Generate a new UUID for each unique request. Retries must use the same body.

KYC & Compliance Errors

Returned when identity verification is needed or has failed.

CodeHTTPDescriptionDeveloper Action
KYC_REQUIRED422The operation requires identity verification.Direct the user to complete KYC before retrying.
KYC_PENDING422KYC verification is still being reviewed.Wait for the kyc.approved or kyc.rejected webhook event.
KYC_REJECTED422The KYC submission was rejected.Ask the user to resubmit with valid documents.
TIER_UPGRADE_REQUIRED422The operation requires a higher wallet tier.Guide the user through additional verification to upgrade their tier.

General Errors

Catch-all errors for validation failures, missing resources, and server issues.

CodeHTTPDescriptionDeveloper Action
VALIDATION_ERROR422One or more request fields are invalid.Check the details object for field-level errors and fix the request body.
NOT_FOUND404The requested resource does not exist.Verify the URL path and resource ID.
SERVER_ERROR500An unexpected internal error occurred.Retry with exponential backoff. If persistent, contact support with the request_id.
SERVICE_UNAVAILABLE503The service is temporarily down for maintenance.Retry after a short delay. Check status.mazad.com for incident updates.
FEATURE_DISABLED422The requested feature is not enabled for your account.Contact sales to enable this feature on your merchant account.

Error Handling Best Practices

1.

Always match on error.code, not HTTP status. Multiple error codes can share the same HTTP status (e.g., 422). The code gives you precise context.

2.

Log the request_id. Every error includes a unique request ID. Include it when contacting support for fastest resolution.

3.

Retry with exponential backoff for 429 and 5xx errors. Start with a 1-second delay and double it on each retry, up to a maximum of 60 seconds.

4.

Use idempotency keys for safe retries. If a request times out, you can safely retry with the same Idempotency-Key without risk of duplicate processing.

5.

Show friendly messages to end users. Map error codes to localized user-facing messages. Never show raw error codes or technical details to customers.