How to Integrate with the Rompslomp API

Developer guide to integrating with the Rompslomp API. Covers personal tokens, OAuth 2.0, scopes, pagination, rate limits, and common gotchas.

Saurabh RaiSaurabh Rai

Saurabh Rai · Developer Relations Engineer, Apideck

10 min readView as .md

Reviewed by GJ, Co-founder

How to Integrate with the Rompslomp API

Rompslomp is a Dutch online bookkeeping product owned by Visma, built for freelancers and zzp'ers who want invoicing and VAT filing without learning double-entry bookkeeping. Pricing starts at €5 per month. The product ships with a mobile app for scanning receipts (the "shoe box"), a desktop UI for invoicing and quotations, and integrations with Shopify, Mijnwebwinkel, Simple-Simon, and Mollie. If your software touches money for the Dutch SMB market, Rompslomp will eventually come up alongside MoneyBird and SnelStart as a platform your customers ask you to sync with.

Below is a working developer's view of the Rompslomp API, including the parts that don't behave the way you'd expect coming from QuickBooks or Xero.

The API in brief

Rompslomp ships a REST API hosted at https://api.rompslomp.nl. Resource URLs follow a consistent pattern:

https://api.rompslomp.nl/api/v1/{company_id}/{resource_type}[/{id}]

Most operations happen in the context of a specific company administration, which is why company_id shows up in nearly every path. Requests and responses both use JSON. The official documentation lives at app.rompslomp.nl/developer and is in Dutch, which is worth flagging if your team isn't.

Rompslomp supports two authentication paths: personal API tokens for internal scripts and single-account integrations, and OAuth 2.0 for commercial applications that connect on behalf of many Rompslomp users. The path you pick has real implications for how you handle credentials and refresh logic.

Prerequisites

Before you start:

  • A Rompslomp account. The API is available from the Puur Factuur tier upward; the free tier does not include API access.
  • The API add-on activated on the company administration you want to access. The owner of the administration enables this from Settings.
  • For commercial integrations: a registered OAuth application. You request one through the Rompslomp API integration form.
  • A working understanding of OAuth 2.0 authorization code flow if you're going the commercial route.

Authentication path 1: Personal API tokens

The fast path. Personal API tokens are what you generate when you only need to access your own administrations, or a single customer's administration that you have direct access to.

The flow:

  1. Log in to rompslomp.nl.
  2. Open the account menu in the top right and choose "Mijn account."
  3. Go to "Mijn API tokens" and find the "Nieuw API token" section.
  4. Pick the scopes you want the token to cover. Don't grant scopes the integration won't use.
  5. Click "Aanmaken." The new token displays once.

Treat the token like any other secret: copy on creation and store in your secrets manager.

To use the token, send it in the Authorization header as a Bearer credential:

curl --request GET 'https://api.rompslomp.nl/api/v1/companies/54321/sales_invoices' \
  --header 'Authorization: Bearer NxtsAs1T6P9TcApiTl4DGcLulrLQDqzIWhdaOBI07gU'

These tokens don't expire. They keep working until you delete them, which makes them convenient for cron jobs and back-office integrations, and dangerous if you ever lose track of where they're stored.

The hard limit on personal tokens: if you're building a product where your customers connect their own Rompslomp accounts, personal tokens are not the right model. You need OAuth.

Authentication path 2: OAuth 2.0

Standard authorization code flow, with one documentation quirk worth flagging up front.

After Rompslomp issues you a client ID and client secret, redirect the user to the authorize endpoint with the scopes you need:

https://api.rompslomp.nl/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code&scope={scope}

The redirect_uri must match exactly what's registered for your application. A trailing slash mismatch will cause the authorization to fail without a clear error message.

On approval, the user comes back to your callback with a code query parameter. Exchange it for an access token:

curl --request POST 'https://api.rompslomp.nl/oauth/token' \
  --form 'client_id={client_id}' \
  --form 'client_secret={client_secret}' \
  --form 'grant_type=authorization_code' \
  --form 'code={code}' \
  --form 'redirect_uri={redirect_uri}'

The response contains the access token, a refresh token, and the expiration window in seconds:

{
  "access_token": "LvpR0xfTE437L_sMufuZxYs1iASUn3b9OLLbPihUMGg",
  "token_type": "Bearer",
  "expires_in": 7199,
  "refresh_token": "WzZmMMCAsKmIH8QMq8dCTpxMyELIUn3-pfz1zHHPsIM",
  "scope": "public",
  "created_at": 989532000
}

Access tokens expire after roughly two hours. When the API returns a 401 with error="invalid_token", refresh:

curl --request POST 'https://api.rompslomp.nl/oauth/token' \
  --form 'client_id={client_id}' \
  --form 'client_secret={client_secret}' \
  --form 'grant_type=refresh_token' \
  --form 'refresh_token={refresh_token}'

One inconsistency in the official docs: the refresh example points to rompslomp.nl/oauth/token, while the initial token exchange uses api.rompslomp.nl/oauth/token. The api subdomain works for both. Use it consistently to avoid edge-case redirect issues.

Each refresh returns a new refresh token alongside the new access token. Persist the new refresh token. If you keep using the old one after a refresh, the next refresh will fail.

Scopes

Rompslomp uses scope-based authorization. The available scopes:

