Bytt client_id og client_secret mot et Bearer-token som gjelder i én time, kun server-til-server.
← Tilbake til API-dokumentasjonen
Din første faktura på 6 steg
- Opprett legitimasjon i panelet under Fakturering → Innstillinger → API-tilgang, og kopier client_secret med én gang — det vises bare én gang.
- Send POST /v1/auth/token med grant_type client_credentials, client_id og client_secret.
- Du får tilbake access_token, token_type Bearer, expires_in 3600 og listen over tildelte scopes.
- Legg tokenet i en Authorization: Bearer <access_token>-header på alle andre kall.
- Sjekk hva du faktisk fikk med GET /v1/me: tenant, scopes og de gjeldende hastighetskvotene.
Alle endepunkter
| Metode | Endepunkt | Scope | Idempotency-Key | Forespørsler / minutt |
|---|---|---|---|---|
| POST | /auth/token Bytt legitimasjon mot et tilgangstoken | — | — | 120 |
| GET | /me Tenant, scopes og gjeldende grenser | invoices:read | — | 120 |
Hva 4invoices-API-et er
bash
curl -sS -X POST https://api.4invoices.net/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{
"grant_type": "client_credentials",
"client_id": "cli_XXXXXXXXXXXX",
"client_secret": "sec_XXXXXXXXXXXXXXXXXXXX"
}'
# → {"access_token":"eyJ...","token_type":"Bearer","expires_in":3600,
# "scope":"invoices:read invoices:write efactura:submit"}bash
curl -sS https://api.4invoices.net/v1/me \
-H "Authorization: Bearer $ACCESS_TOKEN"
# → tenant, tildelte scopes og gjeldende hastighetskvoterjavascript
// Cache tokenet; ikke lag et nytt per forespørsel.
let cached = { token: "", expiresAt: 0 };
async function getToken() {
if (cached.token && Date.now() < cached.expiresAt - 60_000) return cached.token;
const res = await fetch("https://api.4invoices.net/v1/auth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: process.env.FOURINVOICES_CLIENT_ID,
client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
}),
});
if (!res.ok) throw new Error(`token ${res.status}`);
const data = await res.json();
cached = { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000 };
return cached.token;
}https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json
Scopes
- invoices:read
- invoices:write
- clients:read
- clients:write
- efactura:read
- efactura:submit
Kun server-til-server. Kall aldri API-et fra nettleserens JavaScript: client_secret ville nå besøkende, og CORS blokkerer uansett alle opprinnelser.
Feil
| Status | Type | Kode |
|---|---|---|
| 401 | authentication_error | invalid_client |
| 401 | authentication_error | token_expired |
| 401 | authentication_error | invalid_token |
| 403 | permission_error | insufficient_scope |
Vanlige feil
- Token-endepunktet har en egen grense per IP. Ett token per prosess, fornyet før utløp — ikke ett per forespørsel.
- client_secret lagres kun som hash; mister du det, oppretter du ny legitimasjon og tilbakekaller den gamle.
- Lag egen legitimasjon for ERP-et, nettbutikken og interne skript, hver med minimale scopes. Tilbakekalling av én påvirker ikke de andre.
- CORS tillater ingen nettleseropprinnelse: API-et er server-til-server med vilje.
Spørsmål og svar for utviklere
Hva skjer hvis client_secret er feil?
Du får 401 med koden invalid_client. Et for kort secret feiler tidligere, ved validering, med 422 validation_failed og param client_secret.
Finnes det en egen sandkasse?
Nei. Det finnes én produksjonsvert. Test med proformaer (document_kind proforma) og med /invoices/preview-totals, som ikke forbruker noe fiskalt nummer.
Kan jeg innskrenke scopes på eksisterende legitimasjon?
Ja, fra panelet. Tokens som allerede er utstedt beholder scopene de ble laget med til de utløper, innen en time.