# Spiris — Accounting API: configuration

> Canonical URL: https://developers.apideck.com/apis/accounting/spiris/configuration

# How to obtain Spiris (Visma eAccounting) API credentials

This guide is for the **application owner**, the team that ships an integration on Apideck. You
register a developer client with Spiris, register Apideck's redirect URL against it, and paste the
resulting Client ID and Client Secret into the Apideck Dashboard. From that point your consumers
authorize their own company themselves, and never handle your credentials.

> **One product, several names.** Spiris is the company, renamed from Visma Spcs. The API, its
> hosts and its developer portal are still branded Visma eAccounting: the portal is literally
> titled "Spiris/eAccounting API Documentation", and every URL you will use is on
> `vismaonline.com`. In Sweden the product is sold as **Bokföring & Fakturering** (previously
> Visma eEkonomi); Norway and the Netherlands still sell it as **eAccounting**. They are all the
> same API, and the rename left existing registrations untouched. Do not go looking for a
> separate "Spiris" developer portal. There isn't one.

## Before you start

- An **email address you control and monitor**. Your credentials and your sandbox company are
  delivered by email to the address you register with, so use a team address rather than a
  personal one you may lose access to.
- The details the registration form asks for: your **name, email, company, country** and a short
  description of what you intend to build.
- **Apideck's redirect URL**, ready to supply with the registration:
  `https://unify.apideck.com/vault/callback` (see step 1).
