How to Integrate with the Twinfield API

Developer guide to integrating with the Twinfield API. Covers OAuth, cluster routing, SOAP requests, rate limits, and the partner certification process.

Kateryna PoryvayKateryna Poryvay

Kateryna Poryvay · Growth Marketer, Apideck

10 min readView as .md

Reviewed by Saurabh Rai, Developer Relations Engineer

How to Integrate with the Twinfield API

Twinfield is the cloud accounting platform Wolters Kluwer acquired in 2011 to anchor its European tax and accounting suite. In the Netherlands it sits at the upper end of the SMB and mid-market segment, alongside Exact Online and AFAS, and it has meaningful presence in the UK through Wolters Kluwer's CCH ecosystem. If your product serves Dutch accounting firms, mid-sized businesses with multi-entity setups, or any customer that lives inside the WK financial suite, you will end up integrating with Twinfield.

This guide walks through the integration end to end: how OAuth works with the Wolters Kluwer identity platform, why you need to resolve a cluster URL before you can call anything useful, what SOAP services you will actually use, where rate limits hit a non-certified app first, and what the certification process costs in time and effort.

Auth note: Twinfield uses OpenID Connect on top of OAuth 2.0 for authentication, but the API itself is primarily SOAP-based with XML payloads. You combine an OAuth access token with a SOAP header that includes a CompanyCode. Standard REST patterns do not apply.

Prerequisites

Before you start:

  • A Twinfield account with developer portal access. You can register at developers.twinfield.com and create an OAuth client.
  • A backend service that can hold a client secret. The authorization code flow is the only sensible option for a production server-to-server integration.
  • A working knowledge of SOAP and XML parsing. The API does not return JSON.
  • A clear answer to whether you are building for a single organisation (one accountancy firm) or for many. The OAuth consent flow runs per organisation user.

Step 1: Register an OAuth client in the developer portal

Log into the Twinfield developer portal and create a new application. You will get:

  • A Client ID
  • A client secret (only shown once; copy it now)
  • A redirect URI you control on your side

Register the redirect URI exactly as your app will send it, including the trailing slash or absence of one. The token endpoint will reject a request where the redirect URI does not match byte-for-byte. This trips up almost every first integration.

Twinfield supports two OAuth flows: implicit and authorization code. Use the authorization code flow with the offline_access scope. Implicit flow exists for native and JavaScript-only clients, and the lack of a refresh token in that flow is a hard ceiling. Access tokens last 12 hours in implicit flow and 1 hour in code flow, and without offline_access you cannot extend them without sending the user back through the consent screen.

The full set of scopes you almost always want for a server-side accounting integration:

openid twf.user twf.organisation twf.organisationUser offline_access

The twf.organisationUser scope is mandatory for login. The offline_access scope is required for refresh tokens. Without it, you are stuck redoing the consent flow every hour.

Step 2: Walk a user through the authorization flow

Redirect the user to the Twinfield authorize endpoint:

https://login.twinfield.com/auth/authentication/connect/authorize
  ?client_id=YOUR_CLIENT_ID
  &response_type=code
  &scope=openid+twf.user+twf.organisation+twf.organisationUser+offline_access
  &redirect_uri=YOUR_REDIRECT_URI
  &state=RANDOM_STATE
  &nonce=RANDOM_NONCE

After the user logs in and consents, Twinfield redirects to your callback with a code and the original state. Verify the state, then exchange the code at the token endpoint:

POST https://login.twinfield.com/auth/authentication/connect/token
Authorization: Basic BASE64(CLIENT_ID:CLIENT_SECRET)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=THE_CODE_YOU_RECEIVED
&redirect_uri=YOUR_REDIRECT_URI

The response contains an access token, an ID token, an expires_in value (3600 seconds for the auth code flow), and a refresh token. Store all of these against the user record.

A note on refresh token lifetime: Twinfield documents refresh tokens as valid for 788,940,000 seconds, or roughly 25 years. In practice, plan for them to fail earlier than that. If a user changes password, has their account disabled, gets deleted from their organisation, or the organisation itself is deactivated, the refresh token is invalidated immediately. Your only signal is an invalid_request error on the next refresh attempt.

