How to integrate with Procountor: Two authorisation worlds, and one of them has a ceiling
Procountor is quick to call and slower to plan around. Two authorisation flows lead into the same system, and they do not reach the same endpoints: the one that runs without a person cannot touch anything Procountor guards with a second factor. That boundary is described in prose and named once across 192 operations, so it is usually found at runtime.


Two applications, and both take three to four days
The first thing to know about Procountor is not technical. You cannot start against it on the afternoon you decide to. Procountor issues credentials through a form, and the answer comes back by email and by text message after three to four days.
The form asks what your integration does, which objects it will move, in which direction and for which countries, plus the redirect address the flow will use. None of it is hard. All of it sits between you and your first call.
Production is a second application of the same kind, with its own wait, and the test account does not transfer into it. Our own engineer built against the interface while waiting for the first reply and could not run a single request until it arrived.
Asked what advice he would give someone starting tomorrow, the engineer who built this integration said one thing: “Request in advance the test environment, because it takes three to four days.” The wait runs whether your code is ready or not, so it is the one task that pays to start before everything else.
The request form, the three to four day turnaround and the split delivery by email and text message from Procountor’s testing environment request and getting started guide, checked 28 August 2026. The four day wait and the inability to test before it is our own engineer’s account of building it.
Two authorisation worlds, and only one runs unattended
Procountor offers an authorisation code flow for applications with a user in front of them, and a client credentials flow for everything that runs on its own. The second uses an API key as its credential, and that key is bound to one user, one company and one client application at the same time.
So far this is ordinary. The sentence that decides your architecture is the next one, and Procountor publishes it plainly: an access token from the client credentials flow cannot reach any endpoint that requires two-factor authentication, because those endpoints need a user who is actively present.
Your customer completes the login in a browser and picks the company.
An API key bound to one user, one company and one client application.
An integration may modify a purchase invoice on its own. Approving the payment for it needs a person with Procountor Key, which the unattended flow cannot supply.
Counted in the specification: across 192 operations, two-factor authentication is named once. Which endpoints require it is described in prose, so the boundary is found at runtime.
Procountor gives the example itself, and it is the one that matters commercially. An integration may modify a purchase invoice on its own. The payment for that invoice has to be approved by a person holding Procountor Key, which is issued to a natural person and cannot be handed to a service.
The expensive part is that the boundary is not machine readable. Across 192 operations in the published specification, two-factor authentication is named exactly once. Which endpoints sit behind it is described in prose, so a team that plans for full automation usually discovers the line at runtime.
POST /api/oauth/token HTTP/1.1Host: api.procountor.comContent-Type: application/x-www-form-urlencodedgrant_type=client_credentials&client_id=<client_id>&client_secret=<client_secret>&redirect_uri=<redirect_uri>&api_key=<api_key># The response carries the token and its lifetime:# { "access_token": "...", "expires_in": 3600 }
The access token is valid for one hour, after which the same exchange runs again. Note the redirect_uri in a call that redirects nobody: Procountor reuses the same address for both flows, so an application offering both has to tell them apart with the state parameter.
The flow, the binding of the key to user, company and client, the one hour token and the shared redirect address from Procountor’s machine to machine authentication, the two-factor boundary and the purchase invoice example from its certification checkpoints, both checked 28 August 2026. The count of 192 operations is our own, taken from the published specification.
Every connection belongs to one company
A Procountor user can belong to several companies, which on most systems means an identifier you resolve after authenticating and then carry in every request. Procountor settles it earlier. During login it shows a selection page of its own, and the connection that comes back is bound to the company the user chose.
That has a pleasant consequence and one constraint. The pleasant part is that there is nothing to discover afterwards and nothing to thread through your calls. The constraint is that one connection is one company, so a customer running three of them is three connections, each created by a person in a browser.
It also explains something you will notice if you read our documentation: Procountor is not on either of the two flow lists there, because it needs neither a company lookup nor a selection step of ours. The vendor already does it.
Six months on a refresh token, and five ways to lose it
The authorisation code flow returns an access token valid for one hour and a refresh token valid for six months. The refresh token does not rotate, so the value you store on day one is the value you still hold in month five.
What matters is the list of things that end it early, because four of the five are actions by somebody who has never heard of your integration.
| What happens | Who does it |
|---|---|
| The six months run out | Nobody, it is the clock |
| The user changes their password | Your customer |
| The user logs out through the logout endpoint | Your customer or your code |
| The user is removed from the company | Your customer's administrator |
| A hundred tokens exist for the same client, company and user | Usually your own code |
The last row is the one that catches teams out, and it is self-inflicted instead of a limit anyone reaches by growing. Requesting a fresh token on every connection attempt instead of reusing the stored one walks a tenant towards a hundred quietly.
In all five cases the consequence is the same, and it belongs in your design. The stored refresh token is invalid, and because Procountor keeps a person in the authorisation step, nothing can quietly renew it. Your customer authenticates once more. What that costs you is a path in your product for a connection that has gone cold, and a message that says so.
The six month validity and all five invalidation cases from Procountor’s certification checkpoints, section 3.2, checked 28 August 2026. That the token does not rotate is confirmed by our own engineer against the running integration.
One object carries seven kinds of document
Procountor does not model a sales invoice, a purchase invoice and an order as separate things. It models one invoice object with a type on it, and the type takes seven values. A sales invoice, a purchase invoice, both kinds of order, a travel invoice, a bill of charges and a periodic tax return are the same shape with a different label.
The ledger receipt does the same on a larger scale, with sixteen values including salary, employer contributions and a bank statement used as a receipt. Getting the type wrong produces a valid document of the wrong kind.
| Object | Values on its type | Examples |
|---|---|---|
| Invoice | 7 | Sales invoice, purchase order, periodic tax return |
| Ledger receipt | 16 | Journal, salary, employer contribution, VAT form |
Two smaller things belong in the same section because they reach the same schema. First, an id is unique inside one company and nowhere else, so two companies can hold invoices with identical ids. Procountor names the company and the resource id together as the pair that is unique across the system.
Second, updating an invoice requires an invoiceVersion, which is a timestamp carried as a string. You send back the value you received, unchanged, or the write is rejected. It is optimistic concurrency wearing a date.
Through the common data model none of that reaches your product: the seven document kinds arrive as the objects they actually are, and the identifier question is answered before you see the record.
Both type lists counted in the published specification, version 26.08. The id rule and the company plus resource pairing from Procountor’s request and response conventions, checked 28 August 2026. The invoiceVersion requirement is stated on the field itself in the specification.
The rate and its code arrive in separate lists
This one is not in any documentation, and it is the reason this section exists. Asking Procountor for tax rates returns a response containing two arrays. One holds the percentages. The other holds the tax codes. Nothing in the response says which code belongs to which percentage.
Most accounting systems hand you a tax rate and its code as one object, and most data models are built that way, ours included. Against Procountor that model cannot be filled from a single response, so the pairing has to be established another way before any of it is usable.
- A percentage
- A percentage
- A percentage
- A code
- A code
- A code
Nothing says which code belongs to which percentage. A model that pairs them cannot be filled from this response alone, which is the part that costs time.
Through Maesn it arrives as one list in the shared shape, with each entry carrying the rate or the code it came with. The relation stays unpublished, so nobody invents one.
The cost of this one does not show up in any estimate, because nothing announces it. You call an endpoint, you get a valid response, and only when you try to map it does the gap appear.
Connecting through the Procountor API with Maesn changes the shape but not the fact. Tax data arrives as one list instead of two, in the same form every other connected system uses, and each entry carries the rate or the code it came with. The relation is not published by Procountor, so nobody downstream invents one, and a use case that needs the pairing establishes it deliberately.
This section rests on our own implementation, not on published documentation. Procountor documents neither the split nor a key between the two lists, and we could not find one in the specification either. Reported here because it is cheaper to read than to rediscover.
Three events, and none of them on a document
Procountor publishes webhooks, and the list is short. Three event types exist: a payment was updated, a payment was deleted, a user was updated. Subscriptions are authenticated with HMAC over SHA512, and one webhook is allowed per event type.
For an accounting integration that reads accounts, contacts and tax rates, none of those three helps. Change detection is a read you schedule, and the interval is yours to choose.
Paging is thinner than the documentation suggests at first glance. Counted across the specification, 22 of 101 read operations carry paging parameters at all, in four different combinations, and the rest have none. Where paging exists there are two mechanisms, a cursor and a page number with a size that often defaults to fifty.
Our engineer added the practical half of that: some list endpoints return no total count, which he found on accounts. You can page through them, and you cannot tell in advance how far you have to go.
Procountor states that paging only works if the filtering and ordering stay constant between consecutive requests. A job that widens a filter halfway through a run does not return an error. It returns a page from a different result set.
The production request limit is 60 a second per client, and Procountor writes that exceeding it may result in suspending the service for that client. That is a firmer consequence than the usual rejected call, so it belongs in the design of the schedule instead of in the error handling.
Reading on a schedule across a catalogue of systems that each page differently is exactly the work that one way to filter and page removes. The loop you write once is the loop you point at the next system.
The three event types counted in the published specification, the HMAC and SHA512 rule, the paging mechanisms, the constant ordering requirement and the 60 requests a second from Procountor’s request and response conventions, checked 28 August 2026. The missing total count on accounts is our own engineer’s observation. What happens on exceeding the limit is not published, and we have not hit it.
What Maesn covers, and what stays with you
Everything above is real work, and most of it is the same work for every customer you connect. That is the part to do once.
| Handled here | Stays with you |
|---|---|
| The authorisation flow and the company selection | Which objects your use case needs |
| The one hour token and the six month refresh cycle | Telling a customer their connection needs re-authorising |
| Tax data returned as one list in the shared shape | Pairing a rate with its code, where your use case needs it |
| Contacts joined from two endpoints into one shape | The interval your schedule runs on |
| The document types resolved into real objects | Your own error handling and retries |
The role question in that column is genuinely yours. Procountor sorts contacts into companies and people, and neither carries a field saying which side of an invoice they are on. A matching rule written against a system with separate customer and supplier objects needs adjusting here.
And the objects available today are a smaller set than the system as a whole. Accounts, contacts and tax rates have been readable since July, with posting for booking proposals and expenses added in August. The rest of Procountor, including a payroll surface larger than most of its accounting one, is not part of the connection today.
The live scope and its dates come from our own engineer and from our integration documentation, checked 28 August 2026. Procountor releases monthly and publishes discontinuation dates for older versions in its release notes, so the version you build against deserves a second look later.
Frequently asked questions
Can a Procountor integration run without a person present?
How long does a Procountor refresh token last?
Why do two Procountor companies show the same record id?
How do I page through a Procountor list endpoint?
What happens if I exceed Procountor's request limit?
Which Procountor version should I build against?
Do I need a partner status before I can build on Procountor?

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.
Procountor splits its tax response in two, binds a connection to one company and stops the unattended flow at a second factor. The next system will draw every one of those lines somewhere else. Build against one interface and each difference turns into a field you read instead of a project you schedule.