InvoiceHub dokumentace

Aktuální stav implementace: všechny tři spouštěče i všech pět akcí mají dnes reálný efekt. Zbylá omezení jsou popsaná níže – přečtěte si je, než na automatizacích postavíte integraci.

Co reálně funguje:

Známá omezení:

Prakticky to znamená: pravidlo nad konkrétním dokladem (systémová událost → podmínky → změna stavu, e-mail, štítek, oznámení) dnes práci dokončí samo. Cronové pravidlo žádný doklad v kontextu nemá, takže STATUS_CHANGE a ADD_TAG nemají na čem pracovat – tam dál dává smysl poslat webhook ven a navázat vlastní integrací.

Model pravidla

Pravidlo je JSON objekt s těmito poli:

  • triggerTypeSYSTEM_EVENT, SCHEDULED nebo MANUAL.
  • triggerEvent – název události, jen u SYSTEM_EVENT: document.created, document.status_changed nebo document.paid.
  • triggerCron – cron výraz, jen u SCHEDULED.
  • conditions – pole objektů { field, operator, value }.
  • actions – pole objektů { type, params }.

Všechny hodnoty triggerType a actions[].type se zapisují velkými písmeny a parametry akce patří pod klíč params – stejně to uvádí i API reference.

Spouštěče

triggerType Chování
SCHEDULED Naplánuje se podle triggerCron (node-cron). Při naplnění vyhodnotí podmínky a spustí akce. Funkční. Kontext běhu nese jen organizationId – žádný konkrétní doklad, takže akce STATUS_CHANGE a ADD_TAG nemají na čem pracovat.
MANUAL Spouští se výhradně voláním POST /automations/:id/run. Funkční.
SYSTEM_EVENT Spustí se sám, jakmile nastane událost zapsaná v triggerEvent. Funkční. Podporované hodnoty jsou document.created, document.status_changed a document.paid.

Cron výraz je v obvyklém pětipolovém zápisu, například 0 8 * * * pro každý den v 8:00 nebo 0 6 1 * * pro první den v měsíci v 6:00.

Událost document.paid se odpálí navíc k té předchozí: doklad založený rovnou jako uhrazený vyvolá document.created i document.paid, přechod stavu na uhrazeno vyvolá document.status_changed i document.paid. Automatizace běží jako vedlejší efekt požadavku – když selže, založení ani změna dokladu kvůli tomu nespadne, chyba se jen zaznamená (a u částečně neúspěšného běhu přijde interní oznámení).

Kontext běhu u SYSTEM_EVENT nese documentId, organizationId a rovnou i pole, se kterými pracují podmínky – documentType, amount, tags, date – takže se podmínka vyhodnotí bez dalšího dotazu na API.

Podmínky

Podmínka je objekt { field, operator, value }. Podporovaná pole a operátory:

field operator
documentType, amount, tags, date, customField equals, not_equals, gt, lt, gte, lte, contains, not_contains

Jiná pole než těchto pět nejsou podporovaná. Hodnotu value zapisujte jako konstantu – u documentType přesně tak, jak typ dokladu vrací API ve vaší instanci.

Relativní data raději neřešte tady: zápis typu „dnes minus 7 dní“ není dokumentovaný a nedoporučujeme na něj spoléhat. Klouzavé okno („faktury po splatnosti déle než týden“) je spolehlivější vyhodnotit až v systému, který webhook přijme – ten si data načte přes veřejné API a odfiltruje si je sám.

Akce

Akce je objekt { type, params }. Pravidlo může mít akcí víc a provedou se v pořadí, v jakém jsou v poli.

