This guide walks you from zero to your first successful API call in under ten minutes.
https://yourtenant.salami.dgl.co.ke.If your organisation already has a Salami tenant, ask your administrator to invite you. You will receive an email with a link to set your password.
Salami organises credentials around apps. Each app represents one integration channel -- a specific M-Pesa shortcode, an SMS sender ID, or a set of KRA API credentials. You can have many apps per module.
API tokens authenticate your server-to-server requests. Every request to the Salami API must include a valid token.
production-server, staging-erp).curl -X POST https://yourtenant.salami.dgl.co.ke/account/api_tokens \
-H "Content-Type: application/json" \
-H "Cookie: <your-session-cookie>" \
-d '{
"name": "my-server-token",
"abilities": "payments:read,payments:write",
"expires_at": "2027-01-01"
}'
Response:
{
"success": true,
"token": "1|a8Bk3xY9z...plainTextToken",
"msg": "API token created successfully"
}
Once you have a token, include it in the Authorization header of every request:
Authorization: Bearer 1|a8Bk3xY9z...plainTextToken
curl -s https://yourtenant.salami.dgl.co.ke/api/pay/apps \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Accept: application/json" | jq .
{
"status_code": 200,
"status_name": "HTTP_OK",
"message": "OK",
"data": [
{
"id": 1,
"name": "My M-Pesa Till",
"type": "MpesaKeC2B",
"is_live": true,
"created_at": "2025-06-01T08:30:00Z"
}
]
}
curl -s -X POST https://yourtenant.salami.dgl.co.ke/api/sms/apps/1/send \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "+254712345678",
"message": "Hello from Salami Gateway!"
}' | jq .
{
"success": true,
"data": {
"sms_id": 5432,
"status": "sent",
"recipient": "+254712345678"
},
"message": "SMS sent successfully"
}
curl -s -X POST https://yourtenant.salami.dgl.co.ke/api/kra/checkers/pin \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "X-KRA-App-Id: 1" \
-d '{
"KRAPIN": "P051234567A"
}' | jq .
{
"success": true,
"data": {
"TaxpayerName": "ACME LIMITED",
"KRAPIN": "P051234567A",
"TaxPayerType": "Non-Individual",
"Status": "Active"
}
}
curl -s -X POST https://yourtenant.salami.dgl.co.ke/api/kra/etims/sales/submit \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"date": "2026-03-29",
"trader_invoice_number": "INV-001",
"receipt_type_code": "S",
"customer_tin": "P051234567A",
"customer_name": "Acme Limited",
"sales_tax_summary": {
"taxable_amount_a": 0,
"taxable_amount_b": 8620.69,
"taxable_amount_c": 0,
"taxable_amount_d": 0,
"tax_rate_a": 0,
"tax_rate_b": 16,
"tax_rate_c": 0,
"tax_rate_d": 0,
"tax_amount_a": 0,
"tax_amount_b": 1379.31,
"tax_amount_c": 0,
"tax_amount_d": 0
}
}' | jq .
{
"success": true,
"message": "Sale submitted to eTims successfully",
"data": {
"id": 789,
"trader_invoice_number": "INV-001",
"cu_invoice_number": "CU20260329-001",
"status": "submitted"
}
}
Every module supports a sandbox or test mode so you can develop without touching real money or filing real returns.
POST /api/pay/{app}/simulateTransaction) to fabricate callbacks locally.https://apisandbox.kra.go.ke.| Check | Details |
|---|---|
| App environment | Confirm the app is set to Production |
| Callback URLs | Point to your production server (HTTPS required) |
| Credentials | Swap sandbox keys for live keys |
| Token scopes | Ensure the production token has the right scopes |
| Webhook verification | Confirm your server responds with 200 OK within 15 seconds |
Before switching to production, verify every item below.
success field and handles 4xx/5xx responses gracefully.200 quickly; does heavy processing asynchronously.Need help? Email support@dgl.co.ke or check the FAQs.