API publike e 4invoices dërgon të dhënat e faturimit nga sistemi yt te 4invoices dhe e çon faturën deri në sistemin kombëtar të e-faturimit (në Rumani: SPV i ANAF). Një host i vetëm në prodhim, një rrjedhë client_credentials, shkrime fiskale idempotente dhe një zarf i vetëm gabimi në çdo rrugë.
https://api.4invoices.net/v1 · Specifikimi OpenAPI (pa çelës)
Çfarë është API e 4invoices
- API publike e 4invoices është REST mbi HTTPS, me JSON hyrës dhe dalës.
- Një host i vetëm në prodhim: https://api.4invoices.net/v1. Nuk ka host të veçantë sandbox.
- Specifikimi OpenAPI 3.1 është publik dhe pa çelës — importoje direkt në Postman ose në një gjenerues klientësh.
- Çdo përgjigje mban header-in X-Request-Id; citoje kur kërkon mbështetje.
- Çdo shkrim fiskal është idempotent: një rinisje pas timeout-it s'lëshon kurrë dokument të dytë.
- E gjithë rrjedha e e-faturimit kombëtar përmes API (në Rumani: e-Factura ANAF): verifikimi paraprak, paraqitja, ndjekja, përgjigja e nënshkruar dhe kutia hyrëse e marrjes. Asnjë konkurrent rumun s'e ekspozon këtë.
- SmartBill nuk ka asnjë pikë fundore për dërgimin në sistemin kombëtar të e-faturimit (ANAF, në Rumani) — dërgimi është vetëm një cilësim llogarie në ndërfaqe — dhe as nuk ka fare pikë fundore për listimin e faturave.
- Oblio mund të krijojë klientë dhe produkte vetëm si efekt anësor i lëshimit të një dokumenti, jo si burime të veçanta.
- Gjenerimi i XML UBL pa paraqitje (CIUS-RO për Rumaninë): merr dokumentin ligjor si skedar pa prekur sistemin kombëtar të e-faturimit.
- Idempotencë te shkrimet fiskale: një riprovim pas timeout-it s'prodhon faturë të dytë dhe s'harxhon numër të dytë.
- Një kuti hyrëse e lexueshme programatikisht e faturave të furnitorëve — baza e pajtimit automatik.
Fatura jote e parë në 6 hapa
- Krijo një kredencial në panel te Faturim → Cilësime → Aksesi API dhe kopjo client_secret — shfaqet vetëm një herë.
- Plotëso profilin e kompanisë dhe aktivizo të paktën një seri të tipit fiscale; përndryshe lëshimi kthen issuer_profile_incomplete ose no_series_configured.
- Krijo një kredencial në panel te Faturim → Cilësime → Aksesi API dhe kopjo client_secret — shfaqet vetëm një herë.
- Plotëso profilin e kompanisë dhe aktivizo të paktën një seri të tipit fiscale; përndryshe lëshimi kthen issuer_profile_incomplete ose no_series_configured.
- Shkëmbe kredencialin me një token: POST /v1/auth/token me grant_type client_credentials. Tokeni vlen një orë — ruaje në memorie të përkohshme, mos kërko një për çdo kërkesë.
- Lësho faturën: POST /v1/invoices me header-in Idempotency-Key dhe vat_rate si përqindje (21, jo 0,21).
- Bëj verifikimin paraprak (CIUS-RO për Rumaninë) me POST /v1/invoices/{id}/efactura/validate, pastaj dërgoje në sistemin kombëtar të e-faturimit me POST /v1/invoices/{id}/efactura/submit.
- Ndiq gjendjen me GET /v1/efactura/submissions/{id} derisa të arrijë accepted ose rejected.
bash
# 1 — token (1 orë, ruaje në memorie të përkohshme)
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 — lësho faturën (Idempotency-Key është I DETYRUESHËM)
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}",
# Një çelës për çdo operacion LOGJIK — ripërdore në riprovim, mos e rigjenero kurrë.
"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}], # përqindje, jo 0,21
"currency": "RON",
}, timeout=60).json()
print(invoice["number"], invoice["totals"])Autentikimi
- Rrjedha është client_credentials: shkëmben client_id + client_secret me një access_token Bearer.
- Tokeni skadon pas 3600 sekondash. Rinovoje para skadimit, jo në çdo thirrje — POST /auth/token ka kufirin e vet për IP.
- client_secret ruhet vetëm si hash dhe s'mund të rikuperohet. Nëse e humbet, krijon një kredencial të re dhe revokon të vjetrën.
- Vetëm server-me-server. Asnjë origjinë shfletuesi s'kalon CORS: nga JavaScript i faqes sekreti do t'i rrjedhte vizitorit.
- Fushëveprimet jepen për kredencial. Krijo një kredencial të veçantë për çdo sistem dhe jep çdonjërit minimumin e fushëveprimeve që i duhen.
Faturim → Cilësime → Aksesi 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"}javascript
// Ruaje tokenin në memorie të përkohshme; mos krijo një për çdo kërkesë.
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;
}Normat e TVSH-së janë përqindje
vat_rate: 21 ✓ · vat_rate: 0.19 ✗ · vat_rate: 1 ✗- vat_rate është PËRQINDJE: 21 do të thotë 21%.
- Vlerat në (0, 1] refuzohen — 0,19 është thyesë, dhe 1 është e paqartë midis 1% dhe 100%.
- 0 është e vlefshme dhe do të thotë e përjashtuar ose reverse charge (tatimi i kundërt); vendos shënimin ligjor te notes.
- unit_price është ÇMIMI NJËSI NETO kur lëshuesi është tatimpagues i TVSH-së.
- Të duhen totalet përpara se të angazhohesh? POST /v1/invoices/preview-totals kryen të njëjtën aritmetikë pa konsumuar asnjë numër fiskal.
Idempotenca te shkrimet fiskale
- Header-i Idempotency-Key është I DETYRUESHËM te POST /invoices, POST /invoices/{id}/storno dhe POST /invoices/{id}/efactura/submit.
- Çelësat mbahen mend për 24 orë. Përsëritja e të njëjtit çelës me të njëjtin body kthen rezultatin origjinal dhe vendos Idempotency-Replayed: true.
- I njëjti çelës me body tjetër kthen 409 idempotency_key_reuse — një dokument fiskal i lëshuar tashmë nuk mbishkruhet kurrë.
- Një çelës për çdo operacion LOGJIK, jo për çdo tentativë HTTP: order-10457-invoice, jo një UUID të ri në çdo riprovim.
- Arsyeja është ligjore, jo teknike: një numër fiskal i konsumuar dhe një faturë e paraqitur në sistemin kombëtar të e-faturimit nuk mund të tërhiqen.
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" }
}'Çdo pikë fundore
| Metoda | Pika fundore | Fushëveprimi | Idempotency-Key | Kërkesa / minutë |
|---|---|---|---|---|
| POST | /auth/token Shkëmbe kredencialet me një token aksesi | — | — | 120 |
| GET | /me Klienti, fushëveprimet dhe kufijtë aktualë | invoices:read | — | 120 |
| POST | /invoices Lëshon një faturë ose proformë | invoices:write | e detyrueshme | 30 |
| GET | /invoices Liston faturat (faqosje me kursor) | invoices:read | — | 120 |
| POST | /invoices/preview-totals Llogarit totalet pa krijuar asgjë | invoices:read | — | 120 |
| GET | /invoices/{invoice_id} Merr një faturë | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/pdf Shkarkon PDF-në e faturës | invoices:read | — | 120 |
| GET | /invoices/{invoice_id}/xml Shkarkon XML-in UBL (CIUS-RO për Rumaninë) | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/storno Lëshon një notë kredie që anulon këtë faturë | invoices:write | e detyrueshme | 30 |
| POST | /invoices/{invoice_id}/payments Shënon faturën si të paguar | invoices:write | — | 30 |
| DELETE | /invoices/{invoice_id}/payments Shënon faturën si të papaguar | invoices:write | — | 30 |
| GET | /clients Liston klientët | clients:read | — | 120 |
| POST | /clients Krijon ose përditëson një klient | clients:write | — | 30 |
| GET | /lookup/company/{tax_id} Validon një numër tatimor në regjistrin zyrtar (në Rumani: ANAF) | clients:read | — | 120 |
| GET | /series Liston seritë e numërimit | invoices:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/validate Verifikim paraprak — validon pa dërguar | efactura:read | — | 120 |
| POST | /invoices/{invoice_id}/efactura/submit Paraqet faturën në sistemin kombëtar të e-faturimit | efactura:submit | e detyrueshme | 10 |
| GET | /efactura/submissions Liston paraqitjet në sistemin kombëtar | efactura:read | — | 120 |
| GET | /efactura/submissions/{submission_id} Merr një paraqitje | efactura:read | — | 120 |
| POST | /efactura/submissions/{submission_id}/refresh Kërkon gjendjen aktuale nga sistemi kombëtar | efactura:read | — | 10 |
| GET | /efactura/submissions/{submission_id}/download Shkarkon arkivin e përgjigjes së nënshkruar | efactura:read | — | 120 |
| GET | /efactura/inbox Faturat e furnitorëve të marra përmes sistemit kombëtar | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id} Merr një faturë hyrëse | efactura:read | — | 120 |
| GET | /efactura/inbox/{inbound_id}/download Shkarkon arkivin e faturës hyrëse | efactura:read | — | 120 |
| POST | /efactura/inbox/sync Tërheq mesazhet e reja të sistemit kombëtar në kutinë hyrëse | efactura:read | — | 10 |
25 endpoints · https://api.4invoices.net/v1/openapi.json
Fushëveprimet
- invoices:read
- invoices:write
- clients:read
- clients:write
- efactura:read
- efactura:submit
Cikli i e-faturimit kombëtar
- Dallimi kryesor: e gjithë rrjedha drejt sistemit kombëtar të e-faturimit kryhet përmes API, jo vetëm gjenerimi i dokumentit.
- POST /invoices/{id}/efactura/validate kryen verifikimin paraprak (CIUS-RO për Rumaninë) dhe kthen fushat e sakta që sistemi kombëtar i e-faturimit do t'i refuzonte, pa dërguar asgjë.
- GET /invoices/{id}/xml gjeneron XML-in UBL (CIUS-RO për Rumaninë) pa asnjë paraqitje — i dobishëm për arkivin tënd ose për një auditim të brendshëm.
- POST /invoices/{id}/efactura/submit e paraqet në sistemin kombëtar të e-faturimit. Është e pakthyeshme: një kopje e dytë e së njëjtës faturë nuk mund të tërhiqet nga sistemi.
- Cikli i jetës është i normalizuar: not_sent → validating → queued → sent → processing → accepted | rejected | error. accepted do të thotë e transmetuar ligjërisht; error është dështim transporti nga ana jonë dhe mund të riprovohet pa rrezik.
- GET /efactura/submissions/{id}/download merr arkivin me përgjigjen e nënshkruar të sistemit kombëtar të e-faturimit.
- Ekziston edhe krahu i marrjes: POST /efactura/inbox/sync tërheq mesazhet e reja nga sistemi kombëtar i e-faturimit, dhe GET /efactura/inbox liston faturat që t'ua kanë dërguar furnitorët e tu.
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)Gabimet
- Çdo 4xx dhe 5xx përdor të njëjtin zarf: { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
- type është klasa e përgjithshme sipas së cilës vendos («mund ta riprovoj?»), dhe code është arsyeja e qëndrueshme që e lidh me sistemin tënd.
- param është rruga me pika e fushës problematike, për shembull lines.0.vat_rate.
- errors[] shfaqet kur një kërkesë e vetme ka probleme në më shumë se një fushë.
- request_id regjistrohet nga ana jonë. Citoje në çdo kërkesë për mbështetje — e lidh me kërkesën e saktë.
- Kthehet gjithashtu 404 për një id që i përket një tjetri klient: ne nuk konfirmojmë kurrë që ekzistojnë të dhënat e dikujt tjetër.
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" }
]
}
}| Statusi | Lloji | Kodi |
|---|---|---|
| 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 |
Kufijtë e kërkesave
| Grupi | Kërkesa / minutë | Çfarë do të thotë |
|---|---|---|
| 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 |
- Kufijtë janë për kredencial, për minutë: 120 për leximet, 30 për shkrimet, 10 për operacionet e e-faturimit (submit, refresh, inbox/sync).
- X-RateLimit-Limit, X-RateLimit-Remaining dhe X-RateLimit-Reset shfaqen në ÇDO përgjigje, përfshirë 429.
- Një 429 mban edhe Retry-After në sekonda. Respektoje; mos riprovo në një cikël të ngushtë.
- Grupi 10/minutë ekziston sepse në Rumani vetë ANAF lejon afërsisht një thirrje listimi mesazhesh për minutë për CIF.
- Vendose /efactura/inbox/sync në një cron, jo në një polling agresiv.
- Të duhen tavane më të larta? Kërkoje përmes Kontaktit, duke treguar vëllimin tënd ditor të pritshëm.
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
// Respekto Retry-After; mos riprovo kurrë një 4xx tjetër përveç 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;
}
// Riprovimi i një shkrimi DUHET të ripërdorë të NJËJTIN Idempotency-Key, përndryshe lëshon
// një dokument të dytë fiskal.Udhëzues sipas temës
Çdo temë ka faqen e vet me pikat fundore, shembujt dhe gabimet përkatëse.
- Autentikimi në API-n e 4invoicesShkëmben client_id dhe client_secret për një token Bearer me vlefshmëri një orë, vetëm server-me-server.
- Lëshimi i faturave përmes APIPOST /invoices me Idempotency-Key, TVSH si përqindje, plus listimi, storno dhe shënimi si e paguar.
- Klientët dhe kërkimi në regjistrin zyrtarNjë krijim ose përditësim i deduplikuar sipas tax_id, plus një kërkim në regjistrin zyrtar (në Rumani: ANAF), që e-fatura të mos refuzohet.
- E-faturimi kombëtar përmes APIVerifikimi paraprak (CIUS-RO për Rumaninë), paraqitja në sistemin kombëtar, statusi i normalizuar, përgjigja e nënshkruar dhe kutia hyrëse e furnitorëve.
- Seritë e numërimit në APIPa një seri aktive të tipit fiscale, lëshimi kthen 409 no_series_configured.
- Kodet e gabimit dhe zarfi i gabimitNjë formë e vetme në çdo rrugë: type, code, message, param, doc_url, request_id dhe errors.
- Kufijtë e kërkesave dhe riprovimet120 leximë, 30 shkrime dhe 10 operacione e-faturimi në minutë për kredencial, me header-at X-RateLimit-*.
Gabimet e zakonshme
- Dërgimi i TVSH-së si thyesë (0,19) ose si 1. Të dyja refuzohen; dërgo 19 ose 21.
- Krijimi i një tokeni për çdo kërkesë. Tokeni vlen një orë; ruaje në memorie të përkohshme, përndryshe do të bjerësh në kufirin për IP të pikës fundore të tokenit.
- Gjenerimi i një çelësi idempotence të ri në çdo riprovim — pikërisht skenari që prodhon fatura të dyfishta.
- Thirrja nga JavaScript i shfletuesit. CORS bllokon çdo origjinë dhe sekreti do të ekspozohej gjithsesi.
- Paraqitja në sistemin kombëtar të e-faturimit pa verifikimin paraprak. Një dorëzim i gabuar nuk mund të tërhiqet.
- Pyetja e /efactura/submissions/{id}/refresh më shumë se 10 herë në minutë — ky grup ndahet me submit.
- Lëshimi i faturave para se profili i kompanisë të jetë i plotë dhe të ekzistojë një seri fiskale aktive.
Pyetje dhe përgjigje për zhvilluesit
Si i marr kredencialet e API-t të 4invoices?
Në panel, te Faturim → Cilësime → Aksesi API. Merr një client_id dhe një client_secret; sekreti shfaqet vetëm një herë dhe ruhet vetëm si hash.
Sa vlen access_token?
3600 sekonda, pra një orë. Ruaje në memorie të përkohshme dhe rinovoje para skadimit — pika fundore e tokenit ka kufirin e vet të kërkesave për IP.
Si e dërgoj normën e TVSH-së?
Si përqindje: 21 për 21%. Vlerat në (0, 1] refuzohen, pra si 0,19 ashtu edhe 1 dështojnë në validim.
Cilat thirrje kërkojnë Idempotency-Key?
POST /invoices, POST /invoices/{id}/storno dhe POST /invoices/{id}/efactura/submit. Çelësat mbahen mend për 24 orë, dhe një përsëritje kthen dokumentin origjinal me Idempotency-Replayed: true.
A mund ta dërgoj një faturë në sistemin kombëtar të e-faturimit direkt nga API?
Po. Bëj verifikimin paraprak me /efactura/validate, paraqite me /efactura/submit, pyet statusin e normalizuar te /efactura/submissions/{id} dhe shkarko përgjigjen e nënshkruar të sistemit (në Rumani: ANAF).
Cilët janë kufijtë e kërkesave?
Për kredencial, për minutë: 120 leximë, 30 shkrime dhe 10 operacione e-faturimi. Çdo përgjigje mban titujt X-RateLimit-*, dhe një 429 shton Retry-After.
A mund ta thirr API nga frontend-i im?
Jo. Është vetëm server-me-server: asnjë origjinë shfletuesi nuk kalon CORS, dhe client_secret nuk ka vend në kodin që arrin te vizitori.
Pse marr issuer_profile_incomplete në faturën e parë?
Profili i kompanisë është i paplotë ose s'ka asnjë seri aktive të tipit fiscale. Plotësoji të dyja në panel; API refuzon të prodhojë një dokument fiskal të pavlefshëm.