POST /api/verify
Fetch + parse a single receipt URL across all supported providers.
Request
| Field | Type | Description |
|---|---|---|
url | string | Full receipt URL. Works for every supported provider. |
reference | string | Shorthand — telebirr-only. Equivalent to transactioninfo.ethiotelecom.et/receipt/<ref>. |
Exactly one of the two is required. URLs and references shown below are placeholders — substitute one from a receipt you control.
Response envelope
Every success returns the same envelope. The shape of receipt varies by provider; use the source field (or its absence) to dispatch.
Telebirr
receipt.source === "telebirr-html". Scraped from the bilingual HTML.
CBE PDF (apps.cbe.com.et and dashed mbreciept.cbe.com.et)
receipt.source === "cbe-pdf". Amounts are numbers, not strings.
Zemen Bank (share.zemenbank.com)
receipt.source === "zemen-pdf". Amounts are numbers; currency is always ETB on these receipts. The URL has the shape share.zemenbank.com/rt/<token>/pdf where <token> is 24 alphanumeric characters (an 8-char prefix followed by the 16-char reference).
Bank of Abyssinia (cs.bankofabyssinia.com)
receipt.source === "boa-json". The public /slip/ page is a React SPA — we
bypass it and hit the same /api/onlineSlip/getDetails/?id=<trx> endpoint the
bundle does, then normalize the response. Amounts are numbers.
CBE JSON (mb.cbe.com.et and plain mbreciept.cbe.com.et)
receipt.source === "mb-json". Richer than the PDF — includes commissions, taxes, and processing dates as an array.
502 — parsed but invalid
The upstream answered with 200 but the body didn't carry enough to validate as a real receipt (no reference, or telebirr lacked receiptNo/payerName/transactionStatus). The partial receipt is still returned so you can inspect what was extracted.
GET /api/verify
Returns { ok: true, ts }. No auth — used by uptime monitors.