---
title: "How to Integrate with the Dinero API"
description: "A developer guide to the Dinero API: personal vs Visma Connect auth, organizations, pagination, vouchers, webhooks, rate limits and Dinero's review process."
author: "Kateryna Poryvay"
published: "2026-10-14"
updated: "2026-10-15T11:34:18.308Z"
url: "https://www.apideck.com/blog/how-to-integrate-with-the-dinero-api"
category: "Accounting"
tags: ["Accounting", "Guides & Tutorials"]
---

# How to Integrate with the Dinero API

Dinero reported DKK 216.8 million in revenue for 2024, up 32% on the year before, and set a target of 100,000 customers for 2025, according to [the company's own annual results announcement](https://dinero.dk/om-os/presse/nyt-rekordregnskab-dinero-vil-ramme-kvart-milliard-i-2025-2/). Most of its customers are Danish sole traders and small companies doing their own bookkeeping. If you sell software to Danish SMBs, a request to integrate with the Dinero API will land on your roadmap sooner or later.

Visma [acquired Dinero in 2016](https://www.mynewsdesk.com/visma/pressreleases/visma-acquires-the-accounting-software-dinero-3120871), and the API now runs on Visma's identity infrastructure. That is why app registration happens on the Visma Developer Portal while integration approvals come from the Dinero team. Dinero also runs a second, simpler authentication system for personal integrations.

## Personal integration or Visma Connect

A personal integration is meant for a company connecting its own Dinero account to its own systems. It requires a Pro or Total subscription, and access ends if that subscription lapses. Per the [personal integration docs](https://developer.dinero.dk/documentation/personal-integration/), you request credentials inside Dinero under Integrationer, then "Se og opret API-nøgler", then Personlig Integration. Dinero shows the Client ID and secret once and stores them encrypted, so save them immediately. Approval usually takes a few hours and normally finishes within one working day. You then generate an API key inside each organization you want to reach. One set of client credentials works across all of your organizations.

The token exchange uses an OAuth password grant, with the API key passed as both username and password:

```bash
curl -X POST https://authz.dinero.dk/dineroapi/oauth/token \
  -H "Authorization: Basic $(echo -n 'CLIENT_ID:CLIENT_SECRET' | base64)" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&scope=read%20write&username=YOUR_API_KEY&password=YOUR_API_KEY"
```

The access token lasts 3,600 seconds and no refresh token comes back. When it expires, you request a new one with the same call.

Visma Connect is the path for SaaS products that connect many customers' Dinero accounts. It is a standard OAuth 2.0 authorization code flow against `connect.visma.com`, and it is the only path that supports webhooks. If you are building a product for other companies, this is the one you want.

## Registering a Visma Connect application

Registration happens on the [Visma Developer Portal](https://oauth.developers.visma.com/), and the [getting started guide](https://developer.dinero.dk/documentation/getting-started/) has a few requirements that trip people up. Set your team's country to Denmark, or the Dinero scopes will not appear. Use your real company details and a real CVR number, since Dinero rejects placeholder teams. Pick "web application" as the type, because it is the only one supported.

Your Client ID must follow the format `isv_yourcompany` and clearly identify you. Dinero gives `isv_Vibrant` as an approved example and `isv_test-application` as one it would reject. The word "Dinero" is not allowed in the name.

Under grants, choose Authorization Code (or add PKCE if you can) and enable offline access. Configure a re-use refresh token with a 365-day expiration. With that setup, a user authorizes once and only needs to repeat it about once a year. Turn off OpenID Connect, since Dinero's authorization guide and Postman collection do not support it. Then add the Dinero integration and apply for the Read and Write scopes only. Applications that request the Internal scope get rejected.

Approval takes up to a working day. Once you have it, send users to the authorize endpoint:

```
https://connect.visma.com/connect/authorize
  ?client_id=isv_yourcompany
  &response_type=code
  &response_mode=form_post
  &scope=dineropublicapi:read dineropublicapi:write offline_access
  &redirect_uri=https://yourapp.com/callback
  &ui_locales=da-DK
```

Exchange the returned code at the token endpoint. The [authorization docs](https://developer.dinero.dk/documentation/authorization/) warn that a JSON body will fail here, so send it URL-encoded:

```bash
curl -X POST https://connect.visma.com/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=AUTH_CODE&redirect_uri=https://yourapp.com/callback&client_id=isv_yourcompany&client_secret=YOUR_SECRET"
```

Store the refresh token with the same care as a password. If you need a refresher on token storage and rotation, our post on [API integration best practices](https://www.apideck.com/blog/api-integration-best-practices) covers the patterns that apply here.

## Finding the right organization

Visma Connect authorization is per user, and one user can have access to several Dinero companies. Every resource endpoint is scoped to an organization ID, so the first call after authorization should list the organizations the user can reach:

```bash
curl https://api.dinero.dk/v1.1/organizations \
  -H "Authorization: Bearer ACCESS_TOKEN"
```

Let the user pick the company to connect, then store that ID alongside the token. The [Dinero FAQ](https://developer.dinero.dk/documentation/faq/) recommends this flow specifically to avoid 401 errors from guessing the wrong organization. The endpoint stays callable for users without a valid Pro or Total license, which makes it a good place to detect a lapsed subscription before your sync starts failing.

## Reading data

Resource endpoints follow the pattern `https://api.dinero.dk/v1/{organizationId}/{resource}`. Contacts, invoices, credit notes, products, the chart of accounts and accounting entries are all available as list endpoints. The full reference lives in the [Dinero OpenAPI docs](https://api.dinero.dk/openapi/index.html).

```bash
curl "https://api.dinero.dk/v1/123456/contacts?fields=Name,ContactGuid,Email&page=0&pageSize=500" \
  -H "Authorization: Bearer ACCESS_TOKEN"
```

List endpoints return a limited set of fields unless you ask for more with `fields`. Pagination is zero-based. The default page size is 100 and the maximum is 1,000; a larger value throws an error with code 43. Add the `changesSince` filter with the timestamp of your last successful run and you only get records modified since then, which makes incremental sync cheap.

To download an invoice as a PDF, call `GET /v1/{organizationId}/invoices/{guid}` with the `Accept` header set to `application/octet-stream`. Set that header on the PDF request only, since applying it client-wide will break your JSON calls.

## Writing data: vouchers, ledger items and invoices

How you write to Dinero depends on where the source document lives. If your product generates invoices itself, the FAQ recommends booking them as a manual voucher in Dinero and attaching your invoice file, instead of recreating the invoice through the invoices endpoint. Upload the file first with a multipart POST to `/v1/{organizationId}/files`, passing the file name as a query parameter, then reference it from the voucher.

For expenses, use a purchase voucher (købsbilag), which books one item at a time and can set a contact as the creditor. For several booking lines that should post together, use ledger items (kassekladdelinjer), which appear under Bogføring and Kassekladde in the Dinero UI.

Documents start as drafts and only affect the books once booked. [Opter's Dinero integration guide](https://docs.opter.com/en/integration-022.htm) describes this flow in practice: it creates one manual voucher per exported invoice and attaches the invoice PDF to it. Build your write path with the same two stages, and treat a draft that never got booked as a failure your sync should surface.

## Webhooks and keeping data in sync

Dinero [launched webhooks in August 2024](https://developer.dinero.dk/news/webhooks-are-here/) with a single event type: entries. You subscribe by posting the event type and your destination URL to the subscribe endpoint, and you can list and remove subscriptions the same way. Webhooks are only available to one-to-many integrations authorized through Visma Connect. Personal integrations have to poll list endpoints with `changesSince`.

Even with webhooks enabled, you will poll for most objects. The FAQ lists entries as the only webhook event, though Dinero's April 2026 rate-limit announcement also mentions invoice webhooks, so check the events endpoint for what your organization can subscribe to. A scheduled `changesSince` sweep per organization, plus the entries webhook for ledger changes, covers most accounting use cases.

## Rate limits

Dinero [started enforcing its rate limit at the end of April 2026](https://developer.dinero.dk/news/rate-limit-in-effect/). The limit depends on the integration type. Visma Connect (ISV) clients get 100 requests per minute per organization, counted per Client ID. Personal integrations get 60 requests per minute per client. Requests over the limit return HTTP 429 with the body "API calls quota exceeded!".

The limit matters less than the policy around it. Dinero reserves the right to revoke access for clients that use the API inefficiently, and repeated 400, 401 or 403 responses can trigger the same outcome. A sync job that retries a broken token in a loop can get your integration shut off for every customer at once. Back off on 429 and stop after consecutive auth errors.

## Testing, review and publishing

Every new Dinero company gets 30 days of Pro access, which is enough to build against. Per the [test company guide](https://developer.dinero.dk/documentation/test-company/), use a fake CVR number and an obvious name like "My Company API Test". When the trial ends, create another company for another 30 days. If you are building a one-to-many integration, you can email api@dinero.dk with your Client ID and organization ID to request a free Pro license for testing. Dinero does not grant that license to personal integrations.

Before you can onboard customers, Dinero runs a [technical review](https://developer.dinero.dk/documentation/review/). You send traffic that mirrors normal usage, then email api@dinero.dk with your Client ID and the time window of your requests. The team checks whether your request pattern looks efficient and whether you handle client errors correctly. Their guidance is explicit: if you hit consecutive errors, your integration should stop. After approval, you submit your listing details through the publishing form, and Dinero usually responds within a few working days. Published integrations appear on [dinero.dk/integrationer](https://dinero.dk/integrationer/).

The [intro page](https://developer.dinero.dk/documentation/intro/) lists grounds for rejection, including inefficient API use and services that overlap too closely with Dinero's own business. If your product competes with a Dinero feature, raise it with the team before you build.

## A few things the docs will not warn you about

The Node.js example on the personal integration page has two bugs: a `'scope='` key that should read `scope`, and a missing colon in the password field. Copy the curl version instead. Remove any localhost redirect URI from your Visma Connect application before you go to review. And if Dinero's scopes do not show up in the developer portal, check your team country before you email support.

## Dinero and the rest of your accounting integrations

Dinero is one system in a crowded Danish market. Danish customers also run e-conomic and Billy, each with its own API and auth model. Building them one at a time works when Denmark is your only market. It gets expensive once you add Sweden, or the Netherlands, where [Twinfield brings a SOAP API and a certification program](https://www.apideck.com/blog/how-to-integrate-with-the-twinfield-api) of its own.

Dinero is on Apideck's connector radar but not yet supported. When it ships, it will sit behind the same [Accounting API](https://www.apideck.com/accounting-api) that already connects to Fortnox and Visma eAccounting through one normalized REST API, with authentication handled on our side. If Dinero is on your roadmap, request it on the [Dinero connector page](https://www.apideck.com/accounting-software/dinero), or build against the unified API today for the systems it already supports.
