All integrations

Automation & API Available

REST API & API-sleutels

The API is not a layer beside the product, it is the product. The web app uses it, the MCP server proxies onto it, and your script calls exactly the same endpoints.

What you need

  • Your own tenant hostname over HTTPS: the verified custom domain, or <slug>.<base domain>
  • The apikeys.personal.manage permission for a personal key, or apikeys.service_account.manage for a service account
  • A sense of which permissions the integration needs: scopes come from the same permission catalogue as roles
  • For the interactive reference: SCHAKL_API_DOCS_ENABLED must not be false (it is on by default)

How to connect it

  1. 1 Open the reference at https://<your-host>/api/docs (Swagger UI) or https://<your-host>/api/redoc. The document itself is at /api/openapi.json. Mind the path: everything sits under /api/, because that is the only prefix the edge routes to the API service.
  2. 2 Mint a personal key: Instellingen → Mijn account (Settings → My account), section API-sleutels (API keys). Fill in Naam (Name), for example n8n-automatisering, optionally pick a date under Verloopt op (Expires on), and tick under Scopes what the script needs. At least one scope is required.
  3. 3 Or mint a key that needs nobody's account: Instellingen → Service-accounts (Settings → Service accounts) → Service-account toevoegen (Add service account), then Nieuwe sleutel (New key). Such a key carries exactly its own scopes and keeps working after its creator leaves.
  4. 4 Copy the key straight away: schakl_<prefix>_<secret>. It is shown exactly once, because only a hash of the secret is stored; afterwards the API returns nothing but schakl_<prefix>_********.
  5. 5 Send it as Authorization: Bearer schakl_… or as X-API-Key: schakl_…, always to your own tenant hostname.
  6. 6 For n8n: one HTTP Request node per endpoint, with the key as a header credential. There is no separate n8n connector; it is the same API the app itself uses.
  7. 7 Building a real client, generate it from /api/openapi.json. The web app does exactly that with openapi-typescript, so a changed endpoint becomes a type error instead of a surprise.

A personal key or a service account

A personal key belongs to you and is capped by your live permissions on every request: demote the owner and the key shrinks with them. That is exactly what you want for a script acting on your behalf, and exactly what you do not want for the integration the agency runs on. That is what the service account is for: a shared principal tied to no person, with its own scopes, managed by an admin.

  • A key belongs to one organisation; on another hostname it is simply not found
  • Revoked, expired and unknown all answer with the same 401, never confirming that the key exists
  • An expiry date may sit at most 366 days out; leaving it empty means never expires, and revoking is then the kill switch

Why the reference lives under /api/

The edge routes exactly two prefixes to the API service: /api/ and /mcp. Everything else goes to the web app. So at FastAPI's default paths (/docs, /redoc, /openapi.json) you landed on the web app's 404: the documentation was not disabled, it was unroutable. It now sits under the prefix that does arrive, with no edge change on an existing install. If you would rather not serve it at all, set SCHAKL_API_DOCS_ENABLED to false. The document is still built in process, so the typed client and the MCP tool surface keep working.

The shape of the API

Plural nouns under /api/v1/<module>/<resource>. List endpoints take limit and offset, and count=false skips the total where you do not need it. Errors come back in one envelope, { error: { code, message, fields? } }, where message is an i18n key rather than a sentence to show your user. Every enabled module extends the same API and the same spec.

Permissions

Grant these to the role that manages this integration (Settings → Roles). Admin-only by default, and never to the client role.

  • apikeys.personal.manage Manage your own API keys: mint and revoke them yourself. Granted to admin and member by default, because such a key can never exceed its owner.
  • apikeys.service_account.manage Manage service accounts: shared keys tied to no employee. Admin only by default.

What it deliberately does not do

  • 600 requests per minute per key. Enough for automation, and a firm ceiling under a leaked key.
  • The secret is not stored, only its hash. Lost is lost: revoke it and mint a new one.
  • A key never grants more than its scopes, and a personal key never more than its owner may do at that moment. Permissions are granted in Instellingen → Rollen (Settings → Roles), not on the key.
  • The Laatst gebruikt (Last used) column lags: it is updated out of band so an API call never waits on it.
  • Outbound event webhooks do not exist yet. Reacting to a change today means polling, or an automation rule with the Webhook aanroepen (Call a webhook) action.
  • Bulk export over /impex needs its own permission (impex.export) on top of the entity's read permission; a key that may read clients cannot therefore download the client list.

Where to find it Instellingen → Mijn account (Settings → My account), section API-sleutels, for personal keys; Instellingen → Service-accounts (Settings → Service accounts) for integrations. The reference itself lives at https://<your-host>/api/docs.

Read the guide

More in this category

Other integrations