Minors must register their guardians. The form has a repeater (one row per guardian) but KEZA accepts one guardian per call. New idea: iteration: one push request makes one partner call per row.
KEZA API guide · the slice you need
POST /v1/enrollments/{enrollmentId}/guardians (one guardian per call)
{ "fullName", "relationship", "phone" }
201 { "guardianId", "enrollmentId", "fullName", "relationship" }
1 · Request: POST /victor/keza/v1/enrollments/{enrollmentId}/guardians
2 · Responses (the first matching rule wins)
Rule 1 · Guardian registered
| Match on | Key | Operator | Value | |
|---|---|---|---|---|
| If | Header | Authorization | equals | Bearer keza-victor-token-7f3a |
| and | Body | — | raw JSONPath | $.fullName |
Respond with 201 Body type jsonDynamic response ON
{
"guardianId": "GRD-{{randomValue length=5 type='NUMERIC'}}",
"enrollmentId": "{{request.path.enrollmentId}}",
"fullName": "{{jsonPath request.body '$.fullName'}}",
"relationship": "{{jsonPath request.body '$.relationship'}}"
}
Rule 2 · Invalid guardian
| Match on | Key | Operator | Value | |
|---|---|---|---|---|
| If | Header | Authorization | equals | Bearer keza-victor-token-7f3a |
Respond with 422 Body type json
{
"code": "VALIDATION_ERROR",
"message": "fullName is required."
}
Otherwise — when no rule above matches
Respond with 401 Body type json
{
"code": "UNAUTHORIZED",
"message": "Missing or invalid bearer token."
}
3 · Label
| Field | Value |
|---|---|
| Name | Victor KEZA Guardians |
| Code | VICTOR_KEZA_GUARDIANS |
| Service | KEZA |
| Category | victor-course |
| Active | ✔ served by the mock server right away |
| Field | Value | |
|---|---|---|
| **Endpoint adapter *** | PMAPPING (push) |
locked after save |
| **Endpoint code *** | VICTOR_KEZA_GUARDIANS_PUSH |
locked after save |
| **Endpoint url *** | http://mock-service-engine.apps:8000/victor/keza/v1/enrollments/{enrollmentId}/guardians |
|
| **Endpoint type *** | PUSH (set by the adapter) |
|
| **Endpoint name *** | Victor KEZA Guardians |
|
| **Partner *** | KEZA |
locked after save |
| Active | ON |
|
| **Endpoint description *** | Victor course: one partner call per guardian row (iteration). |
**Endpoint Mapping ***
(
$row := guardians[$$.CURRENT_ITERATION];
{
"method": "POST",
"iterateOver": "guardians",
"iterationResponseKey": "guardianResults",
"path": { "enrollmentId": enrollmentId },
"body": {
"fullName": $row.fullName,
"relationship": $row.relationship,
"phone": $row.phone
},
"auth": {
"type": "USER_CREDENTIALS",
"baseUrl": "http://mock-service-engine.apps:8000",
"parameters": {
"authPath": "/victor/keza/v1/auth/login",
"bodyTemplate": { "username": "irembo-integration", "password": "Keza@2026" }
},
"tokenConfig": {
"storageKey": "VICTOR_KEZA_TOKEN",
"headerName": "Authorization",
"tokenPrefix": "Bearer",
"expiryBuffer": 300,
"extractPath": "data.token"
}
}
}
)
$$.CURRENT_ITERATION is the row index the engine adds to the payload (0, 1, …). Wrapping the mapping in ( … ) lets you define $row once.Secrets · training literal. Hard-coded only because KEZA is a training mock. In a real integration use the environment variable instead: Keza@2026 → "${KEZA_PASSWORD}" (the whole quoted string, nothing before or after; see Lesson 3.4).

