Аутентикација на 4invoices API

Мењате client_id и client_secret за Bearer токен који важи сат, само сервер-до-сервер.

Мењате client_id и client_secret за Bearer токен који важи сат, само сервер-до-сервер.

← Назад на API документацију

Прва фактура у 6 корака

  1. Генеришите креденцијал у панелу, у Фактурисање → Подешавања → API приступ, и одмах копирајте client_secret — приказује се само једном.
  2. Пошаљите POST /v1/auth/token са grant_type client_credentials, client_id и client_secret.
  3. Као одговор добијате access_token, token_type Bearer, expires_in 3600 и листу додељених scope-ова.
  4. Токен ставите у заглавље Authorization: Bearer <access_token> у сваком наредном позиву.
  5. Шта сте заправо добили, проверите са GET /v1/me: тенант, scope-ови и тренутни bucket-и ограничења.

Сви endpoint-и

МетодаEndpointScopeIdempotency-KeyЗахтева / минут
POST/auth/token
Замени креденцијале за токен приступа
——120
GET/me
Тенант, scope-ови и тренутни лимити
invoices:read—120

Шта је 4invoices API

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"

# → тенант, одобрени scope-ови и тренутни лимити
javascript
// Кеширајте токен; не правите нови за сваки захтев.
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-ови

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit
Само сервер-до-сервер. Никада не позивајте API из JavaScript-а у прегледачу: client_secret би дошао до посетиоца, а CORS ионако блокира сваки извор.

Грешке

СтатусТипКод
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
403permission_errorinsufficient_scope

Честе грешке

  • Ендпоинт за токен има сопствено ограничење по IP адреси. Један токен по процесу, освежен пре истека — не један по захтеву.
  • client_secret се чува само као хеш; ако га изгубите, генеришете нови креденцијал и опозивате стари.
  • Издајте засебне креденцијале за ERP, онлајн продавницу и интерне скрипте, сваки са минималним scope-овима. Опозив једног не утиче на остале.
  • CORS не дозвољава ниједно порекло из прегледача: API је по дизајну сервер-до-сервер.

Питања и одговори за програмере

Шта се дешава ако је client_secret погрешан?

Добијате 401 са кодом invalid_client. Прекратка тајна пада раније, већ при валидацији, са 422 validation_failed и param client_secret.

Да ли постоји засебно тестно окружение?

Не. Постоји један продукцијски хост. Тестирајте са предрачунима (document_kind проформа) и са /invoices/preview-totals, који не троши фискални број.

Могу ли да сузим scope-ове постојећег креденцијала?

Да, из панела. Већ издати токени задржавају scope-ове са којима су генерисани до истека, најкасније за један сат.