Faktúry

Vystavenie faktúry cez POST /v1/agent/invoices. Predávajúci sa odvodzuje z organizácie (X-Organization-Id), kupujúci z poľa customer alebo z existujúceho customer_id. Číslovanie, výpočet DPH, PDF a QR kód prebiehajú server‑side rovnako ako pri ručnom vystavení.

Endpoint

MetódaCestaScopeHlavičky
POST/v1/agent/invoicesinvoice:createX-API-Key, X-Organization-Id

Na endpoint sa vzťahuje per‑org rate limit 30 požiadaviek / minútu (nad rámec globálneho limitu kľúča). Mena faktúry je vždy EUR.

Telo požiadavky

PoleTypPovinnéPopis
typeinvoice | proforma | self_invoice | final_invoice | credit_note | debit_noteNieTyp dokladu, default invoice. Každý typ má vlastný číselný rad. proforma = zálohová faktúra (výzva na úhradu, nie daňový doklad — nemá DUZP a nedá sa odoslať cez Peppol); self_invoice (samofaktúra) ide cez Peppol pod profilom BIS Self-Billing 3.0; credit_note = dobropis, debit_note = ťarchopis, final_invoice = vyúčtovacia faktúra.
customer_idUUIDPodmienečneID existujúceho zákazníka. Povinné je customer_id ALEBO customer.
customerobjektPodmienečneInline zákazník (vytvorí sa kontakt). Viď tabuľku nižšie.
itemspole objektovÁnoAspoň 1 položka. Viď tabuľku položiek nižšie.
vehicle_idUUIDNieID existujúceho vozidla (modul vozidiel).
vehicle_platestring (≤20)NieŠPZ vozidla: vyhľadá sa vozidlo (normalizuje sa na veľké písmená bez medzier).
payment_methodbank_transfer | cash | card | online | offsetNieDefault bank_transfer (mapuje sa interne na „bank“). online = online platobná služba (PayPal, brána), offset = vzájomný zápočet. Do Peppol UBL sa prenáša ako PaymentMeansCode (UNCL4461): 30 / 10 / 48 / 68 / 97.
due_daysint 0–365NieSplatnosť v dňoch od dátumu vystavenia. Default 14. Pozn.: ak má organizácia nastavené defaultDueDays, použije sa to. Nekombinujte s due_date.
due_dateYYYY-MM-DDNieDátum splatnosti napriamo — alternatíva k due_days (obe naraz = 400). Nesmie byť pred issue_date.
notestring (≤2000)NiePoznámka na faktúre (viditeľná zákazníkovi).
internal_notestring (≤2000)NieInterná poznámka (nie na PDF).
issue_dateYYYY-MM-DDNieDátum vystavenia. Default dnes.
delivery_dateYYYY-MM-DDNieDátum dodania. Default = issue_date.
order_numberstring (≤100)NieČíslo objednávky (orderReference).
invoice_numberstring (≤50)NieVlastné číslo dokladu (napr. z vášho systému). Bez neho sa číslo pridelí z číselného radu organizácie. Obsadené číslo vráti 409. Variabilný symbol = číslice z čísla (posledných 10).
delivery_addressobjektPri režimoch K ánoDodacia adresa (BG-15): name?, street, city, zip, country (2 písmená). Povinná pri intra_eu_goods / intra_eu_transfer / intra_eu_triangulation (BR-IC-12 vyžaduje krajinu dodania), inak voliteľná.
exemption_reasonstring (1–500)NieDôvod oslobodenia od DPH (BT-120) pre 0 % položky — tlačí sa na PDF a prenáša do UBL. Ak žiadna položka nemá vat_rate 0, ignoruje sa. U neplatcu DPH nahrádza predvolený text „Dodávateľ nie je platcom DPH“.
already_paidbooleanNieDefault false. Pri true sa faktúra vystaví so stavom „paid“ a plnou úhradou k dátumu vystavenia.
attachmentsarray (≤10)NiePrílohy (PDF/JPG/PNG/CSV/XLSX/ODS, base64). Pri odoslaní cez Peppol sa vložia priamo do dokladu → dorazia príjemcovi aj na iné systémy (napr. Doklado).
Každá príloha je objekt { filename, mime_code, base64_content } (voliteľne description). Povolené typy: PDF, JPG, PNG, CSV, XLSX, ODS (presne Peppol BIS 3.0 zoznam — DOC/DOCX/XLS/GIF sieť nedoručí, konvertujte ich na PDF); spolu max 10 MB (Peppol limit). Typ sa overuje z obsahu; CSV prejde len s názvom súboru končiacim na .csv. Prílohu možno pridať aj dodatočne k existujúcej faktúre cez POST /v1/agent/invoices/{id}/attachments a spravovať cez GET / DELETE na tej istej ceste.

