Autentificare în API-ul 4invoices

Schimbi client_id și client_secret pe un token Bearer valabil o oră, exclusiv server-to-server.

Schimbi client_id și client_secret pe un token Bearer valabil o oră, exclusiv server-to-server.

← Înapoi la documentația API

Prima factură în 6 pași

  1. Generează credențiala în panou, la Facturare → Setări → Acces API, și copiază client_secret imediat — se afișează o singură dată.
  2. Trimite POST /v1/auth/token cu grant_type client_credentials, client_id și client_secret.
  3. Primești access_token, token_type Bearer, expires_in 3600 și lista de scope-uri acordate.
  4. Pune tokenul în antetul Authorization: Bearer <access_token> pe toate celelalte apeluri.
  5. Verifică ce ai primit cu GET /v1/me: tenant, scope-uri și bucketele de rată curente.

Toate endpoint-urile

MetodăEndpointScopeIdempotency-KeyCereri / minut
POST/auth/token
Schimbă credențialele pe un token de acces
——120
GET/me
Tenant, scope-uri și limitele curente
invoices:read—120

Ce este API-ul 4invoices

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, scope-urile acordate și bucketele de rată curente
javascript
// Păstrează tokenul în memoria cache; nu cere unul nou la fiecare cerere.
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

Scope-uri

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit
Doar server-to-server. Nu apela API-ul din JavaScript de browser: client_secret ar ajunge la utilizator, iar CORS blochează oricum orice origin.

Erori

StatusTipCod
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
403permission_errorinsufficient_scope

Greșeli frecvente

  • Endpointul de token are limită proprie pe IP. Un token per proces, reînnoit înainte de expirare, nu unul per request.
  • client_secret se ține doar ca hash; dacă îl pierzi, generezi o credențială nouă și revoci pe cea veche.
  • Emite credențiale separate pentru ERP, magazin și scripturi interne, cu scope-uri minime. Revocarea unei credențiale nu afectează celelalte.
  • CORS nu permite niciun origin de browser: API-ul este server-to-server prin design.

Întrebări frecvente de la dezvoltatori

Ce se întâmplă dacă client_secret este greșit?

Primești 401 cu code invalid_client. Un secret prea scurt cade mai devreme, la validare, cu 422 validation_failed și param client_secret.

Există un mediu de test separat?

Nu. Există un singur host de producție. Testează cu proforme (document_kind proforma) și cu /invoices/preview-totals, care nu consumă numere fiscale.

Pot restrânge scope-urile unei credențiale existente?

Da, din panou. Tokenurile deja emise păstrează scope-urile de la momentul emiterii până expiră, în cel mult o oră.