type Co se dnes reálně stane
TRIGGER_WEBHOOK Doručí webhook – podepsaný POST na registrovaný endpoint včetně opakování pokusů. Viz průvodce webhooky.
STATUS_CHANGE Přepíše stav dokladu z kontextu (params.status) a zapíše přechod do časové osy dokladu bez userId – provedl ho systém, ne člověk. Platí stejný stavový automat jako u ruční změny: nepovolený přechod akce bezpečně odmítne s vysvětlující hláškou. Přechod PAID → ISSUED navíc odstraní automaticky dopočtenou úhradu; doklad krytý platbou z banky takhle odznačit nejde a akce skončí chybou.
SEND_EMAIL Opravdu odešle e-mail (params.to, params.subject, params.body – starší název text funguje taky). Neplatné „Komu“ nebo chybějící kontakt akci bezpečně ukončí hláškou.
ADD_TAG Přidá dokladu z kontextu štítek params.tag. Je idempotentní – opakované spuštění se stejným štítkem projde beze změny.
INTERNAL_NOTIFICATION Vytvoří interní oznámení (událost automation.notification) s odkazem na automatizaci a případně na doklad; text vezme z params.title a params.message. Vyžaduje organizationId v kontextu běhu, jinak akce selže hláškou „V kontextu chybí organizationId pro interní notifikaci“.

Název události pro TRIGGER_WEBHOOK si volíte sami v params. Systém ho odešle přesně tak, jak ho zapíšete, takže musí odpovídat tomu, co máte v poli events registrovaného webhooku.

V polích „Komu“, „Předmět“ a „Tělo“ akce SEND_EMAIL můžete použít šablonové proměnné {{contact.email}}, {{contact.name}}, {{document.number}}, {{document.amount}} a {{document.currency}} – doklad se kvůli nim načte i s kontaktem. S literálními hodnotami ve všech polích odejde e-mail i v běhu, kde žádný doklad v kontextu není. Prázdné tělo se nahradí předmětem.

Akce se provádějí v pořadí, v jakém jsou v poli, a neúspěch jedné akce nezastaví ty ostatní – zapíše se do historie běhu jako neúspěšná a běh skončí ve stavu FAILED.

API endpointy

Operace Endpoint
Seznam pravidel GET /api/v1/automations
Vytvoření POST /api/v1/automations
Detail GET /api/v1/automations/:id
Úprava PUT /api/v1/automations/:id
Smazání DELETE /api/v1/automations/:id
Historie běhů GET /api/v1/automations/:id/runs
Ruční spuštění POST /api/v1/automations/:id/run

Volání vyžadují hlavičku Authorization: Bearer <API klíč>, základní adresa staging prostředí je https://invoicehub-api.zeabur.app/api/v1.

Příklad 1: Upomínka po splatnosti

Denní kontrola, která pošle webhook ven; vlastní upomínkový e-mail odešle váš systém (Zapier, n8n, vlastní skript).

POST /api/v1/automations
Content-Type: application/json

{
  "name": "Upomínka po splatnosti",
  "triggerType": "SCHEDULED",
  "triggerCron": "0 8 * * *",
  "conditions": [
    { "field": "documentType", "operator": "equals", "value": "INVOICE" },
    { "field": "date", "operator": "lt", "value": "2026-09-01" }
  ],
  "actions": [
    { "type": "TRIGGER_WEBHOOK", "params": { "event": "reminder.due" } }
  ]
}
Zajistí InvoiceHub Musíte zajistit vy
Spustí pravidlo každý den v 8:00 podle cronu, vyhodnotí podmínky a odešle podepsaný webhook s událostí reminder.due. Přijmout webhook, ověřit podpis, dohledat přes veřejné API doklady po splatnosti a odeslat upomínkový e-mail nad tímto seznamem.

Datum ve value je konstanta, takže filtrování „co je dnes po splatnosti“ udělejte spolehlivěji až na své straně – webhook berte jako denní budík.

Akce SEND_EMAIL už e-mail odeslat umí, ale u cronového pravidla nemá z čeho vzít adresáta: běh spuštěný cronem nemá v kontextu žádný doklad, takže šablonové proměnné jako {{contact.email}} se nemají čím nahradit. Hromadné upomínky proto nechte na systému, který webhook přijme; přímé SEND_EMAIL dává smysl u pravidla nad konkrétním dokladem, tedy se spouštěčem SYSTEM_EVENT.

Příklad 2: Poděkování za úhradu

Doklad, který se dostane do stavu uhrazeno, odpálí událost document.paid – poděkování proto nechte poslat InvoiceHub sám, pravidlem se spouštěčem SYSTEM_EVENT:

POST /api/v1/automations
Content-Type: application/json

