Transaction Verify API
A single endpoint that accepts a receipt URL or transaction reference, fetches and parses the receipt from the originating bank, and returns structured transaction data. Verified transactions are cached — repeat lookups are served instantly from the database.
Base URL
/api/v1
Auth
None required
Format
JSON
Endpoint
POST accepts a JSON body. GET accepts the same fields as query parameters. POST is preferred to avoid URL-encoding issues with receipt URLs.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | Either/or | Full receipt URL. Bank is auto-detected from the hostname. Pass this or reference. |
reference |
string | Either/or | Transaction reference / receipt ID. Bank is inferred from the pattern, or pass bank explicitly. |
bank |
string | Optional | Bank slug. Required when the reference pattern is ambiguous (e.g. BOA, Awash, Dashen, M-Pesa). See Supported Banks. |
phone |
string | Conditional | Required when bank=cbebirr and reference is used (not needed when a full URL is provided). |
suffix |
string | Conditional | Account destination suffix appended to the reference when building the receipt URL. Required for bank=cbe (last 8 digits) and bank=boa (last 5 digits) when using reference. |
settlement_account |
string | Optional | Account number or phone the payment is expected to have landed in. When provided, the response includes a settlement_match object with match type and confidence. |
Supported Banks
| Bank | Slug | Auto-detect / Notes |
|---|---|---|
| Commercial Bank of Ethiopia | cbe |
apps.cbe.com.et FT-prefixed references auto-detected. PDF receipt. |
| CBE Mobile Receipt | cbemobile |
mbreciept.cbe.com.et Token slug. Auto-detected from URL. JSON API. |
| CBE Birr | cbebirr |
cbepay1.cbe.com.et Requires phone when using reference. PDF receipt. |
| Bank of Abyssinia | boa |
cs.bankofabyssinia.com Requires bank param with reference. JSON API. |
| Telebirr | telebirr |
transactioninfo.ethiotelecom.et 8–12 char references auto-detected. HTML receipt. |
| Zemen Bank | zemen |
share.zemenbank.com 16+ char references auto-detected. PDF receipt. |
| Awash Bank | awash |
awashpay.awashbank.com Full URL required (no reference template). HTML receipt. |
| Dashen Super App | dashen |
api.dashensuperapp.com Full URL required (no reference template). PDF receipt. |
| M-Pesa Ethiopia | mpesa |
m-pesabusiness.safaricom.et Requires bank param with reference. PDF via base64. |
| Wegagen Bank | wegagen |
wegagenbanksc.com.et Requires bank param with reference. JSON API. |
| NIB International Bank | nib |
nibinvoice.nibbank.com.et Requires bank param with reference. JSON API. |
| Siinqee Bank | siinqee |
receipts.siinqeebank.com Requires bank param with reference. JSON API. |
| Abay Bank | abay |
abaymobile.com.et Requires bank param with reference. JSON API. |
| Kaafi Ebirr | kaafiebirr |
receipt.ebirr.com Requires bank param with reference. JSON API. |
Rate Limits
| Tier | Limit | Scope |
|---|---|---|
| Anonymous | 10 requests / hour | Per IP address |
Cached lookups count against the limit. When exceeded, the API returns
429 Too Many Requests with
Retry-After and X-RateLimit-Reset headers
indicating when the window resets.
Request Examples
cbe
Commercial Bank of Ethiopia
POST /api/v1/verify
Content-Type: application/json
{"url": "https://apps.cbe.com.et:100/?id=FT25211G11JQ21827223"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "FT25211G11JQ21827223"}
cbemobile
CBE Mobile Receipt
POST /api/v1/verify
Content-Type: application/json
{"url": "https://mbreciept.cbe.com.et/fHCxyUdnBt2PA0H8ge"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "fHCxyUdnBt2PA0H8ge", "bank": "cbemobile"}
cbebirr
CBE Birr
POST /api/v1/verify
Content-Type: application/json
{"url": "https://cbepay1.cbe.com.et/aureceipt?TID=ABC1234567&PH=0911234567"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "ABC1234567", "bank": "cbebirr", "phone": "0911234567"}
boa
Bank of Abyssinia
POST /api/v1/verify
Content-Type: application/json
{"url": "https://cs.bankofabyssinia.com/api/onlineSlip/getDetails/?id=FT26166XLKCN05677"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "FT26166XLKCN05677", "bank": "boa"}
telebirr
Telebirr
POST /api/v1/verify
Content-Type: application/json
{"url": "https://transactioninfo.ethiotelecom.et/receipt/DF98Q6QQRM"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "DF98Q6QQRM"}
zemen
Zemen Bank
POST /api/v1/verify
Content-Type: application/json
{"url": "https://share.zemenbank.com/rt/94497018108ATWR2520600HM/pdf"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "94497018108ATWR2520600HM"}
awash
Awash Bank
POST /api/v1/verify
Content-Type: application/json
{"url": "https://awashpay.awashbank.com:8225/-E41AE0D86FFA-21XYYW"}
dashen
Dashen Super App
POST /api/v1/verify
Content-Type: application/json
{"url": "https://api.dashensuperapp.com/receipts/TopUp--Ethio-telecom-air-time-TopUp-387ETAP2522000WK.pdf"}
mpesa
M-Pesa Ethiopia
POST /api/v1/verify
Content-Type: application/json
{"url": "https://m-pesabusiness.safaricom.et/api/receipt/getReceipt?trxNo=MP12345ABC"}
POST /api/v1/verify
Content-Type: application/json
{"reference": "MP12345ABC", "bank": "mpesa"}
Response Format
Valid transaction
{ "valid": true, "status": "verified", "bank": "boa", "cached": false, "data": { "sender_name": "MUBAREK SEID JUHAR", "sender_account": "1******77", "receiver_name": "ELIAS WELDU REZAKUM", "receiver_account": "1**********08", "receiver_bank": "Commercial Bank of Ethiopia", "sent_amount": "10.00 ETB", "service_charge": "0.06 ETB", "tax_vat": "0.01 ETB", "total_paid": "10.07 ETB", "transfer_date": "14/06/26 12:46", "transaction_id": "FT26166XLKCN", "transaction_type": "Other Bank Transfer", "reason": "P2P Transaction" } }
Pending (bank unreachable)
When the bank API is temporarily unreachable (connection timeout), a soft pending state is returned instead of a hard 502 error. Clients should retry.
{ "valid": false, "status": "pending", "bank": "cbe", "cached": false, "data": { "error": "Bank service is temporarily unreachable. Please try again in a moment." } }
Invalid / not found
{ "valid": false, "bank": "boa", "cached": false, "data": { "transaction_id": "", "error": "Invalid reference number" } }
Cached response
When a transaction was previously verified and stored, the response is returned from the database. Only the top-level fields differ — data is identical.
{ "valid": true, "bank": "boa", "cached": true, "data": { ... }, "confirmation": { "confirmed_count": 4, // how many times this txn has been verified "first_confirmed_at": "2026-06-01T09:12:00+03:00", "last_confirmed_at": "2026-06-15T14:33:00+03:00" } }
Settlement match
When settlement_account is provided, the response includes a settlement_match object.
{ "valid": true, "data": { ... }, "settlement_match": { "matched": true, "match_type": "phone_normalised", "match_confidence": "high" } }
X-Verify-Cache header
Every response carries an X-Verify-Cache header indicating whether the result came from the live upstream or the local DB cache.
X-Verify-Cache: HIT // served from database cache X-Verify-Cache: MISS // fetched live from the bank
Response Fields
All fields live inside data. Not every field is present for every bank — omitted fields are simply absent from the object.
| Field | Description | Banks |
|---|---|---|
status |
verified · pending · invalid — always present at the top level | All |
sender_name |
Full name of the payer / debit account holder | All |
sender_account |
Masked or partial account number of the sender | All |
receiver_name |
Full name of the beneficiary / credit account holder | All |
receiver_account |
Masked or partial account / phone of the receiver | All |
receiver_bank |
Destination bank name (inter-bank transfers) | awash, boa, cbe |
sent_amount |
Amount credited to the receiver (with currency) | All |
service_charge |
Bank service / commission fee | All |
tax_vat |
15% VAT on the service charge | All |
total_paid |
Total debited from sender including fees | All |
transfer_date |
Transaction timestamp (format varies by bank) | All |
transaction_id |
Unique transaction reference used for caching | All |
invoice_no |
Invoice number (Zemen Bank) | zemen |
receipt_number |
Receipt number (CBE Birr) | cbebirr |
order_id |
Order ID (CBE Birr) | cbebirr |
receipt_no |
Receipt number (M-Pesa) | mpesa |
status |
Transaction status string | telebirr, zemen |
transaction_type |
Type of transaction (transfer, topup, etc.) | boa, cbemobile, dashen, awash |
reason |
Payment reason or narrative | cbe, awash, boa, telebirr, mpesa |
channel |
Payment channel used | telebirr, cbebirr |
service_type |
Service type label (Dashen) | dashen |
narrative |
Free-text narrative (Dashen) | dashen |
transfer_ref |
Secondary transfer reference (Dashen) | dashen |
error |
Human-readable reason when valid is false | All (when invalid) |
confirmation.confirmed_count |
Number of times this transaction has been verified | All (cached txns) |
confirmation.first_confirmed_at |
ISO 8601 timestamp of the first verification | All (cached txns) |
confirmation.last_confirmed_at |
ISO 8601 timestamp of the most recent verification | All (cached txns) |
settlement_match.matched |
true if the receiver account matches settlement_account | When settlement_account provided |
settlement_match.match_type |
exact · suffix · masked_pattern · phone_normalised · unmatched | When settlement_account provided |
settlement_match.match_confidence |
high or none | When settlement_account provided |
Error Codes
| Status | Cause |
|---|---|
422 |
Neither url nor reference provided; unsupported bank value; bank cannot be auto-detected from reference; CBE Birr missing phone; Awash/Dashen missing URL. |
200 status=pending |
Bank API connection timeout or DNS failure. Not a hard error — the client should retry. No credits are deducted. |
502 |
The bank API returned an unexpected error or the PDF/HTML parser failed. Unlike timeouts, these are non-retriable parsing failures. |
200 status=invalid |
Receipt was fetched but the transaction does not exist or was rejected by the bank. Check data.error for the reason. |
PDF receipts (CBE, CBE Birr, Dashen, Zemen, M-Pesa) are parsed with smalot/pdfparser — a pure-PHP library with no system dependencies.
No additional packages need to be installed on the server.
Playground
Send a live request to /api/v1/verify and inspect the response — no external tools needed.
// fill in the form above
// response will appear here