Authentication
There are two ways to authenticate. Use an API key unless your application acts on behalf of a signed-in person.
API keys
An API key identifies your integration: it is bound to your organisation, carries a role and a set of scopes, and every action it performs is attributed to the key's name in the platform's audit trail.
Send it on every request:
curl -H "API-KEY: wsk_..." "https://<gateway-host>/api/locations/v1"
What a key can do
Two things bound a key, and a request must pass both:
- Role — the privilege ceiling, chosen at creation:
Accountant(read-heavy: sessions, billing, audit) orCompanyAdmin(full tenant control). The same role rules that govern portal users apply to the key. - Scopes — the product areas the key may touch, each as read or read-write (for example
charging-sessions:read,tariffs:readwrite). Every endpoint in the API reference states its required scope; endpoints without one do not accept keys at all.
Reads are GET requests plus the export endpoints explicitly marked as read operations; everything else requires the area's readwrite grant.
Key lifecycle
Keys are managed by your CompanyAdmin on the operator portal's API keys page: created (shown once), re-scoped, regenerated (new secret, old one dies instantly — use for rotation or suspected leaks) and revoked. Scope changes take effect within about a minute.
When a key stops working
| Response | Error code | Meaning | What to do |
|---|---|---|---|
401 | — | Unknown or revoked key | Check the key value; ask your admin whether it was revoked |
403 | API_KEY_SCOPE_INSUFFICIENT | The endpoint needs a scope the key lacks (the message names it) | Ask your admin to grant the scope |
403 | PUBLIC_API_LICENSE_INACTIVE | Your organisation's API license is not active and paid | A billing matter, not a technical one — the key resumes when the license does |
Handle PUBLIC_API_LICENSE_INACTIVE gracefully: back off and alert, don't retry in a loop.
JWT (user context)
Applications acting as a signed-in person — a custom app for your staff, for example — exchange credentials for a JWT:
curl -X POST "https://<gateway-host>/token" \
-H 'Content-Type: application/json' \
-d '{"Email": "person@example.fi", "Password": "..."}'
The response carries the token; send it as Authorization: Bearer <token>. A 202 response is a two-factor challenge to complete. There is no refresh token — re-authenticate when the token expires. Google and Apple sign-in exchanges exist for mobile scenarios.
Do not embed user credentials in a server-side integration: that is exactly what API keys replace.