Objekt customer

Maps na tabuľku kontaktov. Pri inline zákazníkovi sa vytvorí nový kontakt typu customer.

PoleTypPovinnéPopis
namestring 1–300ÁnoNázov firmy alebo meno zákazníka.
icostring (8 cifier)NieIČO: presne 8 číslic.
dicstringNieDIČ: 10 cifier (SK) alebo kód krajiny + 8–10 cifier (napr. CZ12345678). Normalizuje sa na veľké písmená bez medzier.
ic_dphstring (SK + 10 cifier)NieIČ DPH vo formáte SK2120035951.
addressstring | objektNieBuď celý reťazec, alebo objekt { street, city, postalCode, country }. Pre Peppol je potrebný objekt s úplnou adresou.
emailemail (≤254)NiePrázdny string sa berie ako neuvedené.
phonestring E.164 (≤16)NieFormát E.164, napr. +421900123456. Oddeľovače a prefix 00 sa normalizujú (0042... → +42...). Neplatné číslo vráti 400 VALIDATION_ERROR. Prázdny string sa berie ako neuvedené.
address ako objekt vyžaduje neprázdne street, city, postalCode a 2‑písmenový country. Ak pošlete adresu len ako reťazec, reťazec sa uloží do poľa street a country sa nastaví na "SK"; city a postalCode zostanú prázdne: pre Peppol nedostatočné (viď nižšie). Pre Peppol odosielanie vždy posielajte úplný adresný objekt.

Objekt položky (items[])

PoleTypPovinnéPopis
descriptionstring 1–500ÁnoNázov / popis položky.
quantityčíslo > 0ÁnoMnožstvo (akceptuje aj číselný string).
unitenumNieDefault ks. Povolené: ks, hod, l, m, km, súbor, kg, t, g, cm, m2, m3, set, deň, bal, kpl. Do UBL sa mapujú na kódy UN/ECE Rec 20 (km → KMT, kg → KGM, t → TNE, m2 → MTK, deň → DAY …); súbor nemá kód a ide ako C62.
unit_pricečíslo ≥ 0ÁnoJednotková cena bez DPH.
vat_rateintÁnoSadzba DPH v percentách. Povolené: 0, 5, 19, 23.
tax_treatmentenumNieDaňový režim 0 % položky: domestic (default), reverse_charge_service, intra_eu_goods, intra_eu_transfer, intra_eu_triangulation, export_goods. Iná hodnota ako domestic je povolená len pri vat_rate 0 (inak 400) a len pre platcu DPH. Všetky položky s rovnakou sadzbou musia mať rovnaký režim (inak 400). Určuje kategóriu DPH v UBL — tabuľka nižšie.

Kategórie DPH pri 0 % (mapovanie do UBL)

Sadzba 0 % sama o sebe nestačí — EN 16931 rozlišuje prečo je položka bez dane. Kategóriu určuje tax_treatment položky a exemption_reason dokladu (BT-120):

