Versioning and stability
Two promises, one per surface. The member app API never breaks. The platform API changes only in ways semantic versioning allows, and says so.
Member app API and callbacks: frozen
Everything under /api/v1/ and /api/v2/, the unversioned /api/process-ussd/... and /api/biometric paths, and every callback URL registered with Safaricom or a bank, is frozen:
- Paths, HTTP methods and request field names stay as they are.
- Response bodies keep their fields, names and value formats, including
{status, message}with HTTP 200 on failure. - Member tokens and the way the shipped apps send the PIN keep working until the apps that need them are no longer in use.
- Account-number prefixes (
FR-,OP-,MP-,CLS-,CAR-,EV-,EVS-,MERCH-,CH-,QR-) and every church's collection account numbers keep their meaning.
What can change on the frozen surface: a fix where the old behaviour was plainly a defect that no client relied on (a crash that returned HTTP 500 now returns the empty list the app expects; a route that let one church's token act on another church now refuses). Each such difference is listed in the changelog. New fields may appear in responses; parse leniently and ignore fields you do not know.
Platform API (/v1, /auth, /webhooks): semantic versioning
The API is released as MAJOR.MINOR.PATCH:
- Patch: fixes that do not change a documented contract.
- Minor: additions. New routes, new optional request fields, new response fields, new enum values in fields documented as open.
- Major: anything that could break a correct client. Removing or renaming a route or field, changing a type, making an optional field required, tightening a permission.
A major change is announced in the changelog before it ships, with the date and what to change. The /v1 prefix stays; a future incompatible generation would live beside it, not replace it.
Writing a client that survives
- Ignore unknown fields in responses and unknown values in status-like fields.
- Identify records by
uuid, never by position or integer id. - Send only the fields you mean to change on
PATCH. - On the member app API, branch on
status; on the platform API, branch on the HTTP status and thensuccess.
New callback registrations
/webhooks/ paths listed in Callback URLs; both are answered by the same code.