{
  "name": "Poděkování za úhradu",
  "triggerType": "SYSTEM_EVENT",
  "triggerEvent": "document.paid",
  "conditions": [],
  "actions": [
    {
      "type": "SEND_EMAIL",
      "params": {
        "to": "{{contact.email}}",
        "subject": "Děkujeme za úhradu faktury {{document.number}}",
        "body": "Dobrý den, {{contact.name}}, platbu {{document.amount}} {{document.currency}} jsme přijali. Děkujeme!"
      }
    }
  ]
}

Běh spuštěný událostí má v kontextu doklad i organizaci, takže se šablonové proměnné dosadí a e-mail odejde na kontakt z dokladu. Pokud si chcete poděkování zpracovat po svém, dejte místo SEND_EMAIL akci TRIGGER_WEBHOOK – nebo obě, provedou se v pořadí.

Druhá varianta je pravidlo MANUAL, které spouštíte vědomě ze svého skriptu po spárování platby:

POST /api/v1/automations/:id/run
Content-Type: application/json

{
  "context": {
    "documentId": "…",
    "organizationId": "…"
  }
}

U ručního spuštění je organizationId v context povinné: route ho z API klíče sama nedoplní, takže bez něj akce nad dokladem i TRIGGER_WEBHOOK selžou (viz Známá omezení na začátku stránky). Počítejte také s tím, že dry-run neexistuje – běh se zapíše a e-mail nebo webhook opravdu odejde.

Zajistí InvoiceHub Musíte zajistit vy
U varianty SYSTEM_EVENT rozpozná úhradu sám, dosadí údaje dokladu do šablony a odešle děkovný e-mail. U varianty MANUAL provede běh na vyžádání. U varianty MANUAL rozpoznat, že platba dorazila, a zavolat /run s documentId a organizationId v kontextu. Zkontrolovat, že kontakt na dokladu má vyplněný e-mail – jinak akce skončí chybou.

Příklad 3: Opakované faktury

Měsíční budík, na jehož základě vnější systém vystaví novou fakturu přes veřejné API.

POST /api/v1/automations
Content-Type: application/json

{
  "name": "Opakované faktury – měsíční",
  "triggerType": "SCHEDULED",
  "triggerCron": "0 6 1 * *",
  "conditions": [],
  "actions": [
    { "type": "TRIGGER_WEBHOOK", "params": { "event": "invoice.recurring.due" } }
  ]
}
Zajistí InvoiceHub Musíte zajistit vy
Prvního dne v měsíci v 6:00 spustí pravidlo a odešle webhook invoice.recurring.due. Po přijetí webhooku vystavit nové faktury voláním veřejného API pro vytvoření dokladu (viz API reference, sekce Documents). InvoiceHub sám navazující doklad nevytvoří – žádná taková akce v automatizacích neexistuje.

Seznam zákazníků s opakovanou fakturací si držte na své straně (nebo přes štítky v InvoiceHubu, které si přes API přečtete) – automatizace zde slouží jen jako spolehlivý plánovač napojený na vaši integraci.

Historie běhů

GET /api/v1/automations/:id/runs vrací historii běhů včetně výsledku každé akce. Protože všechny akce mají reálný efekt, je záznam o provedení důkazem, že se to opravdu stalo – ne jen logem záměru. U úspěšných akcí najdete v záznamu konkrétní podrobnost (na jakou adresu e-mail odešel, z jakého na jaký stav se doklad přepnul, jaký štítek přibyl), u neúspěšných důvod selhání.

Stav běhu je COMPLETED, jen když prošly všechny akce; stačí jedna neúspěšná a běh je FAILED, i když ostatní akce doběhly. Nesplněné podmínky vedou na SKIPPED a žádná akce se neprovede. Doručení webhooku si navíc ověříte v historii doručení webhooku.

Protože dry-run neexistuje, každý test pravidla je ostrý běh – e-mail opravdu odejde a stav dokladu se opravdu přepíše. Při ladění proto zkoušejte pravidlo nejdřív na testovacím dokladu a webhook směrujte na dočasný endpoint, který teprve pak přepnete na produkční adresu přes PUT /api/v1/webhooks/:id.