Situáciatax_treatmentexemption_reasonKategória (BT-151)VATEX kód
Prenos daňovej povinnosti (§ 69)reverse_charge_servicevoliteľnéAEVATEX-EU-AE
Dodanie tovaru do EÚ (§ 43), premiestnenie, trojstranný obchodintra_eu_goods / intra_eu_transfer / intra_eu_triangulationvoliteľnéKVATEX-EU-IC
Vývoz mimo EÚ (§ 47)export_goodsvoliteľnéGVATEX-EU-G
Oslobodené plnenie (§ 28–42, margin schémy …)domestic / neuvedenéáno (text dôvodu)Epodľa textu (napr. VATEX-EU-F)
Nulová sadzba bez dôvodudomestic / neuvedenénieZ—
Dodávateľ nie je platcom DPH(nepovolené)voliteľné, prepíše defaultOVATEX-EU-O
Bez tax_treatment a bez exemption_reason ostáva správanie ako doteraz (kategória Z). Ak si chcete výsledné UBL pozrieť pred odoslaním, použite GET /v1/agent/invoices/{id}/xml — vráti náhľad (viď nižšie).
Kategóriu určuje výhradne tax_treatment, nie text dôvodu. Ak exemption_reason sám znie ako prenos / vývoz / dodanie do EÚ (napr. „§ 69“, „prenos daňovej povinnosti“, „export“) a položka nemá cezhraničný režim, požiadavka vráti 400 s pokynom, ktorý režim nastaviť. Režimy K (intra_eu_*) navyše vyžadujú delivery_address s krajinou dodania (BT-80, BR-IC-12). Kategória O (mimo predmetu dane) nemôže byť na jednom doklade s položkami s DPH (BR-O-11). Pri self_invoice je dodávateľom kontakt — pre AE/K/G/E musí mať IČ DPH.
Ak organizácia nie je platcom DPH (nemá ic_dph ani isVatPayer), žiadna položka nesmie mať vat_rate > 0; inak požiadavka zlyhá s VALIDATION_ERROR („Nie ste platcom DPH“). Faktúra dostane výnimku „Dodávateľ nie je platcom DPH“.

Kompletný príklad

POST /v1/agent/invoices
X-API-Key: efk_pk_test_...
X-Organization-Id: 0a2c1f3e-…
Idempotency-Key: 7f0c2a4e-order-2026-042
Content-Type: application/json

{
  "customer": {
    "name": "Odberateľ s.r.o.",
    "ico": "87654321",
    "dic": "2010101010",
    "ic_dph": "SK2010101010",
    "address": {
      "street": "Obchodná 5",
      "city": "Košice",
      "postalCode": "04001",
      "country": "SK"
    },
    "email": "fakturacia@odberatel.sk",
    "phone": "+421900123456"
  },
  "items": [
    {
      "description": "Servisné práce",
      "quantity": 2,
      "unit": "hod",
      "unit_price": 50,
      "vat_rate": 23
    },
    {
      "description": "Náhradný diel",
      "quantity": 1,
      "unit": "ks",
      "unit_price": 80,
      "vat_rate": 23
    }
  ],
  "payment_method": "bank_transfer",
  "due_days": 14,
  "note": "Ďakujeme za dôveru.",
  "order_number": "OBJ-2026-042",
  "invoice_number": "2026-000042"
}

Odpoveď

HTTP/1.1 201 Created

{
  "id": "b1f0d7a2-…",
  "invoice_number": "2026001",
  "status": "issued",
  "customer": { "id": "…", "name": "Odberateľ s.r.o." },
  "items": [ … ],
  "subtotal": "180.00",
  "vat_total": "41.40",
  "total": "221.40",
  "currency": "EUR",
  "issue_date": "2026-06-22",
  "due_date": "2026-07-06",
  "pdf_url": "https://…",
  "created_at": "2026-06-22T10:00:00.000Z"
}

Hodnota id sa používa pri odoslaní cez Peppol (POST /v1/agent/peppol/send/{id}) aj pri zisťovaní stavu.

Idempotencia (retry bez duplikátov)

POST /v1/agent/invoices podporuje voliteľnú hlavičku Idempotency-Key: primárny mechanizmus ochrany pred duplicitnými faktúrami pri automatických retry. Rovnaký kľúč s rovnakým telom vráti uloženú odpoveď (faktúra sa nevytvorí druhýkrát a číslo radu sa neminie); rovnaký kľúč s iným telom, alebo súbežná požiadavka s rovnakým kľúčom, vráti 409. Bez hlavičky sa správanie nemení.

