Skip to main content
The eMSP API authenticates with OAuth2 client credentials. You exchange a client ID and secret for a short-lived access token, then send that token as a bearer token on every request. This is different from the rest of the Spirii API, which uses a long-lived API key. If you’re integrating against those endpoints, see Authentication instead.

How access is structured

Four things sit between your company and an endpoint. Your organisation is your company as Spirii knows it. Inside it, a workspace groups credentials; on the eMSP API a workspace is a tenant, so the workspace your credential belongs to decides whose networks, locations and webhooks you’re working with. A credential is one OAuth2 client: a client ID and a secret. The scopes attached to that credential set the capabilities it can ask for. You never pass an organisation, workspace or tenant ID in a request. All three travel inside the access token, and Spirii resolves them from it.

Get your credentials

Spirii provisions credentials during onboarding. Your Spirii contact sends you a client ID, a client secret, and the list of scopes attached to the credential. Store the secret in a secret manager or an environment variable, never in source control. The security best practices for API keys apply here unchanged. When your integration grows into a capability the credential doesn’t cover, ask Spirii to attach the scope. That’s a grant against your existing credential, not a new credential and not a code change on your side.

Get an access token

Post your credentials to the token endpoint of Spirii’s public-api realm, naming the scopes you want the token to carry:
Scope values are space-separated, so they have to be URL-encoded. With curl that means --data-urlencode rather than -d. The response carries four fields worth reading: A token is good for five minutes. Cache it and fetch a new one shortly before it expires. Requesting a token per API call works, but it adds a round trip to every request for no benefit.

Scopes

A scope attached to your credential makes it allowed to request that capability. It does not put the capability in every token. The token carries a scope only when you name it in the scope parameter. Two things follow from that, and both look like a broken integration when you meet them for the first time.
Omit the scope parameter and the token request still succeeds. You get a valid token carrying none of your capabilities, and every eMSP endpoint answers 403. Request a scope that isn’t attached to your credential and the whole token request fails with invalid_scope, so a single typo costs you the token rather than that one scope.
These are the scopes available across the eMSP API: Ask for the scopes a given token needs rather than everything attached to the credential. A token minted for a nightly location sync has no reason to carry emsp:networks:publish, and keeping it out means a leaked token can’t be used to publish anything. Changing what’s attached to a credential doesn’t reach tokens already issued. After Spirii attaches a scope, request a new token to pick it up.

Authorize a request

Send the access token in the Authorization header, prefixed with Bearer:
Every eMSP endpoint sits under https://api.spirii.com/emsp/v1.

What’s in the token

The access token is a signed JWT issued by https://auth.spirii.dk/realms/public-api using RS256. Decode it and you’ll find the claims Spirii uses to identify you: Reading these claims helps when you’re working out why a call was refused. Spirii verifies the token and derives your identity from it on every request, so treat the claims as diagnostic information rather than something your own code makes access decisions from. Alongside your scopes, scope also carries Keycloak’s built-in defaults such as email and profile. They grant nothing on the eMSP API and are safe to ignore.

Errors

Rotate and revoke

Ask Spirii to rotate the secret and you get a new one immediately; the old secret stops working for new token requests at the same moment. Tokens already issued are a different matter. A token stays valid for its full 300 seconds, and Spirii caches the result of verifying it for up to 300 seconds more, so a credential can keep working for roughly ten minutes after it’s rotated or disabled. Neither action is an instant kill switch; plan rotations and revocations around that window. To rotate without downtime: take the new secret, fetch a token with it to confirm it works, roll it into your integration, and drop the old one.

API overview

The four Spirii APIs, their path prefixes, and where to start.

Errors

The status codes the API returns and how to handle them.

Rate limits

The request limits and how to stay under them.