Автентикация в 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 и списъка с предоставените обхвати.
  4. Поставете токена в заглавка Authorization: Bearer <access_token> при всяко друго извикване.
  5. Проверете какво точно сте получили с GET /v1/me: тенант, обхвати и текущите кошници за лимит.

Всички 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

Често срещани грешки

  • Токен endpoint-ът има собствен лимит по IP. Един токен на процес, опресняван преди изтичане — не по един на заявка.
  • client_secret се съхранява само като хеш; ако го загубите, създавате нови идентификационни данни и отменяте старите.
  • Издайте отделни идентификационни данни за ERP системата, магазина и вътрешните скриптове, всеки с минимални обхвати. Отмяната на едните не засяга останалите.
  • CORS не допуска нито един браузър origin: API-то е сървър-към-сървър по замисъл.

Въпроси и отговори за разработчици

Какво става, ако client_secret е грешен?

Получавате 401 с code invalid_client. Твърде кратка тайна се отхвърля по-рано, при валидацията, с 422 validation_failed и param client_secret.

Има ли отделна тестова среда?

Не. Има един продукционен хост. Тествайте с проформи (document_kind проформа) и с /invoices/preview-totals, който не изразходва фискален номер.

Мога ли да стесня обхвати на съществуващи идентификационни данни?

Да, от панела. Вече издадените токени запазват обхвати, с които са създадени, до изтичането си — в рамките на един час.