Integrations
Talks to the services you already use
Payments, domain registrars, DNS, Google Workspace and AI: every integration runs on your own account and your own keys, configured per organisation. Nothing routes through us, because there is no "us" — you run the install yourself.
- 21
- connectable
- 10
- categories
- 4
- on the roadmap
Payments
Let clients pay your invoice online; the payment lands as a payment line on the invoice itself.
In preparation
Stripe On the roadmap
The payment layer in schakl. names no provider: there is a protocol each provider fills in, a per-provider account resolver, and a callback address that names its own organisation. Stripe therefore arrives as an added package rather than a rebuild of the part that touches money. There is nothing to configure today; Mollie is the only implementation that exists.
Adyen On the roadmap
Agencies with enterprise clients ask for Adyen, and that is not a payment method but a different provider. Which is exactly why the payment layer in schakl. names no vendor: there is a protocol, a per-provider account resolver, and a callback address that names its own organisation. There is nothing to configure today; Mollie is the only connection that exists.
Not connectable yet. They are listed because the path to them already exists in the code, not because a date does.
Accounting
Push your invoices through to the package your accountant works in.
In preparation
Exact Online On the roadmap
There is no live Exact Online connection yet. What does exist today: every issued invoice and credit note downloads as UBL 2.1, exactly the file Exact Online imports. The seam a real connector plugs into is in place, but no adapter is installed.
Not connectable yet. They are listed because the path to them already exists in the code, not because a date does.
Domains & DNS
The registrar knows who pays for a domain, the zone knows where it points. schakl reads both.
Cloudflare
Zones, DNS and a redirect that exists
Connect a Cloudflare account per client and manage the zone from the domain record itself: nameservers, the live DNS table, exports and one domain-wide redirect that schakl. creates and reads back. A domain marked as a redirect is now an actual Cloudflare Redirect Rule. The Registrar list separately answers which domains you pay to renew, and may therefore invoice.
- An existing zone is adopted first, and only then created
- Read and edit DNS live, export as a zone file or CSV
- If somebody changes the redirect in Cloudflare's own dashboard, schakl. reports it
OXXA
The register: expiry, lock, nameservers
Reads your OXXA reseller register and puts expiry, transfer lock, autorenew, DNSSEC, the delegated nameservers and the registrant on the domain page. One action writes back: moving a domain's nameservers, which is what finishes the hand-off to Cloudflare. The first sync also shows which domains you are paying to renew that schakl. has no record of.
- Warns 60 days before expiry, and when a transfer lock is off
- Move nameservers from the domain page, with the Cloudflare pair one click away
- The first sync lays what you renew beside what schakl. knows, so what you pay for unknowingly stands out
Websites & monitoring
What runs on a client's site, and whether it is up. Both hang off the website, not off the domain.
WordPress
One password per website, four doors
One WordPress Application Password per website opens four surfaces on the same host: the ordinary REST API, WordPress 6.9's Abilities API, the MCP server where that plugin is installed, and Rank Math's own AI Visibility route. The last of those supplies the fifth marketing source: how often a brand is named and linked in AI answers.
- The connection hangs off the website, not off the organisation: every client site has its own password
- Five independent probes on verify, and none of them decides the verdict of the others
- Rank Math AI Visibility as a marketing source: score, mentions, citations, sentiment and average rank
Uptime Kuma
Is the site down, and since when
Uptime Kuma is the open-source monitor most agencies already run. Connect it and a monitor becomes a real record: with a client, a website, a profile, an activity trail and a place on the client page beside the domain and the hosting account it depends on. If the client's own Kuma sits behind a firewall it still works: the traffic simply runs the other way.
- Two kinds of connection: one we manage, and one that only reports to us
- Profiles instead of retyping the same settings three hundred times
- What we decided and what we last observed are stored apart, so drift is visible rather than silently overwritten
Google Workspace
Calendar, Drive, Gmail and Contacts, connected per organisation with your own OAuth credentials.
Marketing & analytics
The numbers you use to show a client what the work delivered.
Google Analytics 4
Sessions, channels and conversions per client
You link a GA4 property per client, on the client's own page. Every night the daily figures are pulled and stored in your own database, so the panel, the tab and the overview load without calling Google. The link runs on the Google connection a colleague already made, so there is no second login.
- Sessions, users, new users, key events, engagement and revenue, stored per day
- A first link backfills roughly 13 months of history
- Drill-downs by top page, channel, device, key event and referring source
Google Search Console
Clicks, impressions and positions per client
You link a Search Console property per client on the client's page, either a domain property or a URL prefix. Clicks, impressions, CTR and average position are stored per day, and the movers table shows which queries shifted against the previous period. The same Google consent as Analytics and Ads, so no extra login.
- Clicks, impressions, CTR and average position, stored per day
- Top queries, top pages and the biggest movers
- Search Console finalises data two to three days late; the nightly run re-pulls the last week
SE Ranking
Rankings, site audit, AI visibility
SE Ranking is the first marketing source that is not Google, and the connection shows it: it rides one API key for the whole agency instead of a per-employee grant. From a linked SE Ranking project, schakl. stores daily position figures for the dashboard and, per report, fetches the keywords, the latest site audit and AI search visibility.
- One key for the whole agency, stored encrypted under Instellingen → Marketing
- Stored per day: average position, top 3, top 10, top 30 and the number of ranking keywords
- Three report chapters: rankings, AI search visibility and the internal site audit
Google Ads
Spend, clicks and conversions per client
You link a Google Ads account per client and see spend, clicks, impressions, conversions and conversion value beside the Analytics and Search Console figures. If you work from a manager account (MCC), the client accounts under it are expanded in the picker. On top of the Google connection, Google Ads asks for one developer token belonging to your agency.
- Spend, clicks, impressions, conversions and conversion value, stored per day
- Campaign drill-down: the ten costliest campaigns of the period
- MCC hierarchies are expanded, up to 500 client accounts per manager account
Google Tag Manager
The client's container, here
Half of an agency's marketing work is making the measuring happen: a conversion on a new form, an event on a quote request, a tag for the campaign that starts on Monday. Until now all of it happened in a browser tab schakl. knew nothing about. Link a client's container and you see what is live, who put it there and when, and which change has been staged for three weeks without ever being published.
- Editing and publishing are two separate permissions: a key can prepare the measurement without broadcasting it
- schakl. writes in a workspace of its own, so unfinished work never lands in the client's own draft
- What you created stays recorded: which tag and trigger together are "quote requested", set up from here, on a date, by a person
AI & assistants
Your key, your provider, your permissions. With no provider configured there is no AI button anywhere.
Anthropic
Claude behind your AI features, on your key
You put your own Anthropic key into Instellingen → AI (Settings → AI); it is stored encrypted and never played back. Four features switch on and off independently: Assistent, Schrijfhulp, Urenhulp and Briefing & rapporten. A monthly token budget with a live meter keeps the spend visible.
- Your own key, encrypted per organisation, never played back
- Four independently switchable features; default model claude-opus-5
- Usage records counts only, never the text of a prompt or an answer
OpenAI
GPT-5, plus speech to text on Uren
The same core as every provider: your own key encrypted per organisation, four independently switchable features and one monthly budget with a meter. The built-in default model is gpt-5. OpenAI is also the provider that can do speech to text, so this is the choice that lights up the microphone beside Snel toevoegen (quick add) on Uren (Time).
- Your own key, stored encrypted, default model gpt-5
- Can also do speech to text: dictate into Snel toevoegen on Uren
- Audio has its own monthly budget in seconds, separate from the token budget
OpenAI-compatibel
Your own model, on your own server
Anything that speaks the OpenAI chat API on a base URL of your own: Azure OpenAI, Mistral, or an Ollama or vLLM in your own rack. The Basis-URL (base URL) field is mandatory for this provider; saving without it is a validation error on that exact field. Beyond that, the four features, the budget and the meter work exactly as they do with a cloud provider.
- Azure OpenAI, Mistral, a local Ollama or vLLM: anything speaking the OpenAI chat API
- Base URL is mandatory here, for example https://ai.example.com/v1
- Can also do speech to text, if your server implements that endpoint
Login & identity
Sign in with the account your agency already has, with two-factor verification on top.
Single sign-on (OIDC)
Sign in with your own identity provider
Your team signs in with the account your agency already has: Google Workspace, Microsoft Entra ID, Authentik, Keycloak or Auth0. You configure the whole thing in-app, with no environment variables and no restart. If you want to go further, you switch password login off for the entire organisation.
- Discovery URL, client ID and secret per organisation; PKCE is always on
- Test the connection before you make anything mandatory
- An operator break-glass, so a broken provider can never lock you out
Sms-gateway
SMS codes as a fallback beside your app
Two-factor verification works on its own: an authenticator app and ten single-use backup codes, with nothing to connect. Only the SMS fallback needs a gateway, and whoever runs the installation switches it on with one environment variable. Without it, the SMS option does not exist anywhere in the product.
- TOTP and backup codes need no integration; everyone enables them themselves
- One fixed JSON POST to a gateway of your own; Twilio, MessageBird or Spryng each need a small relay in front
- SMS always sits on top of the authenticator app, never instead of it
Storage & delivery
Where your files live and which server your mail leaves through.
E-mailbezorging
Every mail leaves under your own brand
You pick the transport you already pay for: your own SMTP server, or Brevo, SendGrid or SMTP2GO over their own HTTP APIs. Everything the app sends — an invite, a password reset, an invoice, a quote, a reminder, a monthly report — leaves wrapped in your logo, brand name and colour, with your signature underneath. The name schakl. appears nowhere in it.
- Your own SMTP, or Brevo, SendGrid and SMTP2GO over their HTTP APIs
- One HTML signature, appended at the send seam to every outgoing mail
- Invoice, quote, reminder and report in your own words, per language
S3-opslag
A named volume or your own S3 bucket
Files live on a Docker volume beside the database by default. Point the storage backend at s3 and the app writes new files to any S3-compatible bucket: Hetzner Object Storage, MinIO, Scaleway or AWS. Identical bytes cost one object per organisation, so the same signature logo on 500 received mails is one object rather than 500.
- Named volume or S3-compatible bucket, chosen at deploy time
- Files are addressed by their content: duplicates cost nothing after the first
- A nightly job folds legacy duplicates and reclaims unreferenced bytes
Automation & API
Anything the app can do, a script can too: one API, typed, with permissions per key.
MCP (Model Context Protocol)
Your own API as a toolset for AI clients
schakl. runs an MCP server at /mcp. Every /api/v1 operation is a tool there, generated from your own instance's OpenAPI spec and proxied in-process back to that same API. So a tool call travels exactly the same gate as the web app: hostname to organisation, RLS bound, permissions resolved.
- Every /api/v1 operation is a tool, named after the operation: list_companies, create_task, team_time_summary
- Keys are tenant-scoped, revocable and carry exactly the scopes you tick
- Connect in one line with claude mcp add --transport http
REST API & API-sleutels
One typed API, permissions per key
Everything the app does travels /api/v1: the web app never talks to the database directly, so there is no back door a script misses. The interactive reference sits on your own host at /api/docs, with the OpenAPI document at /api/openapi.json. You authenticate with an API key carrying exactly the permissions you tick.
- Swagger UI at /api/docs, ReDoc at /api/redoc, the document at /api/openapi.json
- Personal keys per employee, service accounts for integrations that keep running
- n8n is exactly this: an API key plus HTTP nodes, no separate connector needed
In preparation
Webhooks On the roadmap
Subscribing to events, with schakl. posting a payload to your URL on every change, is not possible yet. What does ship today: an automation rule can call a webhook on eight triggers, and a notification channel can push messages to a webhook URL. To react to anything else, you poll the API or use MCP.
Not connectable yet. They are listed because the path to them already exists in the code, not because a date does.
Your own keys
Every integration is configured per organisation and stored encrypted. Your agency uses its own account; a client who brings their own Cloudflare or registrar gets their own row. Nothing is ever picked for you.
No lock-in
Switching an integration off removes nothing that is already recorded. Payments that came in stay on the invoice; synced domains stay in your register. schakl stores what it decided and what it last observed in separate columns, so "somebody changed this in the provider's dashboard" shows up as visible drift instead of a silent overwrite.
Missing something?
The integration layer is a seam in the code, not a list: a second payment provider or registrar is one file, not a rebuild. Tell us what you need.