API Documentation

Free REST API. No auth. No rate limit. No scam.

No API keyNo signupNo rate limitMIT licensed

Overview

The cheki API verifies Ethiopian bank and mobile money receipts by fetching public bank endpoints. No authentication is required. No API key. No rate limit. Just POST to /api/verify with a bank code and reference number.

Base URL

url
https://chekiapp.vercel.app

Quick Start

Verify a CBE receipt with one cURL call:

bash
curl -X POST https://chekiapp.vercel.app/api/verify \
  -H "Content-Type: application/json" \
  -d '{"bank":"cbe","reference":"FT26140P01YB","accountNumber":"1000560536171"}'

Response

json
{
  "success": true,
  "verified": true,
  "bank": "Commercial Bank of Ethiopia",
  "reference": "FT26140P01YB",
  "amount": 20000,
  "currency": "ETB",
  "senderName": "Mr Mohammed Abdulwasi Reshid",
  "receiverName": "SAMI ADIL ZEKARIA",
  "date": "5/20/2026 7:29:00 PM",
  "sourceUrl": "https://apps.cbe.com.et:100/?id=FT26140P01YB60536171"
}

POST /api/verify

POST/api/verify

Verify a single receipt. Send bank code, reference, and (for CBE/BOA) account number. For BOA inter-bank transfers, send the QR payload in qrData instead.

Parameters

ParameterTypeRequiredDescription
bankstringYes (unless URL)Bank code: cbe, telebirr, boa, mpesa, dashen, zemen, cbebirr, siinqee
referencestringYesTransaction reference number (e.g. FT26140P01YB) or receipt URL
accountNumberstringCBE, BOALast 8 digits for CBE, last 5 for BOA
qrDatastringBOA QRRaw QR payload for BOA inter-bank transfers
phonestringCBE BirrPayer phone number, format: 2519XXXXXXXXX

Request body (CBE)

json
{
  "bank": "cbe",
  "reference": "FT26140P01YB",
  "accountNumber": "1000560536171"
}

Request body (BOA QR code)

json
{
  "bank": "boa",
  "qrData": "3cHRaxVjn/pySp..."
}

Response (200)

json
{
  "success": true,
  "verified": true,
  "bank": "Commercial Bank of Ethiopia",
  "reference": "FT26140P01YB",
  "senderName": "Mr Mohammed Abdulwasi Reshid",
  "senderAccount": "1****1685",
  "receiverName": "SAMI ADIL ZEKARIA",
  "receiverAccount": "1****6171",
  "amount": 20000,
  "currency": "ETB",
  "date": "5/20/2026 7:29:00 PM",
  "branch": "MEKANISA MICHAEL BRANC",
  "durationMs": 7782,
  "sourceUrl": "https://apps.cbe.com.et:100/?id=FT26140P01YB60536171"
}
Response fields
ParameterTypeRequiredDescription
successbooleanWhether the request succeeded (not whether the receipt is real)
verifiedbooleanWhether the receipt was found and matches the bank's records
bankstringFull bank name
referencestringTransaction reference number
senderNamestringName of the account that sent the payment
senderAccountstringMasked sender account number
receiverNamestringName of the account that received the payment
receiverAccountstringMasked receiver account number
amountnumberTransfer amount in ETB
currencystringCurrency code (always ETB for domestic)
datestringTransaction date and time
sourceUrlstringThe bank endpoint URL cheki fetched the data from
durationMsnumberTime spent fetching from the bank endpoint, in milliseconds

POST /api/verify/batch

POST/api/verify/batch

Verify up to 50 receipts in parallel. Send an array of receipt objects with the same fields as the single verify endpoint.

Parameters

ParameterTypeRequiredDescription
receiptsarrayYesArray of receipt objects (same fields as verify). Max 50.
json
{
  "receipts": [
    {
      "bank": "cbe",
      "reference": "FT26140P01YB",
      "accountNumber": "1000560536171"
    },
    {
      "bank": "telebirr",
      "reference": "DET8FJGUJ4"
    }
  ]
}

GET /api/banks

GET/api/banks

List all supported banks with metadata: code, name, type, status, endpoint, and verification requirements.

Response (200)

json
[
  {
    "code": "cbe",
    "name": "Commercial Bank of Ethiopia",
    "type": "bank",
    "status": "live",
    "requiresAccount": true,
    "accountDigits": 8
  },
  {
    "code": "telebirr",
    "name": "Telebirr",
    "type": "wallet",
    "status": "live",
    "requiresAccount": false
  }
]

GET /api/health

GET/api/health

Check if each bank endpoint is reachable. Reports status and latency per bank. Useful for monitoring and debugging.

Response (200)

json
{
  "status": "ok",
  "banks": {
    "cbe": {
      "status": "up",
      "latencyMs": 340
    },
    "telebirr": {
      "status": "geo-blocked",
      "latencyMs": null
    },
    "boa": {
      "status": "up",
      "latencyMs": 180
    }
  }
}

GET /api/receipt

GET/api/receipt?bank=cbe&reference=FT...&account=...

Download the original receipt file (PDF or HTML) from the bank endpoint. Returns the raw file with the appropriate Content-Type header.

SDKs

SDKs are available in 5 languages. All wrap the same REST API with typed errors, retry with exponential backoff, and timeout support.

npm install cheki-verify

import { Cheki } from "cheki-verify";

const cheki = new Cheki();

const result = await cheki.verify("cbe", "FT26140P01YB", {
  accountNumber: "1000560536171"
});

console.log(result.verified);   // true
console.log(result.senderName);
console.log(result.amount);

const batch = await cheki.verifyBatch([
  { bank: "cbe", reference: "FT26140P01YB", accountNumber: "1000560536171" },
  { bank: "telebirr", reference: "DET8FJGUJ4" }
]);

const { banks } = await cheki.getBanks();
const health = await cheki.getHealth();

Error Codes

json
{
  "success": false,
  "error": "Receipt not found. Check the reference number.",
  "bank": "Commercial Bank of Ethiopia",
  "reference": "INVALID123"
}
StatusNameDescription
400Bad RequestMissing required fields or malformed reference number
404Not FoundBank code not recognized or receipt not found at the bank endpoint
422UnprocessableBank endpoint returned data but it could not be parsed
502Bad GatewayBank endpoint is unreachable, geo-blocked, or timed out
500Server ErrorInternal server error. Check /api/health for endpoint status.

Self-hosting with Docker

bash
git clone https://github.com/1RB/cheki.git
cd cheki
docker-compose up -d

# API at http://localhost:3000/api/verify
# Self-hosting on an Ethiopian IP bypasses geo-blocks