Artha All Module Api's
    • Introduction
    • Authentication
    • KYC/KYB Requirements
    • API Setup Guide
    • Products
      • List Products
        GET
      • Get Product
        GET
      • Get Customer Product Status
        GET
    • Customers
      • Create Customer
        POST
      • List Customers
        GET
      • Get Customer
        GET
      • Submit Applicant (KYC/KYB)
        POST
      • Create Onboarding Session
        POST
    • Wallets
      • Beneficiary
        • Create Crypto Beneficiary
        • Update Crypto Beneficiary
        • List Crypto Withdraw Beneficiaries
      • Create Wallet
        POST
      • Get Wallet Address
        GET
      • Get Customer Balances
        GET
      • List Wallets
        GET
      • List Withdrawals
        GET
      • List Withdrawal Networks
        GET
      • Preview Withdrawal Summary
        POST
      • Create Crypto Withdrawal
        POST
    • Cards
      • Issuance
        • Issue Card
        • List Cards
        • List Customer Cards
        • Get Card Details
        • Get Sensitive Card Details
      • Funding
        • Top Up Card
        • Get Card Balance
        • Get Top-Up Status
        • List Top-Up History
      • Operations
        • Resend Activation Code
        • Activate Card
        • Set Card PIN
        • Change Card PIN
        • Update Card Limits
        • Freeze Card
        • Unfreeze Card
        • Replace Card
        • Cancel Card
        • Get Card Limits
        • Show Card PIN Details
        • Get PIN View Iframe URL
        • Get PIN Change Iframe URL
        • Get PIN Set Iframe URL
        • Get Card View Iframe URL
        • Show Card PIN
    • Payees
      • Create a payee for a customer.
        POST
      • List a customer's payees.
        GET
      • Update a payee.
        PUT
      • Retrieve a payee by id.
        GET
      • Look up an existing payee.
        GET
      • List the currencies a payee can be created in.
        GET
      • List the accepted payment purpose codes for a payee.
        GET
      • List the countries a payee can be created in.
        GET
      • List currency/country pairings for payees.
        GET
      • List the accepted beneficiary relationship codes.
        GET
    • Payments
      • Onboarding
        • List the customer's payout-currency configuration sections.
        • Enable a payout-currency section for the customer.
        • Get the customer's terms-of-service acceptance status.
        • Enable or disable a payout-currency section.
      • Quote
        • List the currencies a beneficiary can be paid in under a product.
        • List the payout rails available for a product and beneficiary.
        • Create an FX quote giving the rate and fee for a cross-currency payout.
      • Order
        • Submit a payout order to send money to a beneficiary.
        • Retrieve the on-chain address to fund an order.
        • Retrieve the status and settlement detail of a payout order.
      • Lookups
        • List the accepted payment purpose codes for a payout.
        • List the accepted source-of-funds codes for a payout.
        • List the document types accepted on a payout order.
    • Banks
      • Accounts
        • Create Bank Account
        • Get Account Details
        • Get Account Issuance Status
      • Withdraw
        • Create Withdrawal Quote
        • List Withdrawal Purposes
        • Get Payment Schemes
        • Execute Withdrawal
    • Exchange
      • Quote
        • Get Exchange Rate
        • Create Price Quote
      • Order
        • Place Exchange Order
    • Transactions
      • List Transactions
      • Get Transaction Details
    • Utilities
      • List Currencies
      • List Countries
      • Get Fee Schedule
      • List Product Occupations
      • List Product Industry Codes
      • Upload File
    • Webhook's
      • Wallets Webhooks
      • Banks Webhooks
      • Payments Webhooks
      • Exchange Webhooks
      • Card Webhooks

    Authentication

    Overview#

    The Artha Cards External API uses HMAC-SHA256 request signing for authentication. Every request must include 5 headers that prove the client's identity, ensure request integrity, and prevent replay attacks.
    This is the same approach used by Stripe, Adyen, Razorpay, and other fintech providers.

    Credentials#

    When onboarded, each client receives:
    CredentialDescriptionExample
    API KeyPublic identifier sent with every requestak_live_8f3a9b2c1d4e5f6a
    SecretPrivate key used to compute HMAC signatures. Never sent over the wire.mJ8v3aQpT5y2rX6nK9cD4eH7sB1uF0gLzN2wV8tYqP=
    Important: The Secret is displayed only once at creation time. Store it securely (e.g., in a vault or environment variable). If lost, a new API key must be generated.

    Required Headers#

    Every request to /api/v1/* must include these 5 headers:
    HeaderTypeDescription
    X-API-KeystringYour API key (e.g., ak_live_8f3a9b2c1d4e5f6a)
    X-TimestampstringCurrent UTC time as Unix epoch seconds (e.g., 1707753600)
    X-NoncestringA unique random string per request (e.g., UUID or random hex). Must not be reused within 5 minutes.
    X-Body-Hashstringbase64(SHA-256(request_body)). For requests with no body (GET, DELETE), hash an empty string.
    X-Signaturestringbase64(HMAC-SHA256(secret, string_to_sign))

    How to Compute the Signature#

    Step 1: Compute the Body Hash#

    body_hash = base64(SHA-256(request_body_bytes))
    Use the raw request body bytes (UTF-8 encoded)
    For GET/DELETE requests with no body, hash an empty byte array: base64(SHA-256(b""))
    The body hash for an empty body is always: 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=

    Step 2: Build the String to Sign#

    Concatenate 5 components separated by newline (\n):
    string_to_sign = "{METHOD}\n{PATH_AND_QUERY}\n{TIMESTAMP}\n{NONCE}\n{BODY_HASH}"
    ComponentDescriptionExample
    METHODHTTP method in uppercasePOST
    PATH_AND_QUERYFull path including query string/api/v1/cards?limit=10
    TIMESTAMPSame value as X-Timestamp header1707753600
    NONCESame value as X-Nonce headera1b2c3d4e5f6
    BODY_HASHSame value as X-Body-Hash headerbase64(SHA-256(body))

    Step 3: Compute the HMAC Signature#

    signature = base64(HMAC-SHA256(secret_bytes, string_to_sign_bytes))
    secret_bytes: your Secret encoded as UTF-8 bytes
    string_to_sign_bytes: the string from Step 2 encoded as UTF-8 bytes

    Full Example#

    Request#

    POST /api/v1/cards HTTP/1.1
    Host: api.arthapay.com
    Content-Type: application/json
    X-API-Key: ak_test_abc123def456
    X-Timestamp: 1707753600
    X-Nonce: f47ac10b-58cc-4372-a567
    X-Body-Hash: oWVxV2ghrGQFIMUEm0bRNNMCHTCnxNFKbqA3CMY9VVE=
    X-Signature: K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=
    
    {"product_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "customer_id": "...", "currency": "USD"}

    Step-by-step Computation#

    1. Body Hash:
       body = '{"product_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", ...}'
       X-Body-Hash = base64(SHA-256(body_bytes))
    
    2. String to Sign:
       "POST\n/api/v1/cards\n1707753600\nf47ac10b-58cc-4372-a567\noWVxV2ghrGQFIMUEm0bRNNMCHTCnxNFKbqA3CMY9VVE="
    
    3. Signature:
       X-Signature = base64(HMAC-SHA256(secret, string_to_sign))

    Code Examples#

    C# (.NET)#

    Python#

    JavaScript / Node.js#

    cURL#


    Error Responses#

    When authentication fails, the API returns a 401 Unauthorized response:
    {
      "success": false,
      "error": {
        "code": "UNAUTHORIZED",
        "message": "Missing required authentication headers (X-API-Key, X-Timestamp, X-Nonce, X-Body-Hash, X-Signature)."
      }
    }

    Common Authentication Errors#

    Error MessageCauseFix
    Missing required authentication headersOne or more of the 5 headers is missingInclude all 5 headers
    Invalid API keyAPI key not found in databaseCheck your API key is correct
    API key is disabledKey was manually disabled or auto-lockedContact admin
    API key has expiredKey passed its ExpiresAt dateRequest a new API key
    API key is locked due to excessive failures50+ consecutive auth failuresContact admin to reset
    Request from unauthorized IP addressClient IP not in the AllowedIPs whitelistRequest IP whitelist update
    Request timestamp is outside the allowed windowX-Timestamp is more than 5 minutes from server timeSync your system clock (NTP)
    Replay detected (duplicate nonce)Same nonce reused within 5 minutesGenerate a new nonce per request
    Body hash mismatchX-Body-Hash doesn't match the actual request bodyRecompute SHA-256 of the exact body bytes sent
    Signature mismatchHMAC signature is incorrectVerify string-to-sign format and secret

    Security Properties#

    PropertyMechanism
    IdentityAPI Key identifies the client and tenant
    AuthenticationHMAC-SHA256 proves the client has the secret
    IntegrityBody hash ensures the request body wasn't tampered with
    Replay ProtectionTimestamp window (5 min) + unique nonce per request
    Timing Attack ProtectionConstant-time comparison for all hash/signature checks
    Auto-lockoutKey auto-disables after 50 consecutive auth failures
    IP RestrictionOptional IP whitelist per API key
    ExpirationOptional key expiration date
    ScopingPer-key permission scopes

    Rate Limits#

    Requests are rate-limited per API key
    Default: varies by endpoint
    HTTP 429 is returned when limits are exceeded
    Use X-RateLimit-Remaining and X-RateLimit-Reset response headers to manage your request rate

    Modified at 2026-08-03 04:44:35
    Previous
    Introduction
    Next
    KYC/KYB Requirements
    Built with