Introduction
Welcome to the Milta Wallet Partner API documentation. This API allows partners to integrate wallet, transaction, and payment services. Our REST API provides comprehensive endpoints for managing transfers, account balances, pricing estimates, and reference data. Built with developers in mind, our API is designed to be intuitive, consistent, and powerful.
Base URL
https://api.dev.wallet.milta.be/api/v1/partnerAll API endpoints are relative to this base path
RESTful Design
Predictable resource-oriented URLs and standard HTTP methods
JSON Everywhere
All requests and responses use JSON with UTF-8 encoding
Comprehensive Errors
Detailed error messages with codes for easy debugging purposes.
Authentication
All API requests require HTTP Basic Authentication. Use your API Key ID as the username and API Key Secret as the password.
⚠️ Keep your credentials secure
Never expose your API Key ID or Secret in client-side code, public repositories, or version control. Treat them like passwords and rotate them regularly.
Basic Authentication
Most HTTP clients support Basic Auth natively. The credentials are sent in the Authorization header as a Base64-encoded string.
UsernameYour API Key IDPasswordYour API Key SecretExample Requests
# Using cURL with Basic Auth curl -u "YOUR_API_KEY_ID:YOUR_API_KEY_SECRET" \ https://api.dev.wallet.milta.be/api/v1/partner/inventories/categories
// JavaScript/Node.js
const credentials = Buffer.from(`${apiKeyId}:${apiKeySecret}`).toString('base64');
fetch('https://api.dev.wallet.milta.be/api/v1/partner/inventories/categories', {
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json'
}
});Quick Start
Get up and running in minutes with our quick start guide.
Create an account
Sign up for free and access your dashboard
Generate API key
Create a new API key from the settings page
Make your first request
Test the API with a simple GET request
Test with Postman
Import our Postman collection to quickly test API endpoints without writing code. Our collection includes pre-configured requests for all endpoints with example payloads.
Run in Postman
One-click import directly into your Postman workspace.
Setup Instructions
Import the Collection
Download and import the JSON file into Postman, or use the "Run in Postman" button for direct import.
Configure Environment Variables
Create a new Postman environment and add your API key as API_KEY.
Start Testing
Select any request from the collection, review the parameters, and click Send to test the endpoint.
Terminology
Understanding key terms used throughout our API documentation will help you integrate more effectively.
Transfer
A financial transaction that moves funds from your account to a recipient. Each transfer has a unique ID and can be tracked throughout its lifecycle.
Provider
A payment network or financial institution that processes transactions. Different providers may have varying fee structures, processing times, and geographic coverage.
Product
A specific service offering such as mobile top-ups, bill payments, or money transfers. Each product has unique parameters and availability constraints.
Promotion
Special offers or discounts applied to transactions. Promotions may be time-limited, region-specific, or tied to particular products.
API Responses
All API responses follow a consistent JSON structure with standard HTTP status codes.
Success Response Format
{
"status": "success",
"data": {
// Response payload specific to the endpoint
}
}Error Response Format
{
"status": "error",
"message": "Error description with details about what went wrong"
}HTTP Status Codes
200OKRequest succeeded201CreatedResource created successfully400Bad RequestInvalid request parameters401UnauthorizedInvalid or missing API key429Too Many RequestsRate limit exceeded500Internal Server ErrorServer error - retry with backoffError Codes
Comprehensive list of error codes you may encounter when using the API.
INVALID_API_KEYAPI key is missing or invalidCheck your API key in dashboardINSUFFICIENT_FUNDSAccount balance too lowAdd funds to your accountINVALID_RECIPIENTRecipient details are incorrect or not foundVerify recipient phone number and country codePRODUCT_NOT_AVAILABLERequested product is unavailable in this regionCheck product availability via the inventories endpointRATE_LIMIT_EXCEEDEDToo many requests in a short time periodImplement exponential backoff and retryTRANSFER_ALREADY_EXISTSA transfer with this external ID already existsUse a unique externalId per requestINVALID_AMOUNTTransfer amount is outside the allowed rangeCheck min/max amounts via the pricing endpointPROVIDER_UNAVAILABLEThe payment provider is temporarily unavailableRetry after a short delay or use an alternative providerINTERNAL_ERRORUnexpected server-side error occurredRetry with exponential backoff; contact support if persistsMethod Usage Limits
Rate limits are enforced per API key to ensure fair usage and platform stability. When a limit is exceeded, the API responds with HTTP 429 Too Many Requests.
GET /inventories/*300 req/minReference data endpointsPOST /transfers60 req/minPer API keyGET /transfers/*300 req/minTransfer status lookupsGET /balance60 req/minAccount balance queriesPOST /pricing120 req/minPrice estimation callsHandling 429 Errors
// Retry with exponential backoff
async function requestWithRetry(fn, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (err.status === 429 && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw err;
}
}
}
}Querying
List endpoints support query parameters to filter and refine results. Parameters are passed as URL query strings and are always optional unless stated otherwise.
countrystringISO 3166-1 alpha-2 country code (e.g. GB, US)currencystringISO 4217 currency code (e.g. GBP, USD)providerIdstringFilter results to a specific providerproductTypestringFilter by product categoryExample
GET /inventories/products?country=GB¤cy=GBP&productType=TOPUP
Authorization: Basic {base64(apiKeyId:apiKeySecret)}Paging
Endpoints that return collections support pagination to manage large result sets. Use the page and pageSize query parameters to navigate through results.
pageintegerPage number (1-based). Defaults to 1.pageSizeintegerNumber of items per page. Defaults to 20, max 100.Paginated Response
{
"status": "success",
"data": {
"items": [ ... ],
"pagination": {
"page": 1,
"pageSize": 20,
"totalItems": 84,
"totalPages": 5
}
}
}Batching
Submit multiple transfer requests in a single API call using the batch endpoint. Batching reduces network overhead and simplifies bulk operations.
Batch Limits
Max transfers per batch
A single batch request may contain up to 100 transfers. Each transfer within the batch is processed independently — a failure in one does not affect others.
Batch Request
POST /transfers/batch
{
"transfers": [
{
"externalId": "TXN-001",
"productId": "PRODUCT_123",
"recipientPhone": "+447700900001",
"amount": 10.00,
"currency": "GBP"
},
{
"externalId": "TXN-002",
"productId": "PRODUCT_456",
"recipientPhone": "+447700900002",
"amount": 5.00,
"currency": "GBP"
}
]
}Batch Response
{
"status": "success",
"data": {
"batchId": "BATCH-20260101-ABC",
"accepted": 2,
"rejected": 0,
"transfers": [
{ "externalId": "TXN-001", "status": "PENDING", "transferId": "T-9001" },
{ "externalId": "TXN-002", "status": "PENDING", "transferId": "T-9002" }
]
}
}externalId. Duplicate IDs within the same batch will cause those entries to be rejected.Localization
The API supports locale-aware responses. Pass localization headers to receive product names, descriptions, and messages in the preferred language and currency format.
Accept-Languageen-GBPreferred language for response messagesX-CurrencyGBPPreferred display currency (ISO 4217)X-CountryGBTarget country context (ISO 3166-1 alpha-2)Example
GET /inventories/products
Accept-Language: fr-FR
X-Currency: EUR
X-Country: FR
Authorization: Basic {base64(apiKeyId:apiKeySecret)}Reference Data
Reference data endpoints provide static or slowly-changing information about supported countries, currencies, providers, and products. Cache these responses to reduce API calls.
/inventories/countriesList all supported countries/inventories/currenciesList all supported currencies/inventories/categoriesList product categories/inventories/providersList available payment providers/inventories/productsList products with optional filtersExample Response
GET /inventories/countries
{
"status": "success",
"data": {
"items": [
{ "code": "GB", "name": "United Kingdom", "currencyCode": "GBP" },
{ "code": "FR", "name": "France", "currencyCode": "EUR" },
{ "code": "NG", "name": "Nigeria", "currencyCode": "NGN" }
]
}
}Deferred SendTransfer
Schedule transfers for future execution using the deferred transfer feature. This allows you to prepare transfers in advance and have them execute automatically at the specified time.
How It Works
Submit a deferred transfer
Include `deferred: true` and a `scheduledAt` timestamp in your POST /transfers request.
Transfer enters SCHEDULED state
The API acknowledges the request and holds the transfer until the scheduled time.
Automatic execution
At the scheduled time, the platform processes the transfer and updates its status to PENDING or COMPLETED.
Request Example
POST /transfers
{
"externalId": "TXN-20260101-001",
"productId": "PRODUCT_123",
"recipientPhone": "+447700900001",
"amount": 10.00,
"currency": "GBP",
"deferred": true,
"scheduledAt": "2026-01-15T09:00:00Z"
}Check Status
GET /transfers/T-9001
{
"status": "success",
"data": {
"transferId": "T-9001",
"externalId": "TXN-20260101-001",
"status": "SCHEDULED",
"scheduledAt": "2026-01-15T09:00:00Z",
"amount": 10.00,
"currency": "GBP"
}
}⚠️ Cancellation window
Deferred transfers can be cancelled up to 5 minutes before their scheduled time by calling DELETE /transfers/{id}. After that window, cancellation is not guaranteed.
Optional Features
The Milta Partner API offers several optional features that can be enabled to enhance your integration. Contact your account manager to enable features marked "Available on request".
Webhook Notifications
Available on requestReceive real-time HTTP callbacks when transfer statuses change. Configure your webhook URL in the partner dashboard to avoid polling the status endpoint.
IP Allowlisting
Available on requestRestrict API access to specific IP addresses or CIDR ranges for additional security. Configurable per API key from the developer settings panel.
Idempotency Keys
RecommendedPass an X-Idempotency-Key header to safely retry requests without risk of duplicate transfers. Keys are valid for 24 hours.
Sandbox Environment
Available by defaultA full sandbox environment mirrors the production API for end-to-end testing without real money movement. Use test credentials from your dashboard.