Číslovanie dokladov je postupné a nepreskočiteľné: duplikát vzniknutý retry sa nedá zmazať, len stornovať dobropisom. Preto pri každom klientovi s retry logikou vždy posielajte Idempotency-Key (napr. UUID objednávky). Rovnaká hlavička funguje aj na POST /v1/agent/expenses. Ako doplnok si po úspešnej odpovedi ukladajte vrátené id.

Stiahnutie PDF / XML

Vystavenú faktúru viete stiahnuť ako PDF aj ako UBL XML. Obe operácie sú scopeinvoice:download a vracajú súbor ako prílohu (Content-Disposition: attachment).

MetódaCestaScopeContent-Type
GET/v1/agent/invoices/{id}/pdfinvoice:downloadapplication/pdf
GET/v1/agent/invoices/{id}/xmlinvoice:downloadapplication/xml

Po odoslaní cez Peppol je XML presné UBL, ktoré bolo odovzdané Prístupovému bodu (uchované pre zákonnú archiváciu e‑faktúr). Pred odoslaním endpoint vráti náhľad vygenerovaný tým istým builderom, ktorý používa odosielanie — bez zápisu do DB, bez strhnutia kreditu a bez vložených príloh (tie sa do dokladu vkladajú až pri odoslaní). Ktorý variant ste dostali, hovorí hlavička X-Efaktura-Ubl-Source: archive | preview. Náhľad použite na overenie mapovania business JSON → UBL (jednotky, kategórie DPH, strany). Názov súboru je číslo faktúry ({numberPrefix}{number}.xml).

GET /v1/agent/invoices/b1f0d7a2-…/xml
X-API-Key: efk_pk_test_...
X-Organization-Id: 0a2c1f3e-…

HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Content-Disposition: attachment; filename="OF2026001.xml"
X-Efaktura-Ubl-Source: preview

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">…</Invoice>

Požiadavky na úplnosť pre Peppol

Faktúra vystavená cez tento endpoint je v poriadku ako bežný doklad, ale aby ju bolo možné odoslať cez Peppol, výsledné UBL XML musí prejsť EN 16931 + Peppol BIS Billing 3.0 a navyše slovenským FS overlayom. SK overlay sa uplatní, keď je krajina predávajúceho SK, a vyžaduje:

Pravidlo (BT)PoleZdroj v API
SK-BT-35Ulica predávajúcehoaddress.street organizácie
SK-BT-37Mesto predávajúcehoaddress.city organizácie
SK-BT-38PSČ predávajúcehoaddress.postalCode organizácie
SK-BT-50Ulica kupujúcehocustomer.address.street
SK-BT-52Mesto kupujúcehocustomer.address.city
SK-BT-53PSČ kupujúcehocustomer.address.postalCode
SK-BT-30schemeID pri registračnom ID predávajúcehoodvodené z IČO/DIČ organizácie
SK-BT-47schemeID pri registračnom ID kupujúcehoodvodené z IČO/DIČ kupujúceho
Ak chýba čo i len jedno z polí adresy predávajúceho alebo kupujúceho, odoslanie cez Peppol zlyhá na SK overlayi (napr. SK-BT-35-REQUIRED). Preto pri zakladaní organizácie aj pri vytváraní zákazníka vždy posielajte úplnú adresu (street + city + postalCode + country).

Smerovanie na príjemcu v Peppol prebieha cez DIČ kupujúceho (sandbox: 9915:<DIČ>, produkcia: 0245:<DIČ>). Pre korektnú VAT kategorizáciu (BR‑S/BR‑E) má mať predávajúci aj kupujúci ic_dph. Pred odoslaním viete UBL XML pre‑validovať: viď Validácia.

Faktúru vystavenú týmto endpointom odošlete cez POST /v1/agent/peppol/send/{id}; tesne pred odoslaním ju viete suchým behom (dry‑run) skontrolovať cez Preflight : to je validácia z Agent API (bez session), bez zápisu do DB a bez strhnutia kreditu. Ak si naopak UBL/CII skladáte sami a nechcete ísť cez /agent/invoices, jedným volaním zvalidujete, rezervujete kredit a odošlete cez Konektor.