4invoices geliştirici API'si

HTTPS üzerinden REST, JSON, herkese açık OpenAPI şeması. Faturalama, müşteriler, seriler ve eksiksiz ulusal e-fatura süreci (ANAF e-Factura, Romanya'da) — ERP'nizden, mağazanızdan veya CRM'inizden.

4invoices genel API'si faturalama verilerini sisteminizden 4invoices'a taşır ve faturayı ulusal e-fatura sisteminde (Romanya'da: ANAF SPV) sonuna kadar götürür. Tek bir üretim host'u, tek bir client_credentials akışı, idempotent mali yazma işlemleri ve her rotada aynı hata zarfı.

https://api.4invoices.net/v1 · OpenAPI şeması (anahtar gerekmez)

4invoices API'si nedir

  • 4invoices genel API’si HTTPS üzerinden REST’tir; girdi de çıktı da JSON’dur.
  • Tek bir üretim sunucusu vardır: https://api.4invoices.net/v1. Ayrı bir test sunucusu yoktur.
  • OpenAPI 3.1 spesifikasyonu herkese açıktır ve anahtar gerektirmez — doğrudan Postman’e veya bir istemci üretecine aktarın.
  • Her yanıt bir X-Request-Id başlığı taşır; destek isterken bunu belirtin.
  • Her mali yazma işlemi idempotenttir: timeout sonrasında yapılan yeniden deneme asla ikinci bir belge düzenlemez.
Yalnızca sunucudan sunucuya. API'yi tarayıcı JavaScript'inden asla çağırmayın: client_secret ziyaretçiye ulaşır ve CORS zaten her origin'i engeller.
  • API üzerinden Romanya’daki ANAF e-Factura döngüsünün tamamı: ön kontrol, gönderim, takip, imzalı yanıt ve gelen kutusu. Hiçbir Romen rakip bunu sunmuyor.
  • SmartBill’in ulusal e-fatura sistemine (Romanya’da ANAF) gönderim için hiç endpoint’i yoktur — Romanya’da SPV gönderimi yalnızca arayüzde yapılan bir hesap ayarıdır — ve hiç fatura listeleme endpoint’i de yoktur.
  • Oblio müşteri ve ürünleri birinci sınıf kaynaklar olarak değil, yalnızca bir belge düzenlemenin yan etkisi olarak oluşturabilir.
  • Gönderim yapmadan UBL XML (Romanya’da: CIUS-RO) üretimi: ulusal e-fatura sistemine dokunmadan yasal belgeyi dosya olarak alırsınız.
  • Mali yazma işlemlerinde idempotency: timeout sonrasında yapılan yeniden deneme ikinci bir fatura üretmez ve ikinci bir numara yakmaz.
  • Programatik olarak okunabilen tedarikçi faturaları gelen kutusu — otomatik mutabakatın temeli.

6 adımda ilk fatura

İlk çağrıdan önce
  1. Panelde Faturalama → Ayarlar → API erişimi bölümünden bir kimlik bilgisi oluşturun ve client_secret değerini kopyalayın — yalnızca bir kez gösterilir.
  2. Firma profilini tamamlayın ve fiscale türünde en az bir seri etkinleştirin; aksi hâlde kesim issuer_profile_incomplete veya no_series_configured döner.
  1. Panelde Faturalama → Ayarlar → API erişimi bölümünden bir kimlik bilgisi oluşturun ve client_secret değerini kopyalayın — yalnızca bir kez gösterilir.
  2. Firma profilini tamamlayın ve fiscale türünde en az bir seri etkinleştirin; aksi hâlde kesim issuer_profile_incomplete veya no_series_configured döner.
  3. Kimlik bilgisini token ile değişin: grant_type client_credentials ile POST /v1/auth/token. Token bir saat geçerlidir — önbelleğe alın, her istek için yenisini almayın.
  4. Faturayı kesin: Idempotency-Key başlığı ve yüzde olarak vat_rate (21, 0.21 değil) ile POST /v1/invoices.
  5. Ön kontrolü (Romanya'da: CIUS-RO) POST /v1/invoices/{id}/efactura/validate ile çalıştırın, ardından POST /v1/invoices/{id}/efactura/submit ile ulusal e-fatura sistemine (Romanya'da: ANAF) gönderin.
  6. Durumu GET /v1/efactura/submissions/{id} ile accepted veya rejected olana kadar izleyin.
bash
# 1 — token (1 saat, önbelleğe al)
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 — faturayı kes (Idempotency-Key ZORUNLUDUR)
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}",
    # Her MANTIKSAL işlem için bir anahtar — yeniden denemede aynısını kullanın, asla yeniden üretmeyin.
    "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}],   # yüzde, 0.21 değil
    "currency": "RON",
}, timeout=60).json()

