How to integrate with SnelStart: Two authentication flows, and one account key
Nearly every write-up of this system describes two keys and stops there. That is the development flow. Production works differently: your customer signs in through a redirect SnelStart calls OAuth, the key is delivered to a callback rather than copied by hand, and you only get there through a partner review with a seven day observation period behind it.


The two keys are the development flow, not the whole story
Almost every description of this system, ours included until now, says SnelStart authenticates with two keys and stops there. That is true of the flow you build against and false of the one you ship on. SnelStart runs two separate authentication processes: development and test, which is the two keys below, and production, which is a redirect and has its own section further down.
The reason the second one is missing from the public record is worth knowing before you trust anything else you read about this API: SnelStart’s reference sits behind a login, so write-ups are reconstructed from the half that is visible.
For the development flow, two credentials is unremarkable. What matters is that no single person can produce both of them, and that changes what your onboarding screen can and cannot do.
The connection key belongs to your customer. They sign in to their own account, open Koppelingen, pick Maatwerk, agree to the scopes and save the value. It is per company, it is theirs to revoke, and it is the half you can collect inside your own product.
The subscription key belongs to you. It comes from a developer account you register once, and it identifies your application rather than any customer. No onboarding form can ask for it, because your customer does not have one and never will.
Created in their own SnelStart account after agreeing to the scopes. Per company.
One per application, from your own developer account. Not something a customer can hand you.
Only one of the two is a product step. The connection key can be collected in your own interface. The subscription key is yours, it is registered once, and no onboarding screen can ask a customer for it.
There is a third condition in front of both, and it is the one most likely to surface during a sales call rather than a build. Access is tied to the plan: Maesn’s connect guide states that your customer must hold the inZicht or inControle package to set up access at all. Those are the upper two packages on SnelStart’s own price list.
None of the development flow is a redirect, which is why this is one of the seven systems that can be connected without a hosted page while you build. That changes in production, and the section below is what it changes into.
Connection steps, the package requirement and both key sources from Maesn’s SnelStart connect guide, checked 13 August 2026. Package names cross-checked against SnelStart’s price list. Maesn’s documentation and SnelStart’s own pages write the brand “Snelstart”; quotations keep their source’s spelling.
Production is a redirect, and the key never touches a screen
Once you are an approved partner the handshake changes shape. SnelStart calls this flow OAuth, and it is worth taking that word loosely: it does not follow the standard pattern, and the clearest way to read it is as a separate process rather than as a variation on the two keys.
What you get from the partner application is an application short name, which behaves like a client id. Nothing in this flow can start without it. You send your customer to an activation URL built from it, carrying a reference key that behaves like a state parameter and a success URL for the end of the journey.
Your customer signs in to SnelStart and accepts the scopes your application asked for. Then the part that surprises people: SnelStart does not hand the connection key back through the browser. It posts it to a callback address you registered when you applied, together with the reference key you sent, so that the callback can be matched to the browser session. Your side acknowledges with a 201, and only then is your customer redirected onward.
POST https://auth.snelstart.nl/b2b/tokenContent-Type: application/x-www-form-urlencodedgrant_type=clientkey&clientkey=<connection key>-> { "access_token": "...", "token_type": "bearer","expires_in": 3599 }
This is the join between the two flows. In development the connection key is copied out of the interface, in production it arrives at the callback, and from that point the exchange is identical. Every API call afterwards carries the bearer token plus the subscription key in Ocp-Apim-Subscription-Key, and missing either one returns a 401.
The production flow, the callback behaviour, the token endpoint and the header pair from Maesn’s internal SnelStart authentication reference, checked 13 August 2026. SnelStart’s own documentation is behind a login, which is why this flow is absent from public write-ups of this API.
The access token lasts an hour. Because the connection key is stored per customer, a refresh is the same token request again rather than another trip through the redirect. Your customer signs in once, not hourly.
Through Maesn none of the above reaches your code. The activation link, the callback, the state matching and the storage of the connection key sit behind the connection, and what you hold is one account key. Unified authentication is what makes a system with two different handshakes look the same as a system with one.
The production key arrives after the build, not before
This is the part that belongs in a project plan, and it is missing from every description of this system we have published so far. On most platforms you register, you get keys, you build, and a marketplace listing is optional distribution you can add later. Here the order is inverted.
SnelStart’s developer portal states it plainly, in Dutch: “Ben je als ontwikkelaar klaar met het bouwen van de koppeling en gereed om een permanente maatwerk- of productiesleutel te ontvangen? Dan kun je de koppeling aanmelden om door ons te worden gecertificeerd.” Finish the integration, submit it, and a permanent key follows approval.
Maesn’s own documentation says what that gates. To use the interface in production, “you must become an official Snelstart Partner. Once approved, your application gains access to live customer environments (beyond the default test company).” Until that approval, a fully working integration reaches exactly one company, and it is not a customer’s.
The clock matters too. A development subscription is free and valid for 90 days with limited calls. If your build slips past that window, the key you have been testing with stops being the key you have.
And there is a step between submitting and going live that is easy to miss when you plan backwards from a launch date. When you tell SnelStart’s partner manager that the integration is ready, a seven day observation period begins. During that week the integration has to make at least 150 calls without producing too many errors.
That is a requirement you have to arrange rather than wait out. A hundred and fifty calls in a week is not much traffic, but it is more than an idle integration produces, so somebody has to drive it deliberately. This is the point in the process where Maesn steps in with you rather than watching.
Certification wording from SnelStart’s developer portal, the partner requirement, the 90-day validity and the one-time production fee from Maesn’s connect guide, both checked 13 August 2026. Certification here is SnelStart’s word for SnelStart’s process.
Three of the four writable objects have no read switched on yet
Counted across the 30 systems in this catalogue, SnelStart is the only one where Maesn has more object types switched on for writing than for reading: four create against three read. That sounds like an advantage and is mostly a warning.
What it describes is our own enablement rather than a shape SnelStart imposes. Booking proposals, credit notes and files are switched on for writing, and their reads are marked available on request rather than unavailable. Contacts is the single object enabled on both sides today. So there is no round trip for three of your four writes right now, and nothing you post can be fetched back and compared with what you meant to send until those reads are switched on.
- Booking proposalsNo read
- Credit notesNo read
- FilesNo read
- ContactsReadable
Accounts, Contacts, Tax rates
Accounts and tax rates are what a booking proposal has to name correctly, so the readable side is mostly the coding context for the writable side.
Three writes have no round trip. The response to the request is the only confirmation you will get, which puts the weight on validating the payload before it leaves rather than reconciling afterwards.
| Object | Read | Write | Systems with the write |
|---|---|---|---|
| Booking proposals | on request | yes | 10 of 30 |
| Credit notes | on request | yes | 2 of 30 |
| Files | on request | yes | 4 of 30 |
| Contacts | yes | yes | common |
| Accounts | yes | on request | common |
| Tax rates | yes | no | common |
Counted from the generated coverage data, checked 13 August 2026. On request means not switched on by default rather than unavailable, which is the distinction that matters in this table: only Tax rates create is a plain no. Credit notes create is supported on two of the 30 systems and Files create on four, so two of the three objects here are among the rarer capabilities in the catalogue rather than gaps.
The practical consequence is where your effort goes. On a system with a full round trip you can write optimistically and reconcile later. Here the response to the request is the confirmation, so validation belongs in front of the call. Unified error handling is what makes that failure legible in the same shape as every other system, instead of a vendor-specific rejection you have to learn to read.
A booking proposal states its tax twice
The object you most often write is also the one with the strictest payload rule. A booking proposal carries tax information at the booking level and again on every individual line, both are mandatory, and the two representations have to agree. A mismatch is rejected rather than reconciled.
That is internal accounting logic surfacing in an interface rather than an oversight. It also explains what the readable side of this system is for: accounts and tax rates are precisely the reference data you need in order to state the pair correctly. The three readable objects are the coding context for the four writable ones.
{"tax": { "rate": 21.0, "amount": 21.00 },"lines": [{ "amount": 100.00,"tax": { "rate": 21.0, "amount": 21.00 } }]}
The shape is the point rather than the field names, which differ per payload: state the tax once at booking level and once per line, and keep them consistent. Through Maesn the duplication is produced from a single normalised structure.
The two-level rule reads cleanly while every line carries tax. Introduce lines that carry none, and stating the same thing at both levels stops being a copy of one value and turns into a question about what the booking level should now say. This is the part of the payload teams most often get wrong on the first attempt, so it is worth building a case for it before you meet it in production.
The double representation and its validation behaviour are documented in Maesn’s material for this system, checked 13 August 2026. SnelStart’s own reference is behind a registered account and published in Dutch, so the field-level specimen above is illustrative of the rule rather than copied from it.
Which objects and operations are actually enabled, and which of the 37 are marked on demand, is listed object by object on the SnelStart API page rather than repeated here.
A country is an identifier, and the list can change
Objects here are fragmented in a way that costs calls. A contact does not carry a country code, it carries a country identifier that points at a separate record. Getting from that identifier to something you can display or store means another request.
The part that turns a lookup into a design decision is that the list is not fixed. Countries can be created, changed and deleted, so treating the mapping as a constant you import once will drift. A cache is the right answer and it needs a refresh policy, not a seed script.
This is the ordinary case for reference data across accounting systems, and it is the reason a shared shape exists at all. Through the common data model the identifier is resolved before the object reaches you, so a contact arrives with the same country representation it would have on any other connected system.
GET /contacts -> { "countryId": "..." }GET /countries/{id} -> { "code": "NL", ... }# one contact, two calls, and the second# result is not safe to cache forever
Fetching a page of contacts this way is the classic N+1: one call for the list and one per distinct country. Resolving and caching centrally is what removes it.
Nothing calls you, and the test company is the default
No object in this system carries a native event. Eight of the 30+ connected systems send something, and this is not one of them, so there is no subscription to register and no delivery to verify. Staying current is a scheduled read on the same filters and paging you use everywhere else.
In the event model that is the pull half doing all of the work. A pull catches up after an outage, which a push does not, and the interval is your decision rather than a constraint the vendor sets.
One caveat specific to this system is worth stating before you tune anything. While you are on a development key you are reading the default test company, so whatever you measure about volume, timing and page sizes is measured against data that is not your customer’s. Treat those numbers as a smoke test rather than a baseline.
What Maesn covers, and what stays with you
What we take off the list:
- The token lifecycle. The exchange, the hourly refresh and the storage of both keys per tenant happen behind the connection, so your code holds one account key and no timers.
- The reference resolution. Country identifiers and the other fragmented lookups are resolved before objects reach you, which is where the N+1 would otherwise live.
- The duplicated tax. One normalised booking structure goes in and the two representations this system requires are produced from it, consistently.
What stays with you, and the first two are not engineering problems:
- Partner approval and the production key. The application and the submission are filed in your name, and no interface in front of them shortens the review, so the calendar time belongs in your plan. You do not walk it alone though: we supply the callback address the application asks for, help you cut the scope list down to what your endpoints actually need, and drive the traffic the observation week requires.
- Your customer’s package. Access needs inZicht or inControle. That is a question for your qualification call, not your backlog.
- What a write means. We can make a rejected booking proposal legible, and we cannot make an unreadable object readable. Where there is no round trip, the decision about what to record on your side is yours.
Frequently asked questions
How do I enable access to SnelStart for an integration?
Does SnelStart support OAuth?
What is the SnelStart observation period?
What does a SnelStart integration cost to put into production?
Why does my integration only see one company?
Can I read back a booking proposal I created in SnelStart?
Why does my booking proposal fail validation?
Why does a SnelStart contact return a country identifier instead of a country code?

QuickBooks Online Webhooks: Events, Retries and Recovery
QuickBooks Online webhooks cover 29 entity types and expect HTTP 200 in three seconds. Why Intuit still asks you to poll change data capture.
Lennart Svensson · 25 Aug 2026
Lexware Office Pagination: The 406 and One Page Size
Lexware Office validates the page size and rejects a bad one with 406, the same code it uses for an unsupported media type. What that means for your read loop.
Lennart Svensson · 20 Aug 2026
How to Integrate with DATEV Rechnungswesen: One Connection
One connection carries reading and writing in DATEV Rechnungswesen, on a two-year token. Which objects travel in which direction is the real decision.
Lennart Svensson · 17 Aug 2026Build once on the Unified API.
SnelStart approves before it issues a production key, BuchhaltungsButler meters ten uploads a minute and Xero meters what you read. Build against one interface and each of those becomes a row in a table rather than a project.