Publiskā 4invoices API pārsūta rēķinu datus no jūsu sistēmas uz 4invoices un nogādā rēķinu līdz pat valsts e-rēķinu sistēmai (Rumānijā – ANAF SPV). Viens ražošanas serveris, viena client_credentials plūsma, idempotenti fiskālie ieraksti un viena kļūdu atbildes struktūra katrā maršrutā.
https://api.4invoices.net/v1 · OpenAPI specifikācija (atslēga nav vajadzīga)
Kas ir 4invoices API
- 4invoices publiskā API ir REST pār HTTPS, JSON ievadei un JSON izvadei.
- Viens ražošanas serveris: https://api.4invoices.net/v1. Atsevišķa testa servera nav.
- OpenAPI 3.1 specifikācija ir publiska un bez atslēgām — importējiet to tieši Postman vai klientu ģeneratorā.
- Katrā atbildē ir X-Request-Id galvene; norādiet to, kad lūdzat atbalstu.
- Katrs fiskālais ieraksts ir idempotents: atkārtots mēģinājums pēc noildzes nekad neizveido otru dokumentu.
- Viss valsts e-rēķinu sistēmas cikls caur API (Rumānijā – ANAF e-Factura): iepriekšēja pārbaude, iesniegšana, izsekošana, parakstīta atbilde un ienākošā kaste. Neviens Rumānijas konkurents to nepiedāvā.
- SmartBill nav neviena galapunkta rēķinu iesniegšanai valsts e-rēķinu sistēmā (Rumānijā – ANAF) — sūtīšana ir tikai saskarnes konta iestatījums — un nav arī rēķinu saraksta galapunkta.
- Oblio var izveidot klientus un produktus tikai kā blakusefektu dokumenta izrakstīšanas laikā, nevis kā pirmās šķiras resursus.
- UBL XML ģenerēšana (Rumānijā – CIUS-RO) bez iesniegšanas: juridisko dokumentu saņemat kā failu, neskarot valsts e-rēķinu sistēmu.
- Idempotence fiskālajos ierakstos: atkārtots mēģinājums pēc noildzes neizveido otru rēķinu un neiztērē otru numuru.
- Programmatiski lasāma piegādātāju rēķinu ienākošā kaste — automatizētas saskaņošanas pamats.
Pirmais rēķins 6 soļos
- Izveidojiet piekļuves datus panelī sadaļā Rēķini → Iestatījumi → API piekļuve un nokopējiet client_secret — tas tiek parādīts tikai vienu reizi.
- Aizpildiet uzņēmuma profilu un aktivizējiet vismaz vienu fiskālo sēriju (fiscale), citādi izrakstīšana atgriezīs issuer_profile_incomplete vai no_series_configured.
- Izveidojiet piekļuves datus panelī sadaļā Rēķini → Iestatījumi → API piekļuve un nokopējiet client_secret — tas tiek parādīts tikai vienu reizi.
- Aizpildiet uzņēmuma profilu un aktivizējiet vismaz vienu fiskālo sēriju (fiscale), citādi izrakstīšana atgriezīs issuer_profile_incomplete vai no_series_configured.
- Apmainiet piekļuves datus pret žetonu: POST /v1/auth/token ar grant_type client_credentials. Žetons ir derīgs stundu — saglabājiet to kešatmiņā, nepieprasiet jaunu katram pieprasījumam.
- Izrakstiet rēķinu: POST /v1/invoices ar Idempotency-Key galveni un vat_rate procentos (21, nevis 0.21).
- Veiciet iepriekšēju pārbaudi (Rumānijā – CIUS-RO) ar POST /v1/invoices/{id}/efactura/validate un pēc tam iesniedziet rēķinu valsts e-rēķinu sistēmā ar POST /v1/invoices/{id}/efactura/submit.
- Sekojiet statusam ar GET /v1/efactura/submissions/{id}, līdz tas sasniedz accepted vai rejected.
bash
# 1 — žetons (1 stunda, saglabājiet kešatmiņā)
ACCESS_TOKEN=$(curl -sS -X POST https://api.4invoices.net/v1/auth/token \
-H 'Content-Type: application/json' \
-d '{"grant_type":"client_credentials","client_id":"cli_XXX","client_secret":"sec_XXX"}' \
| python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')
# 2 — izrakstiet rēķinu (Idempotency-Key ir OBLIGĀTS)
curl -sS -X POST https://api.4invoices.net/v1/invoices \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-10457-invoice' \
-d '{"buyer":{"name":"Exemplu Comert SRL","tax_id":"RO12345678","county":"Cluj","city":"Cluj-Napoca","country":"RO"},
"lines":[{"description":"Abonament SaaS","quantity":1,"unit_price":400,"vat_rate":21}]}'
# 3 — preflight CIUS-RO, then send to ANAF
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate \
-H "Authorization: Bearer $ACCESS_TOKEN"
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/submit \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Idempotency-Key: efactura-inv_01J7ABC-1'javascript
const BASE = "https://api.4invoices.net/v1";
const token = await fetch(`${BASE}/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,
}),
}).then((r) => r.json()).then((d) => d.access_token);
const invoice = await fetch(`${BASE}/invoices`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
"Idempotency-Key": `order-${orderId}-invoice`,
},
body: JSON.stringify({
buyer: { name: "Exemplu Comert SRL", tax_id: "RO12345678", county: "Cluj", city: "Cluj-Napoca", country: "RO" },
lines: [{ description: "Abonament SaaS", quantity: 1, unit_price: 400, vat_rate: 21 }],
currency: "RON",
metadata: { order_id: String(orderId) },
}),
}).then((r) => r.json());
console.log(invoice.number, invoice.totals); // "FCT-000123" { net, vat, gross }python
import os, uuid, requests
BASE = "https://api.4invoices.net/v1"
token = requests.post(f"{BASE}/auth/token", json={
"grant_type": "client_credentials",
"client_id": os.environ["FOURINVOICES_CLIENT_ID"],
"client_secret": os.environ["FOURINVOICES_CLIENT_SECRET"],
}, timeout=30).json()["access_token"]
headers = {
"Authorization": f"Bearer {token}",
# Viena atslēga LOĢISKAI darbībai — atkārtojot izmantojiet to atkal, nekad neģenerējiet jaunu.
"Idempotency-Key": f"order-{order_id}-invoice",
}
invoice = requests.post(f"{BASE}/invoices", headers=headers, json={
"buyer": {"name": "Exemplu Comert SRL", "tax_id": "RO12345678",
"county": "Cluj", "city": "Cluj-Napoca", "country": "RO"},
"lines": [{"description": "Abonament SaaS", "quantity": 1,
"unit_price": 400, "vat_rate": 21}], # procentos, nevis 0.21
"currency": "RON",
}, timeout=60).json()
print(invoice["number"], invoice["totals"])Autentifikācija
- Plūsma ir client_credentials: client_id + client_secret pāri apmainiet pret Bearer access_token.
- Žetons derīgs 3600 sekundes. Atjaunojiet to pirms derīguma beigām, nevis katram izsaukumam — POST /auth/token ir savs IP pieprasījumu ierobežojums.
- client_secret tiek saglabāts tikai kā hash un to nevar atgūt. Ja to pazaudējat, izveidojiet jaunus piekļuves datus un atsauciet vecos.
- Tikai serveris–serveris. CORS nepieļauj nevienu pārlūkprogrammas avotu: no lapas JavaScript secret nonāktu pie apmeklētāja.
- Scope piešķir katriem piekļuves datiem atsevišķi. Izveidojiet atsevišķus datus katrai sistēmai un piešķiriet katrai minimāli nepieciešamos scope.
Rēķini → Iestatījumi → API piekļuve
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"}javascript
// Saglabājiet žetonu kešatmiņā; neveidojiet jaunu katram pieprasījumam.
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;
}PVN likmes ir procenti
vat_rate: 21 ✓ · vat_rate: 0.19 ✗ · vat_rate: 1 ✗- vat_rate ir PROCENTS: 21 nozīmē 21 %.
- Vērtības intervālā (0, 1] tiek noraidītas — 0.19 ir daļa, un 1 ir neskaidrs (1 % vai 100 %).
- 0 ir derīga vērtība un nozīmē atbrīvojumu vai apgriezto nodokļa maksāšanu; juridisko atsauci ierakstiet laukā notes.
- unit_price ir NETO vienības cena, ja izrakstītājs ir PVN maksātājs.
- Vai nepieciešamas summas pirms apstiprināšanas? POST /v1/invoices/preview-totals veic to pašu aprēķinu, neizlietojot fiskālo numuru.
Idempotence fiskālajos ierakstos
- Idempotency-Key galvene ir OBLIGĀTA izsaukumos POST /invoices, POST /invoices/{id}/storno un POST /invoices/{id}/efactura/submit.
- Atslēgas tiek atceras 24 stundas. Tās pašas atslēgas atkārtota nosūtīšana ar to pašu saturu atgriež sākotnējo rezultātu un iestata Idempotency-Replayed: true.
- Tā pati atslēga ar citu saturu atgriež 409 idempotency_key_reuse — jau izrakstītais fiskālais dokuments nekad netiek pārrakstīts.
- Viena atslēga vienai LOĢISKAI darbībai, nevis katram HTTP mēģinājumam: order-10457-invoice, nevis jauns UUID katrā atkārtojumā.
- Iemesls ir juridisks, nevis tehnisks: izmantotu fiskālo numuru un valsts e-rēķinu sistēmā iesniegtu rēķinu nevar atsaukt.
bash
curl -sS -X POST https://api.4invoices.net/v1/invoices \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: order-10457-invoice' \
-d '{
"buyer": {
"name": "Exemplu Comert SRL",
"tax_id": "RO12345678",
"address": "Str. Fabricii 12",
"city": "Cluj-Napoca",
"county": "Cluj",
"country": "RO",
"email": "[email protected]"
},
"lines": [
{ "description": "Abonament SaaS, iulie", "quantity": 1, "unit_price": 400, "vat_rate": 21, "unit": "buc" },
{ "description": "Implementare", "quantity": 6, "unit_price": 250, "vat_rate": 21, "unit": "ora" }
],
"currency": "RON",
"document_kind": "factura",
"due_date": "2026-08-15",
"metadata": { "order_id": "10457" }
}'Visi galapunkti
| Metode | Galapunkts | Scope | Idempotency-Key | Pieprasījumi / minūtē |
|---|---|---|---|---|
| POST | /auth/token Apmainīt piekļuves datus pret piekļuves žetonu | — | — | 120 |
| GET | /me Tenant, scope un pašreizējie ierobežojumi | invoices:read | — | 120 |
| POST | /invoices Izrakstīt rēķinu vai proforma rēķinu | invoices:write | obligāts | 30 |
| GET | /invoices Uzskaitīt rēķinus (lapošana ar kursoru) | invoices:read | — | 120 |
| POST | /invoices/preview-totals Aprēķināt summas, neko neveidojot | invoices:read | — | 120 |
| GET | /invoices/{invoice_id} Iegūt vienu rēķinu | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/pdf Lejupielādēt rēķina PDF | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/xml Lejupielādēt UBL XML (Rumānijā – CIUS-RO) | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/storno Izrakstīt kredītrēķinu, kas anulē šo rēķinu | invoices:write | obligāts | 30 |
| POST | /invoices/{invoice_id}/payments Atzīmēt rēķinu kā apmaksātu | invoices:write | — | 30 |
| DELETE | /invoices/{invoice_id}/payments Atzīmēt rēķinu kā neapmaksātu | invoices:write | — | 30 |
| GET | /clients Uzskaitīt klientus | clients:read | — | 120 |
| POST | /clients Izveidot vai atjaunināt klientu | clients:write | — | 30 |
| GET | /lookup/company/{tax_id} Pārbaudīt CUI pret Rumānijas ANAF reģistru | clients:read | — | 120 |
| GET | /series Uzskaitīt numerācijas sērijas | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/validate Iepriekšēja pārbaude (Rumānijā – CIUS-RO) — pārbaudīt, neko nesūtot | efactura:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/submit Iesniegt rēķinu valsts e-rēķinu sistēmā | efactura:submit | obligāts | 10 |
| GET | /efactura/submissions Uzskaitīt iesniegumus e-rēķinu sistēmā | efactura:read | — | 120 |
| GET | /efactura/submissions/{submission_id} Iegūt vienu iesniegumu | efactura:read | — | 120 |
| POST | /efactura/submissions/{submission_id}/refresh Pajautāt valsts e-rēķinu sistēmai pašreizējo stāvokli | efactura:read | — | 10 |
| GET | /efactura/submissions/{submission_id}/download Lejupielādēt parakstīto atbilžu arhīvu | efactura:read | — | 120 |
| GET | /efactura/inbox Caur valsts e-rēķinu sistēmu saņemtie piegādātāju rēķini | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id} Iegūt vienu ienākošo rēķinu | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id}/download Lejupielādēt ienākošā rēķina arhīvu | efactura:read | — | 120 |
| POST | /efactura/inbox/sync Ielādēt jaunus sistēmas ziņojumus ienākošajā kastē | efactura:read | — | 10 |
25 endpoints · https://api.4invoices.net/v1/openapi.json
Scope
- invoices:read
- invoices:write
- clients:read
- clients:write
- efactura:read
- efactura:submit
Valsts e-rēķinu sistēma
- Patiesā atšķirība: viss valsts e-rēķinu sistēmas cikls (Rumānijā – ANAF e-Factura) notiek caur API, nevis tikai dokumenta izveide.
- POST /invoices/{id}/efactura/validate veic iepriekšēju pārbaudi (Rumānijā – CIUS-RO) un atgriež tieši tos laukus, ko valsts e-rēķinu sistēma noraidītu, neko nenosūtot.
- GET /invoices/{id}/xml ģenerē UBL XML (Rumānijā – CIUS-RO) bez iesniegšanas — noderīgi jūsu arhīvam vai iekšējam auditam.
- POST /invoices/{id}/efactura/submit iesniedz rēķinu valsts e-rēķinu sistēmā. Tas ir neatgriezeniski: tā paša rēķina otru eksemplāru nevar atsaukt no sistēmas.
- Cikls ir normalizēts: not_sent → validating → queued → sent → processing → accepted | rejected | error. accepted nozīmē juridiski nosūtīts; error ir mūsu puses pārraides kļūda, un to drīkst droši atkārtot.
- GET /efactura/submissions/{id}/download lejupielādē arhīvu ar valsts e-rēķinu sistēmas parakstīto atbildi.
- Ienākošā puse arī pastāv: POST /efactura/inbox/sync iegūst jaunus ziņojumus no valsts e-rēķinu sistēmas, un GET /efactura/inbox uzskaita jūsu piegādātāju nosūtītos rēķinus.
bash
# CIUS-RO preflight. Sends NOTHING to ANAF.
curl -sS -X POST "https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate?include_xml=true" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# → {"invoice_id":"inv_01J7ABC","valid":false,
# "errors":["buyer.county is required for RO buyers"],
# "xml_base64":"PD94bWwg..."}bash
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/submit \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Idempotency-Key: efactura-inv_01J7ABC-1'
# → {"submission_id":"sub_01J7XYZ","status":"queued"}python
import time, requests
BASE = "https://api.4invoices.net/v1"
TERMINAL = {"accepted", "rejected"}
H = {"Authorization": f"Bearer {token}"}
def wait_for_anaf(submission_id, timeout=900):
deadline = time.time() + timeout
delay = 15
while time.time() < deadline:
r = requests.get(f"{BASE}/efactura/submissions/{submission_id}", headers=H, timeout=30)
r.raise_for_status()
status = r.json()["status"]
if status in TERMINAL:
return r.json()
# /refresh asks ANAF directly and shares the 10/min submit bucket.
requests.post(f"{BASE}/efactura/submissions/{submission_id}/refresh", headers=H, timeout=30)
time.sleep(delay)
delay = min(delay * 2, 120)
raise TimeoutError(submission_id)Kļūdas
- Katrs 4xx un 5xx izmanto to pašu apvalku: { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
- type ir rupja klase, pēc kuras jūs pieņemat lēmumus („vai var mēģināt atkārtoti?”), un code ir stabils iemesls, ko jūs piesaistāt savai sistēmai.
- param ir kļūdaina lauka ceļš ar punktiem, piemēram, lines.0.vat_rate.
- errors[] parādās, kad vienam pieprasījumam ir problēmas vairāk nekā vienā laukā.
- request_id tiek reģistrēts mūsu pusē. Norādiet to katrā atbalsta pieteikumā — tas precīzi nosaka pieprasījumu.
- 404 tiek atgriezts arī identifikatoram, kas pieder citam tenant: mēs nekad neapstiprinām, ka cita persona dati pastāv.
json
{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "Datele trimise nu sunt valide.",
"param": "lines.0.vat_rate",
"doc_url": "https://4invoices.net/ro/api-dezvoltatori#errors",
"request_id": "req_8a893f2f33d4472da8d6e144",
"errors": [
{ "param": "lines.0.vat_rate", "message": "VAT rate must be a percent (21), not a fraction", "type": "value_error" }
]
}
}| Statuss | Tips | Kods |
|---|---|---|
| 401 | authentication_error | missing_bearer_token |
| 401 | authentication_error | invalid_client |
| 401 | authentication_error | token_expired |
| 401 | authentication_error | invalid_token |
| 401 | authentication_error | unauthorized |
| 403 | permission_error | insufficient_scope |
| 403 | permission_error | forbidden |
| 404 | not_found_error | not_found |
| 409 | conflict_error | idempotency_key_reuse |
| 409 | conflict_error | idempotency_in_progress |
| 409 | conflict_error | no_series_configured |
| 422 | invalid_request_error | validation_failed |
| 422 | invalid_request_error | issuer_profile_incomplete |
| 422 | invalid_request_error | cius_ro_incomplete |
| 422 | invalid_request_error | cannot_storno_draft |
| 422 | invalid_request_error | nothing_to_storno |
| 422 | invalid_request_error | invalid_json_number |
| 429 | rate_limit_error | rate_limit_exceeded |
| 502 | upstream_error | upstream_error |
| 503 | service_unavailable_error | service_unavailable |
Pieprasījumu ierobežojumi
| Grupa | Pieprasījumi / minūtē | Ko tas nozīmē |
|---|---|---|
| read | 120 | GET *, POST /invoices/preview-totals, POST /invoices/{id}/efactura/validate |
| write | 30 | POST /invoices, POST /invoices/{id}/storno, POST|DELETE /invoices/{id}/payments, POST /clients |
| submit | 10 | POST /invoices/{id}/efactura/submit, POST /efactura/submissions/{id}/refresh, POST /efactura/inbox/sync |
- Ierobežojumi ir uz piekļuves datiem minūtē: 120 lasījumi, 30 rakstīšanas, 10 e-rēķinu sistēmas darbības (submit, refresh, inbox/sync).
- X-RateLimit-Limit, X-RateLimit-Remaining un X-RateLimit-Reset parādās KATRĀ atbildē, arī 429.
- 429 atbildē ir arī Retry-After sekundēs. Ievērojiet to; neatkārtojiet pieprasījumu stingrā ciklā.
- 10/min grupa pastāv tāpēc, ka Rumānijas ANAF atļauj aptuveni vienu ziņojumu saraksta pieprasījumu minūtē uz nodokļu maksātāja kodu (CIF).
- Ieplānojiet /efactura/inbox/sync ar cron, nevis agresīvu aptauju.
- Vajadzīgi lielāki limiti? Pieprasiet caur Kontakti, norādot paredzamo dienas apjomu.
X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset · Retry-After
http
HTTP/2 429
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1785312000
Retry-After: 17
Content-Type: application/json
{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded",
"message":"...","doc_url":"https://4invoices.net/ro/api-dezvoltatori#errors",
"request_id":"req_..."}}javascript
// Ievērojiet Retry-After; neatkārtojiet nevienu 4xx, izņemot 429.
async function call(url, init, attempt = 0) {
const res = await fetch(url, init);
if (res.status === 429 || res.status >= 500) {
if (attempt >= 5) return res;
const retryAfter = Number(res.headers.get("Retry-After")) || 2 ** attempt;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return call(url, init, attempt + 1);
}
return res;
}
// Rakstīšanas atkārtojumā JĀIZMANTO TO PAŠU Idempotency-Key, citādi izrakstīsiet
// otru fiskālo dokumentu.Ceļveži pēc tēmām
Katrai tēmai ir sava lapa ar attiecīgajiem galapunktiem, piemēriem un kļūdām.
- Autentifikācija 4invoices APIApmainiet client_id un client_secret pret vienas stundas Bearer žetonu — tikai serveris–serveris.
- Rēķinu izrakstīšana caur APIPOST /invoices ar Idempotency-Key, PVN procentos, kā arī saraksts, storno un atzīmēšana kā apmaksāts.
- Klienti un meklēšana oficiālajā uzņēmumu reģistrāDedublēta izveide vai atjaunināšana (upsert) pēc tax_id un uzņēmumu reģistra meklēšana (Rumānijā – ANAF), lai e-rēķins netiktu noraidīts.
- Valsts e-rēķinu sistēma caur APIIepriekšēja pārbaude (Rumānijā – CIUS-RO), iesniegšana sistēmā, normalizēts statuss, parakstīta atbilde un ienākošā piegādātāju kaste.
- Numerācijas sērijas APIBez aktīvas fiskālās sērijas (fiscale) izrakstīšana atgriež 409 no_series_configured.
- Kļūdu kodi un kļūdu apvalksViens formāts katrā maršrutā: type, code, message, param, doc_url, request_id un errors.
- Pieprasījumu ierobežojumi un atkārtošana120 lasījumi, 30 rakstīšanas un 10 e-rēķinu sistēmas darbības minūtē uz piekļuves datiem, ar X-RateLimit-* galvenēm.
Biežākās kļūdas
- PVN tiek sūtīts kā daļa (0.19) vai kā 1. Abi tiek noraidīti; sūtiet 19 vai 21.
- Žetons katram pieprasījumam. Žetons derīgs stundu; saglabājiet to kešatmiņā, citādi sasniegsiet žetona galapunkta IP ierobežojumu.
- Jaunas idempotences atslēgas ģenerēšana katram atkārtojumam — tieši šis scenārijs rada dublētus rēķinus.
- Izsaukšana no pārlūkprogrammas JavaScript. CORS bloķē visus avotus, un secret tik un tā tiktu atklāts.
- Iesniegšana valsts e-rēķinu sistēmā bez iepriekšējās pārbaudes. Nepareizu iesniegumu nevar atsaukt.
- /efactura/submissions/{id}/refresh aptauja biežāk nekā 10 reizes minūtē — šī grupa ir kopīga ar iesniegšanu.
- Rēķinu izrakstīšana, pirms uzņēmuma profils ir pabeigts un ir aktīva fiskālā sērija.
Izstrādātāju jautājumi un atbildes
Kā iegūt 4invoices API piekļuves datus?
Panelī sadaļā Rēķini → Iestatījumi → API piekļuve. Saņemsiet client_id un client_secret; secret tiek parādīts vienu reizi un saglabāts tikai kā hash.
Cik ilgi derīgs access_token?
3600 sekundes jeb viena stunda. Saglabājiet to kešatmiņā un atjaunojiet pirms derīguma beigām — žetona galapunktam ir atsevišķs IP pieprasījumu ierobežojums.
Kā nosūtīt PVN likmi?
Procentos: 21 nozīmē 21 %. Vērtības intervālā (0, 1] tiek noraidītas, tāpēc gan 0.19, gan 1 neizturēs validāciju.
Kuriem izsaukumiem nepieciešams Idempotency-Key?
POST /invoices, POST /invoices/{id}/storno un POST /invoices/{id}/efactura/submit. Atslēgas tiek atceras 24 stundas, un atkārtota atskaņošana atgriež sākotnējo dokumentu ar galveni Idempotency-Replayed: true.
Vai es varu iesniegt rēķinu valsts e-rēķinu sistēmā tieši caur API?
Jā — Rumānijas tirgū ANAF e-Factura sistēmā. Veiciet iepriekšēju pārbaudi ar /efactura/validate, iesniedziet rēķinu ar /efactura/submit, pārbaudiet normalizēto statusu /efactura/submissions/{id} un lejupielādējiet sistēmas parakstīto atbildi.
Kādi ir pieprasījumu ierobežojumi?
Uz piekļuves datiem minūtē: 120 lasījumi, 30 rakstīšanas un 10 e-rēķinu sistēmas darbības. Katrā atbildē ir X-RateLimit-* galvenes, bet 429 papildus satur Retry-After.
Vai es varu izsaukt API no sava frontend?
Nē. Tas ir tikai serveris–serveris: neviens pārlūkprogrammas avots nepāriet cauri CORS, un client_secret nedrīkst atrasties kodā, kas nonāk līdz apmeklētājam.
Kāpēc pirmajā rēķinā saņemu issuer_profile_incomplete?
Uzņēmuma profils nav pilnīgs vai nav aktīvas fiskālās sērijas. Aizpildiet abus panelī; API atsakās ģenerēt nepareizu fiskālo dokumentu.