Iteration mapping in the portal editor
The mapping test below is run with "CURRENT_ITERATION": 1. Which guardian will the body contain?
HTTP 200 captured on staging · 26 Sep 2026
1 · Request (curl)
curl -s -X POST "https://integration-gateway.staging.iremboinc.com/integration/v1/endpoints/VICTOR_KEZA_GUARDIANS_PUSH/mapping/test" \
-H "Authorization: Bearer $TOKEN" \
-H "portal: integration-management-portal" \
-H "Content-Type: application/json" \
-d '{
"applicationNumber": "C260926081900VICTR5",
"enrollmentId": "ENR-2026-0107",
"guardians": [
{
"fullName": "Jeanne Uwase",
"relationship": "MOTHER",
"phone": "0788111222"
},
{
"fullName": "Paul Nkurunziza",
"relationship": "UNCLE",
"phone": "0788333444"
}
],
"CURRENT_ITERATION": 1
}' | jq '.data'
2 · What the engine would send
{
"method": "POST",
"iterateOver": "guardians",
"iterationResponseKey": "guardianResults",
"path": {
"enrollmentId": "ENR-2026-0107"
},
"body": {
"fullName": "Paul Nkurunziza",
"relationship": "UNCLE",
"phone": "0788333444"
},
"auth": {
"type": "USER_CREDENTIALS",
"baseUrl": "http://mock-service-engine.apps:8000",
"parameters": {
"authPath": "/victor/keza/v1/auth/login",
"bodyTemplate": {
"username": "irembo-integration",
"password": "Keza@2026"
}
},
"tokenConfig": {
"storageKey": "VICTOR_KEZA_TOKEN",
"headerName": "Authorization",
"tokenPrefix": "Bearer",
"expiryBuffer": 300,
"extractPath": "data.token"
}
}
}
3 · What to notice
CURRENT_ITERATION yourself.HTTP 200 1.10 s captured on staging · 26 Sep 2026
1 · Request (curl)
curl -s -X POST "https://admin-gateway.staging.iremboinc.com/integration/v1/push/sync" \
-H "Authorization: Bearer $TOKEN" \
-H "portal: administration-management-portal" \
-H "Content-Type: application/json" \
-d '{
"endpointCode": "VICTOR_KEZA_GUARDIANS_PUSH",
"callerId": "victor-course",
"requester": "victor-course",
"applicationNumber": "C260926081900VICTR5",
"payload": {
"applicationNumber": "C260926081900VICTR5",
"enrollmentId": "ENR-2026-0107",
"guardians": [
{
"fullName": "Jeanne Uwase",
"relationship": "MOTHER",
"phone": "0788111222"
},
{
"fullName": "Paul Nkurunziza",
"relationship": "UNCLE",
"phone": "0788333444"
}
]
}
}' | jq
2 · Real response
{
"status": true,
"responseCode": "PUSH_SYNC",
"responseMessage": "PUSH_SYNC",
"data": {
"id": "c7d363fa-8d52-47c4-b1f7-57fb6b809348",
"endpointCode": "VICTOR_KEZA_GUARDIANS_PUSH",
"callerId": "victor-course",
"message": "{\"guardianResults\":[{\"guardianId\":\"GRD-21804\",\"enrollmentId\":\"ENR-2026-0107\",\"fullName\":\"Jeanne Uwase\",\"relationship\":\"MOTHER\"},{\"guardianId\":\"GRD-53306\",\"enrollmentId\":\"ENR-2026-0107\",\"fullName\":\"Paul Nkurunziza\",\"relationship\":\"UNCLE\"}]}",
"adapterCode": "PMAPPING",
"applicationDetails": "{\"guardianResults\":[\"\",\"\"]}"
},
"timestamp": "2026-09-26T09:51:44.604781739",
"traceId": "6ab779904ec90e524a7bbea0620e1404"
}
3 · Decoded data.message
{
"guardianResults": [
{
"guardianId": "GRD-21804",
"enrollmentId": "ENR-2026-0107",
"fullName": "Jeanne Uwase",
"relationship": "MOTHER"
},
{
"guardianId": "GRD-53306",
"enrollmentId": "ENR-2026-0107",
"fullName": "Paul Nkurunziza",
"relationship": "UNCLE"
}
]
}
4 · What to notice
guardianResults has one answer per row, in order.applicationDetails shows ["",""]: one empty entry per call, because the mapping has no response.transform. Read the answers in message.
One guardians push, two partner calls
Gotcha · Iteration rules
- Push (PMAPPING) only.
iterationCount(a fixed number) wins overiterateOver.- If
iterateOverdoes not name a list, you get a single call.- For files inside a repeater, use the
…Fromrepeatermarkers (lowercase r) from Lesson 5.1.
The repeater has 3 rows, but KEZA received 3 calls with the first guardian each time. What is the likely bug?
B. Three calls means iteration worked; identical bodies mean the body ignores the current index.
Your turn · count the calls
Create
${YOUR_FIRST_NAME}_KEZA_GUARDIANS_PUSH(PMAPPING) on your copy of the guardians mock. Replace the variables before saving (Aline →ALINE_…,/aline/…). Push three guardians, then add"iterationCount": 2and push again with a new application number.Predict both results first. Done when:
guardianResultshas 3 entries, then 2 (iterationCount wins). Run the mapping test with"CURRENT_ITERATION": 2and confirm the body holds the third guardian. Remove iterationCount afterwards.
← 5.1 Send files: attachment markers · 6.1 Read requests and traces →