ScopeWhat it covers
publicRead general resources: companies, accounts, VAT rates. Default if you don't specify.
manage:companiesManage company administrations.
manage:contactsManage contacts.
manage:paymentsManage payments.
manage:productsManage products.
manage:sales_invoicesManage outgoing invoices, plus their contacts and payments.
manage:journal_entriesManage journal entries.
manage:quotationsManage quotations.
manage:hoursManage time entries.
manage:ridesManage trip and mileage records.
manage:expensesManage expenses.
read:accountsRead balance sheet and P&L accounts.
read:meRead the authenticated user's profile.

Pass scopes as a space-separated list in the authorize URL. Request the minimum your integration needs. Users see the permissions list during authorization, and an inflated set of scopes is one of the cheapest ways to lose them at consent.

One subtle behavior: an access token's scope value tells you what the user authorized in principle. Whether a given scope is usable for a specific company depends on the user's role in that administration. To check what's actually available, call the companies endpoint:

GET /api/v1/companies

Each company object in the response includes an access_control.allowed_scopes array. If the scope you need isn't in that list for the target company, the request will fail even though the token nominally has it.

Making your first request

Once you have a token, fetch the list of companies the user can access:

curl --request GET 'https://api.rompslomp.nl/api/v1/companies' \
  --header 'Authorization: Bearer {access_token}'

A successful response returns the companies array with IDs, names, and allowed scopes. From there, every other request is scoped to a specific company:

curl --request GET 'https://api.rompslomp.nl/api/v1/companies/{company_id}/sales_invoices' \
  --header 'Authorization: Bearer {access_token}'

Core resources

The resources you'll touch most often when building an integration are grouped below by what they cover.

For sales and customer-facing data: contacts (customers and suppliers), sales_invoices (outgoing invoices, with draft and sent states), quotations (outgoing quotes that can be converted to invoices), and layouts (invoice and quotation templates).

For bookkeeping: expenses (incoming costs and receipts), payments (records that link to invoices or expenses), journal_entries (direct ledger entries), bank_transaction_journals (bank transactions), and accounts (balance and P&L accounts, read-only via read:accounts).

For project and operational data: products (catalog), hours (time entries for project-based billing), and rides (mileage tracking, common for Dutch freelancers claiming kilometer allowances).

Write-only attributes prefixed with an underscore are "triggers": they cause side effects without being stored. The most common is _publish on a sales invoice, which moves a draft into a sent state.

Pagination

Every list endpoint paginates. You control it with two query parameters:

  • page: page number, starting at 1.
  • per_page: items per page, between 1 and 100. Default is 40.

Responses include three headers that tell you where you are in the dataset: X-Page shows the current page, X-Per-Page reflects the page size, and X-Total returns the total number of items across all pages.

This is friendlier than MoneyBird, which doesn't return totals at all and forces you to walk the dataset until you hit an empty page. With Rompslomp you can compute the total page count up front and parallelize fetches if you need to.

Rate limiting

Rompslomp enforces rate limits but doesn't publish exact numbers. When you hit the limit, the API returns 429 with a Retry-After header that tells you how many seconds to wait before retrying.

Build exponential backoff with retries, respect Retry-After, and cache where data doesn't change often. The docs explicitly ask integrators to be respectful of shared infrastructure. A sync job hammering the API every minute will be throttled.

Common gotchas

A few things that catch developers off guard when they first build against this API.

The API add-on isn't on by default. If you're testing against your own account and getting 401s on everything, check that the API add-on is activated for the specific company administration. It's a per-administration toggle, not an account-wide one.

Scope authorization is not the same as scope usability. A token can carry manage:sales_invoices and still fail on a specific company because the user's role doesn't include invoice management for that administration. Always check access_control.allowed_scopes per company before assuming a scope works.

The documentation is in Dutch. If your team doesn't read Dutch, plan on either a translation layer in your dev workflow or extra time when you're investigating endpoint behavior. The Dutch terms bedrijf (company), factuur (invoice), and offerte (quotation) come up everywhere.

Personal tokens and OAuth tokens look identical at the call site. Both are passed as Bearer {token} in the Authorization header. If you're mixing both in the same codebase, label your secrets clearly so a personal token isn't accidentally fed to a refresh flow.

Refresh tokens rotate. Each successful refresh returns a new refresh token. If you store credentials in a database, update both tokens atomically. Storing only the new access token while keeping the old refresh token is a classic way to lock yourself out of an integration overnight.

Triggers use underscores. Fields starting with an underscore (_publish and similar) trigger an action rather than store a value. Easy to miss if you're auto-mapping fields between your data model and Rompslomp's.

Where this fits if you're building broader accounting coverage

Rompslomp is one option in a Dutch SMB accounting market that also includes MoneyBird, SnelStart, e-Boekhouden, Yuki, Exact Online, and Pennylane. If your product asks customers "what's your accounting software?", you're looking at building and maintaining several of these in parallel. Each comes with its own auth model and its own pagination behavior.

Apideck does not have a Rompslomp connector at the time of writing. The path to a Rompslomp integration today is the direct one described above. Our unified Accounting API covers most of the rest of the Dutch and European SMB market, and custom connectors are part of the enterprise plan when a specific platform is missing from the lineup. If you're already integrating with MoneyBird or SnelStart through Apideck and want Rompslomp added, that's the route.

For surrounding work, see our guides on the SnelStart API and the MoneyBird API. Between them, they cover the largest share of the Dutch SMB accounting market by user count.

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