KEZA sent Irembo their API guide. Before touching the portal, turn the guide into a one-page integration worksheet. It forces every question you will need answered, and it becomes the checklist for your mock and your endpoint.
KEZA API guide · excerpt (the two operations we need first)
POST /v1/auth/login
Content-Type: application/json
{ "username": "irembo-integration", "password": "<given by KEZA>" }
200 OK
{ "status": "SUCCESS",
"data": { "token": "<opaque token>", "tokenType": "Bearer", "expiresIn": 3600 } }
401 { "code": "INVALID_CREDENTIALS", ... }
GET /v1/eligibility?nationalId=<16 digits>&program=<PROGRAM_CODE>
Authorization: Bearer <token>
200 OK { "found": true,
"learner": { "nationalId", "firstName", "lastName", "district" },
"eligibility": { "status": "ELIGIBLE" | "NOT_ELIGIBLE", "programCode", "reasonCode" } }
404 { "found": false, "code": "LEARNER_NOT_FOUND", ... }
401 { "code": "UNAUTHORIZED", ... }
The full KEZA API reference lives in the Irembo documentation wiki: KEZA API reference, with the operations used in this course on the training endpoints page. You will come back to it in every lesson.
KEZA’s guide also lists synthetic test learners. Two of them follow us through the whole course: Aline Mukamana from Gasabo (1199880012345678), who is eligible and gets enrolled, and Eric Habimana from Huye (1199770098765432), who is refused. Mocks only ever contain synthetic people like them, never real citizens’ data.
The integration worksheet
| Worksheet line | KEZA eligibility (worked example) | Portal decision it drives |
|---|---|---|
| Where it is used | On the application form, before submission | Picks the adapter: form → FMAPPING |
| Direction | Fetch (read) | Call /fetch/sync; the mapping builds a read request |
| Operation | GET /v1/eligibility |
Method + path → endpoint URL |
| Inputs | nationalId, program (query) |
Map from payload fields nationalId, programCode |
| Auth | Login first: POST /v1/auth/login, token at data.token, sent as Authorization: Bearer, valid 3600 s |
Auth type USER_CREDENTIALS |
| Success | 200 with eligibility.status |
Note: NOT_ELIGIBLE is also a 200 |
| Failures | 404 LEARNER_NOT_FOUND, 401 UNAUTHORIZED | Each one becomes a mock rule |
| Test data | Aline Mukamana 1199880012345678 (eligible), Eric Habimana 1199770098765432 (not eligible), unknown ID 1190000000000009 |
One mock rule per person |
| Names | Mocks VICTOR_KEZA_LOGIN, VICTOR_KEZA_ELIGIBILITY; endpoint VICTOR_KEZA_ELIGIBILITY_FETCH |
Codes are permanent: choose carefully |
Your tech notes · Ask for the ugly cases
Partners document the happy path. Always ask: what does not found look like? invalid input? expired token? a business refusal? Is a refusal a 200 or a 4xx? Those answers decide your mock rules now and your response validation in Module 4.
In the KEZA guide the token is returned as {"status":"SUCCESS","data":{"token":"..."}}. Which token path must the endpoint use?
D. The path is read from the root of the login response: data.token. You will put it in tokenConfig.extractPath.
| Card | Answer |
|---|---|
| Your turn Fill the worksheet for KEZA’s GET /v1/learners/{nationalId} (same login). Then flip. |
Used on the form → FMAPPING · fetch · URL ends with /learners/{nationalId} · input = path variable from payload nationalId · auth USER_CREDENTIALS, token at data.token · success 200 profile · failures 404 LEARNER_NOT_FOUND, 400 INVALID_NATIONAL_ID, 401 · built in Lesson 2.1. |
← 1.2 Tour of the Integration Management Portal · 1.4 Your first mock: fake KEZA login + eligibility →