All integrations
VoiceDock

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

01

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.

02

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.

03

Register a request or a change

Through one UpdateConnector with a fixed field set, so the agent cannot compose a message Profit will reject.

04

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

connector-call.log
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 design

What 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.

The read, as the connector receives it
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

Bring 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.

Voice agents and AFAS Profit: GetConnectors, tokens and the real delay | VoiceDock