print(invoice["number"], invoice["totals"])

Kimlik doğrulama

  • Akış client_credentials’tır: client_id + client_secret karşılığında bir Bearer access_token alırsınız.
  • Token 3600 saniyede sona erer. Her çağrıda değil, süresi dolmadan önce yenileyin — POST /auth/token’ın IP başına kendi hız sınırı vardır.
  • client_secret yalnızca hash olarak saklanır ve kurtarılamaz. Kaybederseniz yeni bir kimlik bilgisi oluşturur ve eskisini iptal edersiniz.
  • Yalnızca server-to-server. CORS üzerinden hiçbir browser origin’e izin verilmez: sayfadaki JavaScript’ten gizli anahtar ziyaretçiye sızardı.
  • Scopes her kimlik bilgisi için ayrı ayrı verilir. Her sistem için ayrı bir kimlik bilgisi oluşturun ve her birine yalnızca ihtiyaç duyduğu en az scopes’u verin.

Faturalama → Ayarlar → API erişimi

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
// Token'ı önbelleğe alın; her istekte yeni bir token üretmeyin.
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;
}

KDV oranları yüzdedir

vat_rate: 21 ✓  ·  vat_rate: 0.19 ✗  ·  vat_rate: 1 ✗
  • vat_rate bir YÜZDEDİR: 21, %21 anlamına gelir.
  • (0, 1] aralığındaki değerler reddedilir — 0.19 bir kesirdir, 1 ise %1 ile %100 arasında belirsizdir.
  • 0 geçerlidir ve muafiyet ya da ters ibraz (reverse charge) anlamına gelir; yasal ibareyi notes alanına yazın.
  • Düzenleyen KDV mükellefi olduğunda unit_price NET birim fiyattır.
  • Kaydetmeden önce toplamlara mı ihtiyacınız var? POST /v1/invoices/preview-totals, mali numara tüketmeden aynı hesaplamayı yapar.

Mali yazmalarda idempotency

  • Idempotency-Key başlığı POST /invoices, POST /invoices/{id}/storno ve POST /invoices/{id}/efactura/submit üzerinde ZORUNLUDUR.
  • Anahtarlar 24 saat boyunca hatırlanır. Aynı anahtarı aynı gövdeyle yeniden göndermek orijinal sonucu döndürür ve Idempotency-Replayed: true ayarlar.
  • Aynı anahtar farklı bir gövdeyle 409 idempotency_key_reuse döndürür — daha önce düzenlenmiş bir mali belgenin üzerine asla yazılmaz.
  • HTTP denemesi başına değil, MANTIKSAL işlem başına bir anahtar: her yeniden denemede yeni bir UUID değil, order-10457-invoice.
  • Sebep teknik değil, hukukidir: tüketilmiş bir mali numara ve ulusal e-fatura sistemine (Romanya’da: SPV) gönderilmiş bir fatura geri çekilemez.
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" }
  }'

Tüm uç noktalar

