An API you do not have to ask for: how Membership treats developers

An association's member register is never the only system it runs. A competition platform wants to know who gets the member price, a booking system who gets through the door, the bookkeeping wants the invoices. How easy those things are to build decides a great deal about how much use the register is. Here is how we think about it.

The description comes from the code that enforces it

Every endpoint in Membership validates incoming requests against a schema. The schema is the thing that rejects a malformed request, so it knows the contract exactly. That is why the API description is generated from the same schema: the OpenAPI document at /api/v1/openapi.json is not a page somebody writes, it is read from the running deployment.

The difference sounds small and is not. Hand-maintained documentation goes stale the first time someone adds a field and forgets the page, and from then on it is worse than nothing, because a developer believes it. Ours cannot describe an endpoint that no longer behaves that way, because it reads the same object the server uses to decide.

It is machine-readable, so you can point a client generator straight at it and get a typed library in your own language without anyone hand-writing one.

The documentation is public, before you buy anything

Reading the API description takes no key, no account, no support ticket and no upgrade. That is deliberate. A developer evaluates a system on a Saturday evening, before anyone phones anyone, and if the description is only reachable after purchase then that evaluation never happens.

For the same reason the developer documentation is an ordinary public page. It also states what the API does not do, because that is information an integration's author needs before starting rather than after.

The association decides, not the developer

A connection begins when an administrator at the association generates a single-use pairing code and hands it to you. The code is exchanged for an API key that works for that one association. A developer never gets access because they asked for it, only because an association chose to give it.

The key can be revoked from either end. The association sees which systems are connected and can cut one off whenever it likes; the integration can disconnect itself when a user removes it on their side. Only a hash of the key is stored, and the association can see when it was last used. In practice: if a key leaks, it is one association's key, it shows up in a log, and it dies with one click.

The question is about membership, not about the person

A membership check answers whether an email address belongs to an approved member of that association, and which membership type they hold. It does not return a phone number, an address, a date of birth or any custom field, even though the register holds them.

That is a position rather than a missing feature. A competition system pricing an entry needs to know whether someone is a member. It does not need to know where they live. When an API hands over only what the question requires, an association does not have to trust every connected system as much as it trusts itself.

The same thinking runs through the rest of the product. A member's personal details sit behind a deliberate click even for staff, and every such look is written to an audit log. The API's narrowness is a continuation of that, not an exception to it.

The limits are stated in advance

Every endpoint has its own rate limit, returned in standard response headers. The batch lookup accepts 200 addresses at a time, because reconciling a whole roster should be a handful of calls rather than hundreds.

Errors arrive in the same envelope as successes, and a failed authentication usually means the connection was ended from the other side. Treat it as a connection that has closed rather than an error worth retrying.

What the API still cannot do

This belongs on the list, because an integration's author loses more time to an assumption that turns out wrong than to a gap they knew about. At the moment:

  • The API is read-only. Creating or updating a member from an external system is not possible yet.
  • There are no webhooks. Changes are discovered by asking, not by being told.
  • There is no sandbox. Development needs a real association and a real pairing code.
  • Response bodies are not yet described in the OpenAPI document. Requests are, because they have a schema; responses do not have one yet, and we are not going to hand-write them, since hand-written descriptions are the exact thing all of this avoids.

These are in order of work, and the order is considered: the permission model has to be settled before the first write endpoint exists, because afterwards every key already issued would silently be all-powerful.

Why this matters to us

A member register is rarely an association's only system. The easier it is to connect to, the less anyone copies member data by hand into a spreadsheet, and a hand-copied member register is the one that eventually goes stale and leaks.

If you are building something on Membership and something is missing or awkward, say so. Requests move the order more than you would guess, and the gaps above are written-down decisions rather than settled ones.


Published 15/09/2026. All articles · Lue suomeksi