
AFAS Profit
AFAS does not answer questions it was not asked
Connecting a voice agent to AFAS Profit is rarely blocked by engineering. It is blocked by the fact that AFAS only returns data through connectors that somebody has to publish first, and that somebody is usually not on the project yet.
Reading
GetConnector, per token
Writing
UpdateConnector, per token
What sets the date
Publishing the connector
What gets asked for
Four jobs, in the order people want them
Look up the caller among the relations
One filtered GetConnector call on the number. Fast enough to sit inside a conversation, provided the connector exists.
Read an order, work order or appointment
So the agent can answer the question the caller actually rang about, rather than take a message about it.
Register a request or a change
Through one UpdateConnector with a fixed field set, so the agent cannot compose a message Profit will reject.
Push the outcome back
So the office sees what was agreed without anybody retyping it from a transcript.
The constraint that bites
There is no general query API
AFAS exposes data through GetConnectors and accepts changes through UpdateConnectors. Both are defined inside Profit, and a token is scoped to the specific connectors it is allowed to use. So before an agent can look anything up, somebody with AFAS rights has to publish a GetConnector that returns exactly those fields and attach it to the AppConnector your token belongs to. That is a short job for an AFAS administrator and a long wait if nobody has asked them yet.
Plan the connector conversation first, not last. It sets the date more often than the code does.
Mechanics
- Authentication
- Authorization header, AfasToken plus a base64 value
- Reading
- GetConnector, scoped per token
- Writing
- UpdateConnector, scoped per token
- Large reads
- skip and take, under the AFAS Online 15-minute ceiling
In practice
A recognised call, end to end
inbound +31612345678 t+0.00s
[norm] normalised → 0612345678 t+0.00s
[afas] GET /connectors/VD_Relatie_OpNummer
filterfieldids=Telefoonnr
filtervalues=0612345678
[afas] 200 · 1 row · 410ms t+0.41s
[afas] GET /connectors/VD_Werkbon_Open
[afas] 200 · 1 row · 380ms t+0.79s
[agent] "About work order 2026-4471?" t+0.86s
token scope VD_Relatie_OpNummer, VD_Werkbon_Open
not in scope everything else, by designWhat gets built
A warm cache, and a narrow write path
Single-caller lookups go straight through, because one GetConnector call with a filter is fast enough to sit inside a conversation. Anything that would need a broad retrieval is prepared in advance by a background sync, which is where skip and take and the fifteen-minute ceiling become your problem instead of the caller's. Writes go through a specific UpdateConnector with a fixed field set, so the agent cannot invent a payload Profit will reject.
GET /profitrestservices/connectors/VD_Relatie_OpNummer
?filterfieldids=Telefoonnr
&filtervalues=0612345678
&operatortypes=1
&skip=0&take=1
Authorization: AfasToken <base64>
// take=1 on purpose. A connector that can return a thousand rows
// will eventually be asked to, on a call, by an agent that guessed.What we need from you
One person, and three decisions
An AFAS administrator, early
Somebody who can publish a GetConnector and manage the AppConnector token. Without them the project waits, whatever we do. This is the single item most worth arranging before the kickoff.
The exact fields, named
Per connector, the fields the agent may read. A connector that returns everything is a connector that will eventually return something a caller should not hear.
One UpdateConnector per write
With a fixed field set. Narrow beats flexible here, because the thing on the other end is a language model and Profit rejects what it does not recognise.
A token, and a rotation plan
Rotating it changes which connectors it reaches. Write down which ones before the first rotation rather than discovering it afterwards.
Questions we get first
Do you have an AFAS connector we can switch on?
No. The connectors live in your Profit environment, defined by your administrator or your AFAS partner, and they are specific to your configuration. What we build is the endpoint between the agent and those connectors.
Who has to be in the room?
Somebody who can publish a GetConnector and manage the AppConnector token. That is usually an internal AFAS administrator or the partner who implemented Profit. Without them the project waits, whatever we do.
What about the token?
It goes in the Authorization header as AfasToken followed by a base64 value, and it carries the connector scope. Rotating it means re-checking which connectors it still reaches, which is worth writing down before the first rotation rather than after.
Is AFAS fast enough for a live call?
For a filtered single-record lookup, yes, comfortably inside the thirty seconds a tool call gets. For anything that pulls a large set, no, and that work belongs in a scheduled sync rather than in the conversation.
Going deeper
The two articles underneath this page
Thirty seconds, one attempt
Why a tool call gets a single try, which lookups may hold up a conversation, and what the agent says while it waits.
Thirty seconds, one attemptKnowing who is calling before they say so
The number arrives in E.164 and your CRM holds six other formats. Normalisation, caching, and shared numbers.
Knowing who is calling before they say soBring us the awkward one
Send the system, its API documentation and one call you want to automate. On the intake call we will tell you whether the hard part is the code or the configuration, and which of the two sets the date.