MetotUç noktaScopeIdempotency-Keyİstek / dakika
POST/auth/token
Kimlik bilgilerini erişim token'ı ile değiştir
——120
GET/me
Kiracı, scope'lar ve mevcut limitler
invoices:read—120
POST/invoices
Fatura veya proforma düzenle
invoices:writezorunlu30
GET/invoices
Faturaları listele (imleçle sayfalama)
invoices:read—120
POST/invoices/preview-totals
Hiçbir şey oluşturmadan toplamları hesapla
invoices:read—120
GET/invoices/{invoice_id}
Bir faturayı getir
invoices:read—120
GET/invoices/{invoice_id}/pdf
Faturanın PDF'ini indir
invoices:read—120
GET/invoices/{invoice_id}/xml
UBL XML'ini indir (Romanya'da: CIUS-RO)
invoices:read—120
POST/invoices/{invoice_id}/storno
Bu faturayı iptal eden bir iade faturası düzenle
invoices:writezorunlu30
POST/invoices/{invoice_id}/payments
Faturayı ödendi olarak işaretle
invoices:write—30
DELETE/invoices/{invoice_id}/payments
Faturayı ödenmedi olarak işaretle
invoices:write—30
GET/clients
Müşterileri listele
clients:read—120
POST/clients
Müşteri oluştur veya güncelle
clients:write—30
GET/lookup/company/{tax_id}
ANAF sicilinde CUI doğrula (Romanya)
clients:read—120
GET/series
Numaralandırma serilerini listele
invoices:read—120
POST/invoices/{invoice_id}/efactura/validate
Ön kontrol (Romanya'da: CIUS-RO) — göndermeden doğrula
efactura:read—120
POST/invoices/{invoice_id}/efactura/submit
Faturayı ulusal e-fatura sistemine gönder (Romanya'da: ANAF/SPV)
efactura:submitzorunlu10
GET/efactura/submissions
Ulusal e-fatura sistemine yapılan gönderimleri listele
efactura:read—120
GET/efactura/submissions/{submission_id}
Bir gönderimi getir
efactura:read—120
POST/efactura/submissions/{submission_id}/refresh
Ulusal e-fatura sistemine güncel durumu sor
efactura:read—10
GET/efactura/submissions/{submission_id}/download
İmzalı yanıt arşivini indir
efactura:read—120
GET/efactura/inbox
Ulusal e-fatura sistemi üzerinden alınan tedarikçi faturaları
efactura:read—120
GET/efactura/inbox/{inbound_id}
Bir gelen faturayı getir
efactura:read—120
GET/efactura/inbox/{inbound_id}/download
Gelen faturanın arşivini indir
efactura:read—120
POST/efactura/inbox/sync
Ulusal e-fatura sisteminden yeni mesajları gelen kutusuna çek
efactura:read—10

25 endpoints · https://api.4invoices.net/v1/openapi.json

Scope'lar

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit

Ulusal e-fatura sistemi süreci

not_sentvalidatingqueuedsentprocessingacceptedrejectederror
  • Asıl fark: yalnızca belge üretimi değil, ulusal e-fatura sistemiyle (Romanya’da: ANAF e-Factura) döngünün tamamı API üzerinden yürür.
  • POST /invoices/{id}/efactura/validate, ön kontrolü (Romanya’da: CIUS-RO) çalıştırır ve hiçbir şey göndermeden ulusal e-fatura sisteminin reddedeceği alanları tam olarak döndürür.
  • GET /invoices/{id}/xml, gönderim yapmadan UBL XML’ini (Romanya’da: CIUS-RO) üretir — kendi arşiviniz veya iç denetim için kullanışlıdır.
  • POST /invoices/{id}/efactura/submit faturayı ulusal e-fatura sistemine (Romanya’da: SPV) gönderir. Bu geri alınamaz: aynı faturanın ikinci bir kopyası sistemden geri çekilemez.
  • Yaşam döngüsü normalleştirilmiştir: not_sent → validating → queued → sent → processing → accepted | rejected | error. accepted yasal olarak iletildi demektir; error bizim tarafımızdaki bir aktarım hatasıdır ve yeniden denemek güvenlidir.
  • GET /efactura/submissions/{id}/download, ulusal sistemin (Romanya’da: ANAF) imzalı yanıtını içeren arşivi indirir.
  • Gelen taraf da mevcuttur: POST /efactura/inbox/sync ulusal e-fatura sisteminden (Romanya’da: SPV) yeni mesajları çeker, GET /efactura/inbox ise tedarikçilerinizin size gönderdiği faturaları listeler.
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)

Hatalar

  • Her 4xx ve 5xx aynı zarfı kullanır: { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
  • type, dallanmayı üzerine kurduğunuz genel sınıftır (“yeniden deneyebilir miyim?”); code ise kendi sisteminize eşlediğiniz kararlı nedendir.
  • param, sorunlu alanın noktalı yoludur; örneğin lines.0.vat_rate.
  • errors[], tek bir istekte birden fazla alanda sorun olduğunda görünür.
  • request_id bizim tarafımızda kayda alınır. Her destek talebinde belirtin — isteği tam olarak tespit eder.
  • Başka bir tenant’a ait bir id için de 404 döndürülür: başkasına ait verilerin var olduğunu asla doğrulamayız.
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" }
    ]
  }
}
DurumTipKod
401authentication_errormissing_bearer_token
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
401authentication_errorunauthorized
403permission_errorinsufficient_scope
403permission_errorforbidden
404not_found_errornot_found
409conflict_erroridempotency_key_reuse
409conflict_erroridempotency_in_progress
409conflict_errorno_series_configured
422invalid_request_errorvalidation_failed
422invalid_request_errorissuer_profile_incomplete
422invalid_request_errorcius_ro_incomplete
422invalid_request_errorcannot_storno_draft
422invalid_request_errornothing_to_storno
422invalid_request_errorinvalid_json_number
429rate_limit_errorrate_limit_exceeded
502upstream_errorupstream_error
503service_unavailable_errorservice_unavailable

İstek limitleri

