MyChurchDocs

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.

Base URL
https://uat-api.mychurch.co.ke/v1

Authentication

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 user role) the explicit permission list. It expires after the idle window and is renewed with POST /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

FieldTypeRequiredDescription
churchadmin | user | tokenNoA church's own staff. admin may do everything under church:*; user and mc_ tokens may do exactly what their permission list says.
head_officehead_officeNoA head office or subsidiary user. Read access over the churches in its subsidiary tree, plus head_office:* permissions such as report generation.
systemsuper_admin | support | financeNoBitwise 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.

A head office user reading a church's members
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.

200 OK
{
  "success": true,
  "data": [
    { "uuid": "0b6f4c1e-1111-4a2b-9c3d-000000000001", "name": "Jane Wanjiku", "status": "active" }
  ],
  "meta": { "page": 1, "page_size": 25, "total": 1 }
}
403 Forbidden
{
  "success": false,
  "error": "You don't have permission to do that."
}

Status codes

FieldTypeRequiredDescription
200OKNoThe request worked. Deletes answer data {"status": "deleted"}.
400Bad requestNoMalformed JSON, a missing church for head office or staff, or an unusable parameter.
401UnauthenticatedNoNo credential, an expired or revoked JWT, an unknown mc_ token, or wrong login details.
402Payment requiredNoThe 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.
403ForbiddenNoThe credential lacks the permission, or the account or church is inactive, suspended or still on the previous MyChurch system.
404Not foundNoNo such route, or no such resource in the acting church. Another church's uuid is a 404, never a 403.
405Method not allowedNoThe path exists with a different method.
409ConflictNoA duplicate or a state that blocks the change, for example a paybill short code already registered, or a paybill that collection accounts still use.
422Validation failedNoA field failed validation; error names the field and the rule. Also wrong, expired or exhausted verification codes and reset links.
429Too many requestsNoA rate limit was hit. Back off and retry; see Rate limits.
500Server errorNoSomething 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 return meta.page, meta.page_size and meta.total.
  • Filters are flat query parameters: q for free text, then status, from, to and 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 from and to (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, PATCH with 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 as 2547....
  • 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

If that works, every route your token's permissions allow will too. A person signed in with a session JWT can also call GET /v1/me to read their own scope, role and permissions.

Reference

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.