Step 3: Resolve the cluster URL

This is the step most teams miss in their first day.

Twinfield runs multiple data clusters. Your access token is issued by the central login service, but the actual web service endpoints live on whichever cluster your customer's organisation sits on. You do not know which cluster that is from the token alone.

Send the access token to the validation endpoint:

GET https://login.twinfield.com/auth/authentication/connect/accesstokenvalidation?token=ACCESS_TOKEN

The response includes a twf.clusterUrl claim. That URL is the base for every subsequent SOAP call. If your customer is on https://accounting.twinfield.com, your calls go there. If they are on a different cluster, calls to the wrong one return what looks like an authentication error but is actually a routing problem. Cache the cluster URL alongside the customer's tokens.

Step 4: Make your first authenticated SOAP request

Twinfield's API is organised around two patterns: Commands and Queries. Commands mutate data, Queries read it. Both wrap a payload in a SOAP envelope with an authentication header.

A simple ProcessXml query that reads the list of offices in an administration looks like:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <Header xmlns="http://www.twinfield.com/">
      <AccessToken>YOUR_ACCESS_TOKEN</AccessToken>
      <CompanyCode>001</CompanyCode>
    </Header>
  </soap:Header>
  <soap:Body>
    <ProcessXmlString xmlns="http://www.twinfield.com/">
      <xmlRequest>
        <list>
          <type>offices</type>
        </list>
      </xmlRequest>
    </ProcessXmlString>
  </soap:Body>
</soap:Envelope>

POST that to {clusterUrl}/webservices/processxml.asmx with Content-Type: text/xml; charset=utf-8 and a SOAPAction header set to http://www.twinfield.com/ProcessXmlString.

CompanyCode scopes every call to a single administration. If your customer manages 200 client books, you iterate by changing the company code in the header. You can pass CompanyId (a GUID) instead of CompanyCode for the same effect.

Twinfield maintains official C# integration samples on GitHub if you want a working reference for the SOAP scaffolding.

Key endpoints and data models

The Twinfield API exposes the core accounting object graph through a mix of typed SOAP services and a generic ProcessXml endpoint that handles XML documents directly.

Master data covers offices (administrations), users, periods, financial settings, VAT codes, currencies, and payment conditions. Dimensions cover customers, suppliers, general ledger accounts, projects, cost centers, and asset codes. Transaction data covers sales invoices, purchase invoices, bank statements, journal entries, cash entries, and memorial entries. Request data covers browse queries for financial reports and trial balance, hierarchy queries for the chart of accounts, and individual transaction reads by number.

The data model leans heavily on dimensions. In Twinfield, customers and suppliers are not first-class objects; they are dimensions of types DEB and CRD respectively. General ledger accounts are dimensions of type BAS or PNL. Once you understand that customers, suppliers, projects, cost centers, and accounts share a dimension data structure, the rest of the API gets easier to navigate. The dimensions documentation is worth reading before you write any code.

Rate limits and concurrency

Twinfield enforces credit-based rate limiting as of December 2024. The credit system charges differently for reads and writes. Query requests (HTTP GET, OPTIONS, and SOAP actions starting with Get, Query, Search, or Load, plus ProcessXml requests with list, read, columns, accountcode, or accountcodes root elements) cost 1 credit. Everything else costs 3 credits.

The credit budget per minute:

  • 1000 credits per IP address
  • 1000 credits per Client ID
  • 1000 credits per Organisation ID
  • 500 credits per Client ID and Organisation ID combination

One wrinkle: those numbers apply to certified integrations. New and uncertified clients get 5% of those limits. That means a non-certified Client ID is capped at 50 credits per minute, and 25 credits per minute against a single organisation. You can hit that ceiling in a few seconds of synchronous backfill.

