client_id və client_secret-i yalnız server-server üçün bir saatlıq Bearer tokenə dəyişirsiniz.
6 addımda ilk fakturanız
- Kredensialı panelinizdə Fakturalaşdırma → Parametrlər → API girişi altında yaradın və client_secret-i dərhal kopyalayın — yalnız bir dəfə göstərilir.
- grant_type client_credentials, client_id və client_secret ilə POST /v1/auth/token göndərin.
- access_token, token_type Bearer, expires_in 3600 və verilmiş əhatələrin siyahısını alırsınız.
- Hər digər çağırışda tokeni Authorization: Bearer <access_token> başlığına qoyun.
- GET /v1/me ilə nə əldə etdiyinizi yoxlayın: müştəri, əhatələr və cari sorğu limiti qrupları.
Bütün son nöqtələr
| Metod | Son nöqtə | Əhatə | Idempotency-Key | Sorğu / dəqiqə |
|---|---|---|---|---|
| POST | /auth/token Kredensialları giriş tokeninə dəyişdirir | — | — | 120 |
| GET | /me Müştəri, əhatələr və cari limitlər | invoices:read | — | 120 |
4invoices API nədir
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"
# → müştəri, verilmiş əhatələr və cari sorğu limiti qruplarıjavascript
// Tokeni keşdə saxlayın; hər sorğu üçün yeni yaratmayın.
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
Əhatələr
- invoices:read
- invoices:write
- clients:read
- clients:write
- efactura:read
- efactura:submit
Yalnız server-server. API-ni heç vaxt brauzer JavaScript-indən çağırmayın: client_secret ziyarətçiyə çatar, və CORS hər halda bütün mənbələri bloklayır.
Xətalar
| Status | Növ | Kod |
|---|---|---|
| 401 | authentication_error | invalid_client |
| 401 | authentication_error | token_expired |
| 401 | authentication_error | invalid_token |
| 403 | permission_error | insufficient_scope |
Ümumi səhvlər
- Token son nöqtəsinin öz IP üzrə limiti var. Prosesə bir token, bitməzdən əvvəl yenilənmiş — hər sorğuya yox.
- client_secret yalnız hash kimi saxlanılır; itirsəniz yeni kredensial yaradın və köhnəni ləğv edin.
- ERP, mağaza və daxili skriptlər üçün ayrı kredensiallar verin, hər biri minimal əhatə ilə. Birini ləğv etmək digərlərinə təsir etmir.
- CORS heç bir brauzer mənbəyinə icazə vermir: API dizaynı etibarilə server-server üçündür.
İnkişafçılar üçün suallar və cavablar
client_secret səhvdirsə nə olur?
401 invalid_client kodu alırsınız. Həddindən qısa secret daha əvvəl, validasiyada 422 validation_failed və param client_secret ilə uğursuz olur.
Ayrıca sandbox varmı?
Yox. Yalnız bir istehsal hostu var. Proformalarla (document_kind proforma) və heç bir fiskal nömrə istifadə etməyən /invoices/preview-totals ilə test edin.
Mövcud kredensialın əhatələrini daraltmaq olarmı?
Bəli, paneldən. Artıq verilmiş tokenlər yaradıldıqları əhatələri bir saat ərzində bitənə qədər saxlayır.