API Reference openapi.yaml

jamiio API

Build jamiio into your own software. Read and write communities, members, events, votes, funds and maintenance jobs over HTTPS with JSON.

Introduction

The API is HTTP and JSON, with 35 endpoints. Everything the jamiio apps do, you can do — there is no private API behind this one.

Base URL

https://api.jamiio.net/v1

Every path in this document is relative to that base. So /health means https://api.jamiio.net/v1/health.

Quick start

Check the service is up. This is the one call that needs no key:

curl https://api.jamiio.net/v1/health
{ "ok": true, "tables": 15 }

Then register a key and use it. Full steps below.

Authentication

There are two ways to call the API. Which one you want depends on whether a person is present.

MethodUse it when
API key Your system calls jamiio on its own — a sync job, a backend, a report. This is what you want for an integration.
Session token A signed-in person is using your app and acting as themselves.

A key acts as the person who created it, with the same permissions and no more. If they administer two communities, the key reaches both. If they are an ordinary member, the key is too.

Authentication steps

1. Create a jamiio account

Sign in at the jamiio app and join or start a community. A key can only reach communities its owner belongs to, so this decides what your integration can see.

2. Register a client

Give it a name you will recognise later.

curl -X POST https://api.jamiio.net/v1/clients \
  -H 'Authorization: Bearer YOUR_SESSION_TOKEN' \
  -H 'content-type: application/json' \
  -d '{ "name": "Billing sync", "scopes": ["read", "write"] }'

3. Save the secret

The response contains your credentials:

{
  "client": {
    "id": "jam_9f3c2a1b7e4d8055",
    "name": "Billing sync",
    "scopes": ["read", "write"]
  },
  "secret": "sk_2b91d4ff08c6a37e5401bd9e77aa3c62f0d18e4b96c5a237",
  "note": "Copy the secret now — it is not stored and cannot be shown again."
}

The secret is shown once. It is stored only as a hash, so nobody — including us — can recover it. If you lose it, revoke the key and register a new one.

4. Send both headers on every request

curl https://api.jamiio.net/v1/communities?mine=1 \
  -H 'x-jamiio-client: jam_9f3c2a1b7e4d8055' \
  -H 'x-jamiio-secret: sk_2b91d4ff08c6a37e5401bd9e77aa3c62f0d18e4b96c5a237'

That is the whole of it. There is no token exchange, no refresh, and nothing expires.

Scopes

ScopeAllows
readGET requests.
writePOST, PUT, PATCH and DELETE as well.

Ask for read only, unless you need to write. It is the default.

Enforced on every writing method. A read-only key attempting one is refused with 403 before the request reaches the endpoint — including POST /clients, so it cannot register itself a wider key.

Revoking a key

Takes effect immediately. There is no grace period.

curl -X DELETE https://api.jamiio.net/v1/clients \
  -H 'x-jamiio-client: jam_9f3c2a1b7e4d8055' \
  -H 'x-jamiio-secret: sk_...' \
  -d '{ "id": "jam_9f3c2a1b7e4d8055" }'

List your keys with GET /clients. Secrets are never included.

Requests

Send JSON, get JSON.

curl -X POST https://api.jamiio.net/v1/communities \
  -H 'x-jamiio-client: jam_...' \
  -H 'x-jamiio-secret: sk_...' \
  -H 'content-type: application/json' \
  -d '{ "name": "Riverside Gardens", "area": "Kileleshwa", "countryCode": "KE", "homes": 60 }'
{
  "community": {
    "id": "riverside-gardens",
    "name": "Riverside Gardens",
    "area": "Kileleshwa",
    "homes": 60,
    "members": 1
  }
}

Errors

Every error has the same shape:

{ "error": "That invitation has already been used, or has expired" }
CodeMeaningWhat to do
400Missing or malformed field.Fix the request.
401Missing, wrong or revoked credentials.Check both headers.
403Not yours.The key's owner does not have access.
404No such record.Check the id.
409Exists, but not in a state that allows this.A spent invite, a closed vote.
429Too many requests.Wait for Retry-After.

Branch on the status code. The message is written for people and may change.

Rate limits

Per key, in fixed one-minute windows.

RequestsPer minute
/health600
Reads120
Writes30
Votes20

Every response tells you where you stand:

RateLimit-Limit: 120
RateLimit-Remaining: 117
RateLimit-Reset: 41

Personal data

The API never returns another person's phone number, email, exact location or financial detail. You get a display name and a house number:

{ "name": "Wanjiru K.", "unit": "House 14" }

This applies to your integration too. There is no scope, parameter or account type that lifts it. Build accordingly: if you need to contact a resident, ask them, do not expect the API to hand them over.

Communities

GET/healthService check. No key needed.
GET/communitiesSearch, or fetch one by id
POST/communitiesCreate one. You become admin.
PATCH/communitiesUpdate one you administer
DEL/communitiesArchive. Refused while members remain.
GET/clientsList your API keys
POST/clientsRegister a key
DEL/clientsRevoke a key

Members and invites

GET/membershipsCommunities you belong to
POST/membershipsJoin
DEL/membershipsLeave
GET/invitesPreview one, or list those you sent
POST/invitesInvite one person. Single use, 7 days.
PATCH/invitesRedeem or revoke
GET/exitsRequests to leave
POST/exitsAsk to leave
PATCH/exitsApprove, refuse or withdraw
PUT/exitsCommittee vote
GET/profileYour own profile
PUT/profileSave it

An invite is for one named person, works once, and expires in seven days. It carries a three-word phrase the sender says out loud. A forwarded link shows different words, which is how a recipient knows it was not meant for them.

Events and voting

GET/proposalsThe notice board
POST/proposalsPropose something
PATCH/proposalsMove, postpone, cancel or publish
POST/votesCast or change a vote

One home, one vote. Voting again replaces your first vote rather than adding to the count. Tallies are counted from the votes on every read, so they cannot drift.

Money

GET/contributionsWhat a campaign raised and what it buys
POST/contributionsRecord a contribution
PUT/contributionsSet the target and spending plan

Amounts are integers in minor units. 2500 means 25.00 where the currency has two decimal places. Nothing is charged through the API — it records money that moved elsewhere.

Jobs

GET/jobsYour requests, or a trade's inbox
POST/jobsRaise a maintenance request
PATCH/jobsMove it on. History is kept.
GET/providersTrades covering a community
PUT/providersCreate or update a trade account