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óda | Cesta | Scope | Hlavičky |
|---|---|---|---|
| POST | /v1/agent/invoices | invoice:create | X-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 predvolene mena firmy, inú viď currency nižšie.
Telo požiadavky
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
type | invoice | proforma | self_invoice | final_invoice | credit_note | debit_note | Nie | Typ 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_id | UUID | Podmienečne | ID existujúceho zákazníka. Povinné je customer_id ALEBO customer. |
customer | objekt | Podmienečne | Inline zákazník (vytvorí sa kontakt). Viď tabuľku nižšie. |
items | pole objektov | Áno | Aspoň 1 položka. Viď tabuľku položiek nižšie. |
vehicle_id | UUID | Nie | ID existujúceho vozidla (modul vozidiel). |
vehicle_plate | string (≤20) | Nie | ŠPZ vozidla: vyhľadá sa vozidlo (normalizuje sa na veľké písmená bez medzier). |
payment_method | bank_transfer | cash | card | online | offset | Nie | Default 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. |
currency | ISO 4217 | Nie | Mena dokladu. Bez nej mena firmy (EUR pre slovenskú, CZK pre českú). Viď Cudzia mena a kurz. |
exchange_rate | string (desatinné číslo) | Nie | Kurz cudzej meny: jednotky currency na jednu jednotku domácej meny firmy. Bez neho kurz ECB / ČNB. Viď Cudzia mena a kurz. |
due_days | int 0–365 | Nie | Splatnosť 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_date | YYYY-MM-DD | Nie | Dátum splatnosti napriamo — alternatíva k due_days (obe naraz = 400). Nesmie byť pred issue_date. |
note | string (≤2000) | Nie | Poznámka na faktúre (viditeľná zákazníkovi). |
internal_note | string (≤2000) | Nie | Interná poznámka (nie na PDF). |
issue_date | YYYY-MM-DD | Nie | Dátum vystavenia. Default dnes. |
delivery_date | YYYY-MM-DD | Nie | Dátum dodania. Default = issue_date. |
order_number | string (≤100) | Nie | Číslo objednávky (orderReference). |
invoice_number | string (≤50) | Nie | Vlastné čí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_address | objekt | Pri režimoch K áno | Dodacia 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_reason | string (1–500) | Nie | Dô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_paid | boolean | Nie | Default false. Pri true sa faktúra vystaví so stavom „paid“ a plnou úhradou k dátumu vystavenia. |
attachments | array (≤10) | Nie | Prí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). |
{ 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.
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
name | string 1–300 | Áno | Názov firmy alebo meno zákazníka. |
ico | string (8 cifier) | Nie | IČO: presne 8 číslic. |
dic | string | Nie | DIČ: 10 cifier (SK) alebo kód krajiny + 8–10 cifier (napr. CZ12345678). Normalizuje sa na veľké písmená bez medzier. |
ic_dph | string (SK + 10 cifier) | Nie | IČ DPH vo formáte SK2120035951. |
address | string | objekt | Nie | Buď celý reťazec, alebo objekt { street, city, postalCode, country }. Pre Peppol je potrebný objekt s úplnou adresou. |
email | email (≤254) | Nie | Prázdny string sa berie ako neuvedené. |
phone | string E.164 (≤16) | Nie | Formá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[])
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
description | string 1–500 | Áno | Názov / popis položky. |
quantity | číslo > 0 | Áno | Množstvo (akceptuje aj číselný string). |
unit | enum | Nie | Default 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 | Áno | Jednotková cena bez DPH. |
vat_rate | int | Áno | Sadzba DPH v percentách. Povolené: 0, 5, 19, 23. |
tax_treatment | enum | Nie | Daň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ácia | tax_treatment | exemption_reason | Kategória (BT-151) | VATEX kód |
|---|---|---|---|---|
| Prenos daňovej povinnosti (§ 69) | reverse_charge_service | voliteľné | AE | VATEX-EU-AE |
| Dodanie tovaru do EÚ (§ 43), premiestnenie, trojstranný obchod | intra_eu_goods / intra_eu_transfer / intra_eu_triangulation | voliteľné | K | VATEX-EU-IC |
| Vývoz mimo EÚ (§ 47) | export_goods | voliteľné | G | VATEX-EU-G |
| Oslobodené plnenie (§ 28–42, margin schémy …) | domestic / neuvedené | áno (text dôvodu) | E | podľa textu (napr. VATEX-EU-F) |
| Nulová sadzba bez dôvodu | domestic / neuvedené | nie | Z | — |
| Dodávateľ nie je platcom DPH | (nepovolené) | voliteľné, prepíše default | O | VATEX-EU-O |
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).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.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",
"exchange_rate": null,
"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.
Cudzia mena a kurz
Bez currency sa faktúra vystaví v mene firmy (EUR pre slovenskú, CZK pre českú). Inú menu pošlite v poli currency (EUR, CZK, USD, GBP, PLN, CHF, HUF, RON, BGN, SEK, DKK, NOK, HRK, RSD, UAH, RUB, TRY, CNY, JPY, CAD, AUD). Pole exchange_rate je desatinné číslo v texte väčšie ako 0 (najviac 7 celých a 8 desatinných miest): počet jednotiek currency na jednu jednotku domácej meny firmy. Slovenská firma, 1 EUR = 1.0842 USD: "exchange_rate": "1.0842".
{
"customer_id": "550e8400-…",
"currency": "USD",
"exchange_rate": "1.0842",
"items": [ { "description": "Konzultácie", "quantity": 1, "unit": "ks", "unit_price": 500, "vat_rate": 0 } ]
}Bez exchange_rate na faktúre v cudzej mene server doplní kurz ECB (slovenská firma) alebo ČNB (česká firma) k dátumu zdaniteľného plnenia (delivery_date, inak issue_date). Ak sa kurz nepodarí získať, faktúra sa aj tak vytvorí s exchange_rate: null. Odpoveď POST /v1/agent/invoices aj GET /v1/agent/invoices/{id} nesú exchange_rate (string alebo null) vedľa currency.
exchange_rate pri faktúre v domácej mene vráti 400. Dobropis alebo ťarchopis s original_invoice_id musí byť v mene pôvodnej faktúry, inak 400 — správa uvádza, akú menu poslať. Bankový účet (bank_account_id) musí mať rovnakú menu ako faktúra (BANK_ACCOUNT_CURRENCY_MISMATCH).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í.
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óda | Cesta | Scope | Content-Type |
|---|---|---|---|
| GET | /v1/agent/invoices/{id}/pdf | invoice:download | application/pdf |
| GET | /v1/agent/invoices/{id}/xml | invoice:download | application/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>Vzájomný zápočet
Zápočet vydanej faktúry s prijatým dokladom tej istej protistrany (napr. platforma fakturuje klientovi službu a jeho odmenu eviduje ako prijatý doklad). Jedno volanie zapíše úhradu so spôsobom offset na faktúru aj na prijatý doklad a obe spáruje. Len pre slovenské firmy. Ak potrebujete uhradiť len jednu stranu, použite POST /v1/agent/invoices/{id}/payments.
| Metóda | Cesta | Scope | Poznámka |
|---|---|---|---|
| POST | /v1/agent/offsets | invoice:update + receipt:update | Podporuje Idempotency-Key. |
| GET | /v1/agent/offsets | invoice:read | Filtre invoice_id, expense_id, page, per_page (≤100). |
| Pole | Typ | Povinné | Popis |
|---|---|---|---|
invoice_id | UUID | Áno | Vydaná faktúra, len type invoice. |
expense_id | UUID | Áno | Prijatá faktúra dodávateľa tej istej protistrany. |
amount | string | Áno | Kladná suma s najviac 2 desatinnými miestami. Nesmie presiahnuť zostatok žiadneho z oboch dokladov (bez tolerancie na zaokrúhlenie). |
offset_date | YYYY-MM-DD | Nie | Default dnes (Europe/Bratislava). Nie v budúcnosti ani pred dátumom vystavenia niektorého z dokladov. |
reference | string (≤100) | Nie | Vaše číslo zápočtu / vyúčtovania. |
note | string (≤500) | Nie | Poznámka. |
POST /v1/agent/offsets
X-API-Key: efk_pk_test_...
X-Organization-Id: 0a2c1f3e-…
Idempotency-Key: 3c8e1d52-settlement-2026-10
Content-Type: application/json
{
"invoice_id": "b1f0d7a2-…",
"expense_id": "5b7e91c4-…",
"amount": "110.70",
"offset_date": "2026-10-31",
"reference": "VYUCT-2026-10"
}
HTTP/1.1 201 Created
{
"data": {
"id": "3d9a60f8-…",
"invoice_id": "b1f0d7a2-…",
"expense_id": "5b7e91c4-…",
"amount": "110.70",
"currency": "EUR",
"offset_date": "2026-10-31",
"reference": "VYUCT-2026-10",
"note": null,
"accounting_program": { "status": "pending", "reason": null },
"created_at": "2026-10-31T09:12:00.000Z",
"invoice": { "id": "b1f0d7a2-…", "total": "270.60", "paid_amount": "110.70", "outstanding": "159.90", "status": "partially_paid" },
"expense": { "id": "5b7e91c4-…", "total": "110.70", "paid_amount": "110.70", "outstanding": "0.00", "payment_status": "paid" }
}
}Úhrady zápočtu sa nedajú zmazať samostatne, ani doklady, ktoré zápočet uhradil (409). Ak niektorý doklad neexistuje, odpoveď je 404. Chyby 400:
| Kód | Význam |
|---|---|
OFFSET_NOT_SUPPORTED | Česká firma — zápočet cez API je len pre slovenské. |
OFFSET_INVOICE_TYPE | Faktúra nie je type invoice (samofaktúra, zálohová faktúra a dobropis sa nezapočítavajú). |
OFFSET_INVOICE_STATUS | Faktúra je koncept, čaká na schválenie alebo je stornovaná. |
OFFSET_EXPENSE_TYPE | Doklad nie je schválená prijatá faktúra dodávateľa. |
OFFSET_COUNTERPARTY_MISMATCH | Kontakt, IČO ani DIČ oboch dokladov sa nezhodujú. Pri osobe bez IČO pošlite prijatý doklad s rovnakým contact_id ako faktúra. |
OFFSET_CURRENCY_MISMATCH | Doklady majú rôzne meny. |
OFFSET_DATE | Dátum je v budúcnosti alebo pred dátumom vystavenia niektorého z dokladov. |
OFFSET_EXCEEDS_BALANCE | Suma presahuje zostatok faktúry alebo prijatého dokladu. |
accounting_program.status pending a reason hovorí prečo; po vytvorení dokladu je sent s internal_document_id. Pri iných programoch sa zápočet automaticky neexportuje.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) | Pole | Zdroj v API |
|---|---|---|
SK-BT-35 | Ulica predávajúceho | address.street organizácie |
SK-BT-37 | Mesto predávajúceho | address.city organizácie |
SK-BT-38 | PSČ predávajúceho | address.postalCode organizácie |
SK-BT-50 | Ulica kupujúceho | customer.address.street |
SK-BT-52 | Mesto kupujúceho | customer.address.city |
SK-BT-53 | PSČ kupujúceho | customer.address.postalCode |
SK-BT-30 | schemeID pri registračnom ID predávajúceho | odvodené z IČO/DIČ organizácie |
SK-BT-47 | schemeID pri registračnom ID kupujúceho | odvodené z IČO/DIČ kupujúceho |
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 skontrolujte suchým behom (dry‑run) cez POST /v1/agent/invoices/{id}/preflight (viď Odporúčaný tok): bez zápisu do DB a bez strhnutia kreditu. Samostatný /peppol/preflight je len pre UBL/CII, ktoré si skladáte sami. Ak si UBL/CII skladáte sami a nechcete ísť cez /agent/invoices, jedným volaním zvalidujete, rezervujete kredit a odošlete cez Konektor.