Using the API
This guide explains how to authenticate your requests and use the ZitoPay API effectively, including understanding required headers and generating signatures.
API Environments
Environment Separation
Sandbox and production environments are completely isolated. They have different base URLs, different API keys, and separate data. What you do in sandbox does not affect production, and vice versa.
Base URLs
| Environment | Base URL |
|---|---|
| Sandbox | http://localhost:9000 |
| Production | https://api.zitopay.com |
Note: Update base URLs based on actual deployment configuration.
Authentication
API Key Authentication
ZitoPay uses API key authentication with HMAC-SHA256 signatures. This is not JWT tokens (those are for merchant dashboard access). Each request must include your API key and a valid signature.
This authentication method ensures that:
- Only you can make requests with your API key
- Requests cannot be tampered with (signature validation)
- Requests cannot be replayed (timestamp and nonce validation)
Getting Your API Keys
- Navigate to your merchant dashboard
- Go to API Settings or Credentials section
- Copy your sandbox API key and secret key
- For production, complete KYC and request production access
- Save your secret key securely - it's only shown once!
This key will authenticate your requests to the sandbox environment only and should not be used in production. Production API keys are separate and only available after completing KYC verification and requesting production access.
Required Headers
Overview
Every request to /api/v1/* endpoints must include these 6 headers. Think of headers as labels on a package - they tell the API who you are, when the request was made, and prove it's authentic.
Header Details
x-zito-key
Your merchant API key (sandbox or production). This identifies which merchant is making the request - like your ID card, it proves who you are. Retrieved from your merchant dashboard.
x-zito-timestamp
Current Unix timestamp in seconds. Must be within ±5 minutes of server time. This prevents replay attacks (using old requests). Example: 1705564800
x-zito-nonce
Unique random string (UUID recommended). Each request must have a different nonce. This prevents duplicate request attacks. Cannot be reused within 10 minutes. Example: 550e8400-e29b-41d4-a716-446655440000
x-zito-origin
Your application's origin URL or IP address. Must match a verified domain OR allowed IP. Used for allowlisting validation. Example: https://example.com or 192.168.1.1
x-zito-signature
HMAC-SHA256 signature of the request. Generated using your secret key. This proves the request is authentic and hasn't been tampered with. See "Signature Generation" section below.
x-zito-version
API version you're using. Currently: "1.0". This allows for future API versioning while maintaining backward compatibility.
Signature Generation
Why Signatures?
Signatures serve three critical purposes:
- Proves the request really came from you (authentication)
- Prevents tampering (if request is changed, signature won't match)
- Prevents forgery (only you have the secret key)
How to Generate
To generate a signature, you need to:
- Construct a canonical string from:
method + path + sorted_query + body_json + timestamp + nonce + origin - Generate HMAC-SHA256 using your secret key
- Include the signature in
x-zito-signatureheader
Signature Formula
stringToSign = METHOD + PATH + SORTED_QUERY_PARAMS + REQUEST_BODY + TIMESTAMP + NONCE + ORIGIN
signature = HMAC-SHA256(secretKey, stringToSign)
Critical Formatting Rules
- NO separators: All components must be concatenated directly without newlines, spaces, or special characters
- NO prefix: The signature header must contain ONLY the hexadecimal hash (no
sha256=prefix) - Query sorting: Query parameters must be sorted alphabetically before inclusion
- Canonical JSON: Body must be stringified consistently (same format for signature and request)
The exact format must match precisely. Code examples with detailed implementations are provided in the Authentication documentation. It's crucial that the string construction matches exactly, including the order of components and how query parameters are sorted. Even small formatting differences will cause authentication failures in both sandbox and production environments.
Request Flow
Typical Request Flow
- Prepare your request body
- Generate timestamp and nonce
- Construct canonical string
- Generate HMAC signature
- Include all headers
- Send request
- Handle response
Response Handling
ZitoPay uses standard HTTP status codes:
- 2xx: Success - Your request was processed successfully
- 4xx: Client error - Check your request (authentication, validation, etc.)
- 5xx: Server error - Retry later (these are rare)
Always implement proper error handling to gracefully manage different response scenarios.
Rate Limiting
Overview
The API implements rate limiting for stability and fair usage. Default rate limit is 100 requests per minute per merchant, but this is configurable per merchant based on your needs.
Rate Limit Responses
When rate limit is exceeded, you'll receive a 429 Too Many Requests response. The response includes a retry_after header indicating how many seconds to wait before retrying. Implement exponential backoff when handling rate limit responses.
Security Features
IP/Domain Allowlisting
Requests must come from allowlisted IPs OR verified domains. Configure this in your merchant dashboard. This provides an additional security layer by ensuring only requests from your known sources can access your API.
Timestamp Validation
Prevents replay attacks. Requests older than 5 minutes are rejected. This ensures that even if someone intercepts your request, they can't use it later.
Nonce Validation
Prevents duplicate requests. Each nonce can only be used once within a 10-minute window. This protects against accidental or malicious duplicate submissions.
Important: If you retry a request with the same nonce within 10 minutes, it will be rejected. Always generate a new nonce (UUID recommended) for each API request, even if you're retrying a failed request.
Signature Verification
All signatures are verified using constant-time comparison (prevents timing attacks). Invalid signatures are rejected immediately. This ensures that only requests with valid signatures from the correct secret key are accepted.
Best Practices
- Always use HTTPS in production
- Store API keys securely (never in client-side code)
- Generate unique nonces for each request
- Handle all error responses gracefully
- Implement retry logic for transient errors (with exponential backoff)
- Monitor your API usage and set up alerts
- Test in sandbox before production
- Keep your secret keys secure and rotate them periodically
- Use IP allowlisting or domain verification for additional security
Next Steps
Now that you understand how to authenticate and make requests, explore the specific API endpoints:
- Collection API Documentation - Learn how to accept payments from customers
- Disbursement API Documentation - Learn how to send payments to customers
- Transaction Status Documentation - Learn how to check transaction status
- Webhooks Documentation - Learn how to receive real-time notifications