Twinfield also enforces concurrency: 20 simultaneous requests per Client ID, 10 per Client ID and Organisation combination. A 429 response with the Retry-After header is the signal to back off. The full rate limit rules are documented in the fair use policy.

Two practical implications:

  • Build your client around exponential backoff and respect the X-RateLimit-Remaining header from day one. Adding it after you ship is harder than adding it before.
  • Batch your writes. The XML format lets you submit up to 25 children per parent element and up to 500 lines per transaction (1000 is the hard ceiling). One batched call costs 3 credits; 25 individual calls cost 75.

The certification process

Twinfield gates production access behind a partner program. Until you are certified, you live with the 5% rate limit, and you cannot publish your integration to the Twinfield marketplace, which is where most Twinfield-using accountants discover and install third-party apps.

The certification process consists of a technical review against the API best practices document, a security review, and a recurring audit cadence. Wolters Kluwer charges a partner fee per active API link, and uncertified integrations are eventually phased out. Pricing is published in the partner price list and is worth confirming directly with WK before committing, since the numbers third-party blogs cite are not always current.

Plan for several weeks between submitting an integration for certification and getting marketplace approval. If your product launch depends on it, start the conversation with Wolters Kluwer's partner team before you finish the build, not after.

Common gotchas

A few things that will cost you a day each if you do not know them upfront.

Cluster URL caching. If you skip the cluster resolution step or assume accounting.twinfield.com for every customer, you will hit silent authentication failures the first time a customer is on a different cluster. Cache the resolved URL against the customer's organisation ID.

CompanyCode versus CompanyId. Both work in the SOAP header, but they behave slightly differently across services. CompanyCode is the human-readable code (e.g. 001); CompanyId is the GUID. Some downstream tooling and reporting flows expect one or the other. Pick a convention and stick with it.

Refresh token revocation is silent. When a user is disabled or password-rotated, your refresh token stops working with no upfront notice. Your only signal is an invalid_request error on the next refresh. Build for the case where you have to send the user back through consent without warning.

XML size limits are unevenly documented. The fair use policy says 25 children per parent and 500 lines per transaction recommended, 1000 hard. Some entities have their own internal limits that are not in the public docs. If a large payload fails with a generic error, split it and retry.

The sandbox is a real Twinfield account. Twinfield does not offer a separate sandbox API. Test environments are real Twinfield administrations that you request from your partner contact. Pollution between test data and live data is on you to manage.

VAT handling does not match generic accounting models. Twinfield's VAT logic is opinionated about Dutch and EU compliance rules. Submitting an invoice with an inconsistent VAT code and base amount returns errors that read as schema problems but are actually compliance validation failures. Read the VAT calculation docs before posting any invoices.

Where this leaves you

A direct Twinfield integration is a meaningful build. You are looking at OAuth with cluster resolution, SOAP plumbing, XML payload construction, a credit-based rate limiter that throttles you to 5% until you certify, and a partner program with ongoing fees and a recertification cadence. None of it is unreasonable for a platform with Twinfield's market position, but it is a multi-week commitment for one connector.

If Twinfield is one of several accounting platforms on your roadmap, the math shifts. Your Dutch SMB customers also use MoneyBird and SnelStart. Your French ones use Pennylane. Your German ones use DATEV. Each has its own auth model, its own pagination behaviour, its own gotchas. Building and maintaining a portfolio of direct integrations is a real ongoing engineering investment.

Apideck does not yet have a Twinfield connector. Our unified Accounting API covers most of the rest of the Dutch and broader European SMB market, and custom connectors are part of the enterprise plan when a specific platform is missing. Twinfield is on the roadmap. If you would benefit from it being there sooner, you can request Twinfield support or start building today against the 40+ accounting connectors already in the unified API with a 30-day free trial.

Ready to get started?

Scale your integration strategy and deliver the integrations your customers need in record time.

Ready to get started?
Talk to an expert

Frequently asked questions

Trusted by fast-moving product & engineering teams

JobNimbus
Blue Zinc
Exact
Drata
Octa
Apideck Blog

Continue reading