Platform API (/v1)
The API the MyChurch portal is built on. Church systems, head offices and partners use the same routes with a portal session or a scoped mc_ token.
Every route on this API lives under one base URL and answers JSON in the same envelope with real HTTP status codes. It is the contract we own and version, unlike the member app API, which is frozen to keep the shipped apps working.
https://uat-api.mychurch.co.ke/v1Authentication
Send one credential in the Authorization: Bearer header. The api accepts two kinds on /v1:
- A portal session JWT, issued by POST /auth/login and /auth/verify-otp to church users, head office users and Bitwise staff. It carries the scope, the role and (for the
userrole) the explicit permission list. It expires after the idle window and is renewed withPOST /auth/refresh. - A scoped API token that starts with
mc_. It belongs to one church, carries an explicit list of permissions and is stored only as a SHA-256 hash, so it cannot be shown again after it is issued. Tokens are issued per church by MyChurch support; revoked or expired tokens, and tokens of a church that is suspended or still on the previous MyChurch system, are refused. Use one for any server to server integration.
Member tokens from the app do not work here. See Authentication for every caller and credential side by side.
Scopes, roles and permissions
Scopes
| Field | Type | Required | Description |
|---|---|---|---|
| church | admin | user | token | No | A church's own staff. admin may do everything under church:*; user and mc_ tokens may do exactly what their permission list says. |
| head_office | head_office | No | A head office or subsidiary user. Read access over the churches in its subsidiary tree, plus head_office:* permissions such as report generation. |
| system | super_admin | support | finance | No | Bitwise staff. super_admin holds every permission; support and finance hold their seeded lists. |
A permission is a string scope:resource:action, for example church:members:view or church:collections:reconcile. Each reference page lists the permission every route checks. A missing permission answers 403 with a message that names it.
Most read routes also accept head_office:churches:view and system:churches:view, so head office and staff can look at a church without being one of its users. The reference pages say where.
Acting on a church
Church users and mc_ tokens always act on their own church; the church comes from the credential, never from the request. Head office and staff callers name the church on every church-level request with the X-Church header (or a ?church= query parameter), holding the church's uuid. A head office can only name churches under its own subsidiary tree; anything else answers 404. Without a church the api answers 400 choose a church first.
curl "https://uat-api.mychurch.co.ke/v1/members?status=active" \
-H "Authorization: Bearer $MYCHURCH_JWT" \
-H "X-Church: 11111111-2222-4333-8444-555555555555"Responses
Every response is the same envelope. success tells you which half is filled; meta appears on paged lists.
{
"success": true,
"data": [
{ "uuid": "0b6f4c1e-1111-4a2b-9c3d-000000000001", "name": "Jane Wanjiku", "status": "active" }
],
"meta": { "page": 1, "page_size": 25, "total": 1 }
}{
"success": false,
"error": "You don't have permission to do that."
}Status codes
| Field | Type | Required | Description |
|---|---|---|---|
| 200 | OK | No | The request worked. Deletes answer data {"status": "deleted"}. |
| 400 | Bad request | No | Malformed JSON, a missing church for head office or staff, or an unusable parameter. |
| 401 | Unauthenticated | No | No credential, an expired or revoked JWT, an unknown mc_ token, or wrong login details. |
| 402 | Payment required | No | The feature needs the premium plan (events, appointments, parking, merchandise, TV schedules, budgets and requisitions, advanced reports), or a money account holds too little for a withdrawal. |
| 403 | Forbidden | No | The credential lacks the permission, or the account or church is inactive, suspended or still on the previous MyChurch system. |
| 404 | Not found | No | No such route, or no such resource in the acting church. Another church's uuid is a 404, never a 403. |
| 405 | Method not allowed | No | The path exists with a different method. |
| 409 | Conflict | No | A duplicate or a state that blocks the change, for example a paybill short code already registered, or a paybill that collection accounts still use. |
| 422 | Validation failed | No | A field failed validation; error names the field and the rule. Also wrong, expired or exhausted verification codes and reset links. |
| 429 | Too many requests | No | A rate limit was hit. Back off and retry; see Rate limits. |
| 500 | Server error | No | Something failed on our side. The body never carries internals; retry later. |
Responses and errors compares this envelope with the member app one, and Rate limits explains the 429.
Lists, filters and exports
- Paged lists take
?page=(from 1) and?page_size=(default 25, at most 200) and returnmeta.page,meta.page_sizeandmeta.total. - Filters are flat query parameters:
qfor free text, thenstatus,from,toand the resource's own (each reference page lists them). - Ledgers kept per month (collections, money account ledgers, check-ins, outgoing SMS) are always read for a date window. Without
fromandto(YYYY-MM-DD) the api reads the current month. - Exports stream a file straight from a
GET, for example/v1/collection-transactions/export.csv. Large and formatted exports go through reports.
Pagination and exports has the details and examples.
Conventions
- Resources are addressed by uuid only:
/v1/members/{uuid}. Integer ids never appear. - Actions on a resource are
POST /v1/<resource>/{uuid}/<verb>, for example/v1/members/{uuid}/status. - Updates are
PUT; where a route says PUT,PATCHwith the same body is accepted too unless the reference says otherwise. - Money is a decimal number in Kenya shillings with two places. Phones are accepted as
07...,2547...or+2547...and returned as2547.... - Dates are
YYYY-MM-DD; timestamps are RFC 3339. - Every change is recorded in the church's audit log with the user or token that made it.
A first call
The church profile answers any signed-in caller of a church, so it is the quickest way to check a credential.
# Paste your token once (it starts with mc_):
export MYCHURCH_TOKEN="mc_your_token_here"
curl "https://uat-api.mychurch.co.ke/v1/church" \
-H "Authorization: Bearer $MYCHURCH_TOKEN"Then the rest
GET /v1/me to read their own scope, role and permissions.Reference
- Login and sessions:
/auth/*and/v1/me - Members:
/v1/members,/v1/children - Groups: departments, cell groups, affinity groups, meetings
- Services and attendance: services, check-ins, Sunday school, biometric devices, visitors
- Giving and paybills: collection accounts, the collection ledger, incoming payments, pledges, fundraisers, paybills, bank accounts
- Finance: money accounts, transfers, withdrawals, expenses, budgets, requisitions
- Reports and Imports
- Users and roles and Settings
Other resources
These follow the same conventions and are documented here as they are opened to integrations. Their prefixes:
- Content:
/v1/sermons,/v1/devotions,/v1/livestreams,/v1/tv-schedules,/v1/announcements,/v1/verses,/v1/social-media,/v1/content-categories - Messaging:
/v1/messaging(send, scheduled, outgoing, senders, signature, blocked numbers) - Engagement:
/v1/feedback,/v1/prayer-requests - Activities (premium):
/v1/events,/v1/event-positions,/v1/regions,/v1/buses,/v1/calendar,/v1/appointments,/v1/appointment-slots,/v1/classes,/v1/halls,/v1/merchandise,/v1/orders,/v1/parking - Head office:
/v1/head-office(overview, subsidiaries and the churches in the tree) - Staff only:
/v1/system/*(church registry, subscriptions, staff accounts, roles, security, legacy migration). Not available to church credentials.
Versioning
/v1 follows semantic versioning: new routes and new response fields arrive without notice, a breaking change only with a new major version and a migration window. Ignore fields you do not know. See the versioning policy and the changelog.