Applicants who already hold a KEZA certificate skip the entry test. KEZA’s certificate registry uses HTTP Basic authentication. New idea: auth type BASIC.
KEZA API guide · the slice you need
GET /v1/certificates/{certificateNumber}
Authorization: Basic base64(username:password)
200 { "certificateNumber", "holder": { "nationalId", "fullName" }, "programCode", "issuedOn", "status" }
404 { "code": "CERTIFICATE_NOT_FOUND" }
401 { "code": "UNAUTHORIZED" }
1 · Request: GET /victor/keza/v1/certificates/{certificateNumber}
2 · Responses (the first matching rule wins)
Rule 1 · Valid certificate
| Match on | Key | Operator | Value | |
|---|---|---|---|---|
| If | Header | Authorization | equals | Basic dmljdG9yLWNlcnRzOkNlcnRAMjAyNg== |
| and | Path variable | certificateNumber | equals | KZ-CERT-2026-0001 |
Respond with 200 Body type json
{
"certificateNumber": "KZ-CERT-2026-0001",
"holder": {
"nationalId": "1199880012345678",
"fullName": "Aline Mukamana"
},
"programCode": "WEB_BASICS",
"issuedOn": "2025-12-15",
"status": "VALID"
}
Rule 2 · Unknown certificate
| Match on | Key | Operator | Value | |
|---|---|---|---|---|
| If | Header | Authorization | equals | Basic dmljdG9yLWNlcnRzOkNlcnRAMjAyNg== |
Respond with 404 Body type json
{
"code": "CERTIFICATE_NOT_FOUND",
"message": "No certificate with this number."
}
Otherwise — when no rule above matches
Respond with 401 Body type json
{
"code": "UNAUTHORIZED",
"message": "Basic credentials missing or wrong."
}
3 · Label
| Field | Value |
|---|---|
| Name | Victor KEZA Certificates |
| Code | VICTOR_KEZA_CERTIFICATES |
| Service | KEZA |
| Category | victor-course |
| Active | ✔ served by the mock server right away |
victor-certs:Cert@2026. You can compute it with printf 'victor-certs:Cert@2026' | base64.| Field | Value | |
|---|---|---|
| **Endpoint adapter *** | FMAPPING (fetch) |
locked after save |
| **Endpoint code *** | VICTOR_KEZA_CERTIFICATE_FETCH |
locked after save |
| **Endpoint url *** | http://mock-service-engine.apps:8000/victor/keza/v1/certificates/{certificateNumber} |
|
| **Endpoint type *** | FETCH (set by the adapter) |
|
| **Endpoint name *** | Victor KEZA Certificate Check |
|
| **Partner *** | KEZA |
locked after save |
| Active | ON |
|
| **Endpoint description *** | Victor course: verify a KEZA certificate (BASIC auth, path parameter). |
**Endpoint Mapping ***
{
"method": "GET",
"path": { "certificateNumber": certificateNumber },
"auth": {
"type": "BASIC",
"parameters": { "username": "victor-certs", "password": "Cert@2026" },
"tokenConfig": { "headerName": "Authorization", "tokenPrefix": "Basic" }
}
}
base64(username:password). No HTTP call, no caching."${KEZA_CERT_PASSWORD}", never payload fields.Authorization with prefix Basic.Secrets · training literal. Hard-coded only because KEZA is a training mock. In a real integration use the environment variable instead: Cert@2026 → "${KEZA_CERT_PASSWORD}" (the whole quoted string, nothing before or after; see Lesson 3.4).
Secrets · training value, not production practice
Clear-text value in this lesson: the Basic credentials
victor-certs/Cert@2026. The value is hard-coded only because this is a training sandbox with a fake partner. In real integrations, keep secrets out of the mapping: use an environment variable that the platform team defines per environment.Proper configuration:
"parameters": {"username": "${KEZA_CERT_USER}","password": "${KEZA_CERT_PASSWORD}"}The format must be exact: the whole JSON string is
"${NAME}"(quotes included, nothing before or after)."Bearer ${NAME}","$NAME"and"{{NAME}}"are not resolved: they are sent as plain text. An unquoted$NAMEor$env.NAMEis an undefined JSONata variable, so the key is dropped from the request. A variable that is not defined on the environment stops every call with 500 MISSING_ENVIRONMENT_VARIABLE (Lesson 6.3 shows it in Kibana).
HTTP 200 0.69 s captured on staging · 26 Sep 2026
1 · Request (curl)
curl -s -X POST "https://integration-gateway.staging.iremboinc.com/integration/v1/fetch/sync" \
-H "Authorization: Bearer $TOKEN" \
-H "portal: integration-management-portal" \
-H "Content-Type: application/json" \
-d '{
"endpointCode": "VICTOR_KEZA_CERTIFICATE_FETCH",
"callerId": "victor-course",
"requester": "victor-course",
"payload": {
"certificateNumber": "KZ-CERT-2026-0001"
}
}' | jq
2 · Real response
{
"status": true,
"responseCode": "integration_870000",
"responseMessage": "integration_870000",
"data": {
"id": "fe9523bd-9227-42bd-88c3-1161fad8caf6",
"endpointCode": "VICTOR_KEZA_CERTIFICATE_FETCH",
"callerId": "victor-course",
"response": "{\n \"certificateNumber\": \"KZ-CERT-2026-0001\",\n \"holder\": {\n \"nationalId\": \"1199880012345678\",\n \"fullName\": \"Aline Mukamana\"\n },\n \"programCode\": \"WEB_BASICS\",\n \"issuedOn\": \"2025-12-15\",\n \"status\": \"VALID\"\n}",
"adapterCode": "FMAPPING"
},
"timestamp": "2026-09-26T09:48:12.767412526",
"traceId": "6ab778bc3dd33cca328be7b3235ddc41"
}
3 · Decoded data.response
{
"certificateNumber": "KZ-CERT-2026-0001",
"holder": {
"nationalId": "1199880012345678",
"fullName": "Aline Mukamana"
},
"programCode": "WEB_BASICS",
"issuedOn": "2025-12-15",
"status": "VALID"
}
4 · What to notice
HTTP 500 0.64 s captured on staging · 26 Sep 2026
1 · Request (curl)
curl -s -X POST "https://integration-gateway.staging.iremboinc.com/integration/v1/fetch/sync" \
-H "Authorization: Bearer $TOKEN" \
-H "portal: integration-management-portal" \
-H "Content-Type: application/json" \
-d '{
"endpointCode": "VICTOR_KEZA_CERTIFICATE_FETCH",
"callerId": "victor-course",
"requester": "victor-course",
"payload": {
"certificateNumber": "KZ-CERT-2026-9999"
}
}' | jq
2 · Real response
{
"httpStatus": 500,
"exception": "PartnerException",
"responseCode": "PARTNER_ERROR_FETCH-VICTOR_KEZA_CERTIFICATE_FETCH",
"responseMessage": "{\n \"code\": \"CERTIFICATE_NOT_FOUND\",\n \"message\": \"No certificate with this number.\"\n}",
"fieldErrors": null
}
3 · What to notice
A BASIC endpoint returns PARTNER_ERROR with responseMessage {"code":"UNAUTHORIZED"}. You removed "tokenPrefix": "Basic" yesterday. Why does it fail?
A. Without a prefix the engine sends the raw token: Authorization: dmljdG9y…. The partner expects Basic dmljdG9y….
Your turn · your own Basic credentials
Copy the certificates mock to
/${your_first_name}/keza/v1/certificates/{certificateNumber}with your own training pair${your_first_name}-certs/Cert@2026: compute the header withprintf '${your_first_name}-certs:Cert@2026' | base64. Create${YOUR_FIRST_NAME}_KEZA_CERTIFICATE_FETCH(FMAPPING: a form reads it). Replace the variables before saving (Aline →ALINE_…,/aline/…).Done when: the valid certificate returns 200; with
tokenPrefixremoved you get PARTNER_ERROR with{"code":"UNAUTHORIZED"}; after you restore it, 200 again. In your evidence pack, write the two variables you would ask for in production ("${KEZA_CERT_USER}","${KEZA_CERT_PASSWORD}").
← 3.1 API key header (TOKEN): programme catalogue · 3.3 OAuth2 client credentials: scholarships →