- Access to your Apideck
  [Spiris connector settings](https://platform.apideck.com/configuration/accounting/spiris): this
  is where the credentials end up.

## 1. Register for developer access, and register Apideck's redirect URL with it

Registration is self-service and free, with no review step in front of it. Submit the developer
registration form at **[selfservice.developer.vismaonline.com](https://selfservice.developer.vismaonline.com/)**.

Submitting the form enrols you in the **Spiris Partner Programme** and Spiris emails you:

- a **sandbox Client ID and Client Secret**, and
- a **sandbox company** to develop and test against.

These are *sandbox* credentials. They are everything you need to build and test the integration
end to end, but they cannot be pointed at a live customer's company: production credentials are a
separate request, covered in step 4.

### The redirect URL

Your OAuth client needs Apideck's callback registered against it before anyone can authorize. The
value is **exactly**:

```
https://unify.apideck.com/vault/callback
```

Character for character, https, no trailing slash, no localhost variant. Any other value makes the
identity server reject the authorization with a redirect URI mismatch before the consumer ever
reaches your integration.

Supply this with your registration: in the redirect URI field if the form offers one, and
otherwise in the description of what you are building. Spiris documents no self-service way to
edit a client's redirect URI afterwards, so if it does need to change, treat it as a request to
Spiris API support (contacts in step 4) with your Client ID and the exact URL you need registered.
Confirming the registered value before your first authorization attempt is quicker than
diagnosing a mismatch later.

Reference: [Spiris/eAccounting API documentation](https://developer.vismaonline.com/docs/spiris-eaccounting-api-documentation).

## 2. Scopes

The connector requests the following five scopes on every authorization:

| Scope | Grants |
|-------|--------|
| `ea:api` | Access to the eAccounting / Bokföring & Fakturering API. **Required**: nothing works without it. |
| `ea:sales` | Read and write sales data: invoices, credit notes, customers, invoice items |
| `ea:purchase` | Read and write purchase data: bills and suppliers |
| `ea:accounting` | Read and write accounting data: journal entries, ledger accounts, VAT codes |
| `offline_access` | Issues a refresh token. **Required**: without it the connection dies when the first access token expires and the consumer has to authorize again. |

Two things not to substitute:

- **Read-only variants exist and are not what this connector uses.** Spiris also offers
  `ea:sales_readonly`, `ea:purchase_readonly` and `ea:accounting_readonly`. The connector supports
  write operations, so granting a read-only variant in place of the read/write scope makes every
  create and update fail.
- **`vls:api` is the Payroll scope.** This connector does not use it, and adding it does not
  extend accounting coverage.

Spiris documents what each scope covers on its
[authentication page](https://developer.vismaonline.com/docs/authentication).

## 3. Configure the connector in Apideck

Open your [Spiris connector settings](https://platform.apideck.com/configuration/accounting/spiris)
in the Apideck Dashboard, choose **Use your own client credentials**, and paste in:

- **Client ID**
- **Client Secret**

Save, then test by connecting your sandbox company through Vault. Apideck now runs the OAuth flow
against *your* client: your consumers see your app on the Visma consent screen, and your Client
Secret never leaves the Dashboard.

## 4. Request production access

Production access is **not self-service**. Once your integration works against the sandbox
company, request it from Spiris API support for your market:

| Market | API support address |
|--------|---------------------|
| Sweden | api@spiris.se |
| Norway | api_eaccounting@visma.com |
| Netherlands | partner.eaccounting@visma.com |

When you write to them:

- **Include your Client ID.** Spiris asks for it to identify your registration.
- **Never send your Client Secret.** Spiris states this explicitly: API support will never need it,
  and sharing it compromises every connection your integration holds.
- **Ask your contact for an expected timeline** and for anything they need from you (a demo, a
  description of the data you touch). They own that answer; treat their reply as the schedule.
- **Ask what the grant produces**: whether your existing client is promoted to production, or a new
  Client ID and Secret are issued. That answer decides whether you need to re-enter credentials in
  the Apideck Dashboard (step 3) and reconnect anything, so it is worth settling in the same email
  rather than discovering it afterwards.

Those are the markets Spiris publishes support addresses for. If you operate elsewhere, write to
the address closest to your market and ask them who owns your region.

## Which credentials reach which companies

Sandbox and production are **not separate hosts**: the same API and the same identity server serve
both, and the type of client credentials you authorize with is what decides which companies are in
reach:

- A **sandbox client** reaches your sandbox company only. It can never reach a live customer's
  company, which is the whole reason production access is a separate step.
- A **production client** reaches live companies, and can also be used against your sandbox
  company, so you keep somewhere safe to test after going live.

If you find older material describing dedicated sandbox hosts such as `test.vismaonline.com` or
`identity-sandbox.test.vismaonline.com`, do not configure anything against them: Spiris retired
those on **31 August 2024**. Current detail lives on the
[environments](https://developer.vismaonline.com/docs/environments) and
[sandbox FAQ](https://developer.vismaonline.com/docs/sandbox-faq) pages.

## Token behaviour you need to design around

Apideck handles the token lifecycle for connections made through the connector. Two of these
details still change what you build, so they are worth knowing:

| Item | Value |
|------|-------|
| Access token lifetime | 60 minutes, refreshed automatically by Apideck |
| Authorization code | Single use, valid 5 minutes |
| Refresh token lifetime | Two years, rotated on every refresh |

- **A password change breaks the connection.** When a consumer changes their Visma Online
  password, Spiris invalidates the refresh token immediately and without warning. The connection
  then fails until that consumer authorizes again. This is the most common cause of a
  previously-healthy connection going quiet, and the only fix is reauthorization, so build a
  visible "reconnect" path into your own UI rather than assuming a connection stays valid for the
  full two years.
- **The 5-minute, single-use authorization code** means a consumer who walks away halfway through
  the consent screen has to restart the connection rather than resume it.

If you also call the Spiris API directly, outside the connector, the token endpoint is
`POST https://identity.vismaonline.com/connect/token` with HTTP Basic authentication
(`base64(client_id:client_secret)`) and `Content-Type: application/x-www-form-urlencoded`;
`https://identity.vismaonline.com/connect/revocation` revokes a token. Full detail is on the
[authentication page](https://developer.vismaonline.com/docs/authentication).

### Authorization request parameters (for direct callers)

Spiris recommends two optional parameters on the authorize request. They apply to code that calls
the identity server itself: **the connector's OAuth flow does not send them**, so they are not
what governs what your consumers see when they connect through Vault:

- `prompt=select_account`: forces the company picker to appear instead of reusing whatever Visma
  Online session the browser already holds.
- `acr_values=service:44643EB1-3F76-4C1C-A672-402AE8085934`: narrows the picker to companies with
  an eAccounting or Payroll subscription.

The practical consequence for connections made through the connector: a consumer already signed in
to Visma Online may go straight through without being offered the picker. Signing out of Visma
Online first is what brings it back, useful to know when a consumer reports landing on the wrong
company.

## What happens on the consumer's side

Nothing further is required from you per customer. With your credentials saved, the redirect URL
registered and production access granted, each consumer signs in with their own Visma Online login
and selects the company they want to connect. There are no extra credential fields for them to
fill in: the company is chosen during authorization, so a customer with more than one company
authorizes the one they want synced.

## FAQ and troubleshooting

### Authorization fails with a redirect URI mismatch

The redirect URI registered against your client does not match
`https://unify.apideck.com/vault/callback` exactly. Check for a trailing slash, `http` instead of
`https`, or a localhost URL left over from an early experiment. Correcting it goes through Spiris
API support (step 4): send them your Client ID and the exact URL you need registered.

### Everything works against my sandbox company but fails for a real customer

Expected if you are still on sandbox credentials: a sandbox client cannot access a production
company. The failure usually surfaces as an authorization or permission error rather than an
explicit "wrong environment" message, which makes it easy to misread as a scope problem. Request
production access (step 4).

### A consumer's connection stopped working and nothing changed on my side

Ask whether they recently changed their Visma Online password. That invalidates the refresh token
immediately, and reauthorization is the only fix. A consumer revoking access has the same effect.

### A consumer connected the wrong company

Have them sign out of Visma Online, authorize again, and select the intended company at the
picker. The company is bound at authorization time, so it cannot be switched after the fact
without reconnecting.

### Creates and updates fail while reads work

Check the scopes on your client (step 2). A read-only variant granted in place of `ea:sales`,
`ea:purchase` or `ea:accounting` produces exactly this pattern.

### Who do I ask?

- Spiris client registration, redirect URI changes, production access, API behaviour: the region
  API support address in step 4.
- Anything on the Apideck side (connector settings, Vault, connections):
  [Apideck Support](https://help.apideck.com/en/articles/7774658).

## Reference

- [Spiris/eAccounting API documentation](https://developer.vismaonline.com/docs/spiris-eaccounting-api-documentation)
- [Authentication](https://developer.vismaonline.com/docs/authentication)
- [Environments](https://developer.vismaonline.com/docs/environments)
- [Sandbox FAQ](https://developer.vismaonline.com/docs/sandbox-faq)
- [Developer registration](https://selfservice.developer.vismaonline.com/)
- [Apideck Spiris connector settings](https://platform.apideck.com/configuration/accounting/spiris)


[API reference](https://developers.apideck.com/apis/accounting/reference.md) · [Coverage matrix](https://developers.apideck.com/apis/accounting/coverage)