Bucketİstek / dakikaAnlamı
read120GET *, POST /invoices/preview-totals, POST /invoices/{id}/efactura/validate
write30POST /invoices, POST /invoices/{id}/storno, POST|DELETE /invoices/{id}/payments, POST /clients
submit10POST /invoices/{id}/efactura/submit, POST /efactura/submissions/{id}/refresh, POST /efactura/inbox/sync
  • Sınırlar kimlik bilgisi başına, dakika başınadır: okuma için 120, yazma için 30, ulusal e-fatura sistemi işlemleri (submit, refresh, inbox/sync) için 10.
  • X-RateLimit-Limit, X-RateLimit-Remaining ve X-RateLimit-Reset, 429 dahil HER yanıtta bulunur.
  • 429 ayrıca saniye cinsinden Retry-After taşır. Buna uyun; sıkı bir döngüde yeniden denemeyin.
  • 10/min kovası vardır, çünkü Romanya’da ANAF, CIF başına dakikada yaklaşık bir mesaj listesi çağrısına izin verir.
  • /efactura/inbox/sync’i agresif polling ile değil, cron ile çalıştırın.
  • Daha yüksek tavanlara mı ihtiyacınız var? Beklenen günlük hacminizle birlikte İletişim üzerinden talep edin.

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
// Retry-After'a uyun; 429 dışındaki 4xx hatalarını asla yeniden denemeyin.
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;
}

// Bir yazma yeniden denemesi AYNI Idempotency-Key'i kullanmak ZORUNDADIR, aksi hâlde
// ikinci bir mali belge kesersiniz.

Konuya göre kılavuzlar

Her konunun kendi sayfası var: ilgili uç noktalar, örnekler ve hatalar.

Sık yapılan hatalar

  • KDV’yi kesir (0.19) ya da 1 olarak göndermek. İkisi de reddedilir; 19 veya 21 gönderin.
  • Her istek için token oluşturmak. Token bir saat geçerlidir; önbelleğe alın, aksi takdirde token endpoint’inin IP başına sınırına takılırsınız.
  • Her yeniden denemede yeni bir idempotency anahtarı üretmek — tam olarak mükerrer faturalar üreten senaryo.
  • Tarayıcıdaki JavaScript’ten çağırmak. CORS her origin’i engeller ve gizli anahtar zaten açığa çıkardı.
  • Ön kontrol (Romanya’da: CIUS-RO) olmadan ulusal e-fatura sistemine göndermek. Hatalı bir gönderim geri çekilemez.
  • /efactura/submissions/{id}/refresh’i dakikada 10 defadan fazla polling yapmak — bu kova submit ile ortaktır.
  • Şirket profili tamamlanmadan ve etkin bir mali seri oluşmadan düzenleme yapmak.

Geliştiriciler için soru ve cevaplar

4invoices API kimlik bilgilerini nasıl alırım?

Panelde Faturalama → Ayarlar → API erişimi bölümünden. client_id ve client_secret alırsınız; secret yalnızca bir kez gösterilir ve sadece hash olarak saklanır.

access_token ne kadar geçerli?

3600 saniye, yani bir saat. Önbelleğe alın ve süresi dolmadan yenileyin — token uç noktasının IP bazlı kendi limiti var.

KDV oranını nasıl gönderirim?

Yüzde olarak: 21 için 21. (0, 1] aralığındaki değerler reddedilir, yani 0.19 ve 1 doğrulamadan geçmez.

Hangi çağrılar Idempotency-Key gerektirir?

POST /invoices, POST /invoices/{id}/storno ve POST /invoices/{id}/efactura/submit. Anahtarlar 24 saat hatırlanır ve tekrar gönderim orijinal belgeyi Idempotency-Replayed: true ile döndürür.

Faturayı doğrudan API üzerinden ulusal e-fatura sistemine gönderebilir miyim?

Evet. /efactura/validate ile ön kontrol (Romanya'da: CIUS-RO), /efactura/submit ile gönderim, /efactura/submissions/{id} üzerinden normalleştirilmiş durum takibi ve sistemin (Romanya'da: ANAF) imzalı yanıtının indirilmesi.

İstek limitleri nedir?

Kimlik bilgisi başına, dakikada: 120 okuma, 30 yazma ve 10 ulusal e-fatura sistemi işlemi. Her yanıt X-RateLimit-* başlıkları taşır, 429 ayrıca Retry-After ekler.

API'yi frontend'den çağırabilir miyim?

Hayır. Yalnızca sunucudan sunucuyadır: hiçbir tarayıcı origin'i CORS'tan geçmez ve client_secret ziyaretçiye ulaşan kodda yer almamalıdır.

İlk faturada neden issuer_profile_incomplete alıyorum?

Şirket profili eksik ya da fiscale türünde etkin bir seri yok. İkisini de panelde tamamlayın; API geçersiz bir mali belge üretmeyi reddeder.