Skip to main content

Messaging and Routing Protocols

The middleware uses an event-driven pipeline to process invoices. Every invoice event triggers a configurable sequence of actions. This page explains how events, actions, and webhook delivery work.


Invoice Events

The platform exposes the following event IDs. Use these IDs when configuring Event Routing rules.

Lifecycle — Outbound (platform → FIRS)

Event IDDescription
invoice.createdInvoice created in the system from an ERP webhook
invoice.validatedInvoice passed schema and business rule validation
invoice.signedInvoice digitally signed with tenant FIRS credentials
invoice.transmittedInvoice transmitted to FIRS
invoice.deliveredInvoice successfully delivered and acknowledged by FIRS — IRN issued

Lifecycle — Inbound (FIRS/external → platform)

Event IDDescription
invoice.receivedInbound invoice received from an external system
invoice.acknowledgedInbound invoice acknowledged

Lifecycle — Both directions

Event IDDescription
invoice.failedInvoice processing failed at any stage
invoice.rejectedInvoice rejected by FIRS or the receiving party
invoice.canceledInvoice canceled
invoice.paidPayment confirmed for the invoice

ERP — Inbound (ERP → platform via webhook)

These are the event IDs your ERP sends in the X-Event-Type header when posting to the platform's inbound webhook URL.

Event IDDescription
erp.invoice.submittedInvoice submitted from the ERP into the platform
erp.invoice.updatedAn existing invoice was updated in the ERP
erp.invoice.voidedInvoice voided in the ERP
erp.invoice.canceledInvoice canceled in the ERP
erp.payment.receivedPayment recorded for an invoice in the ERP
erp.creditnote.issuedCredit note issued from the ERP
erp.debitnote.issuedDebit note issued from the ERP

System

Event IDDescription
test.eventTest event used to verify webhook connectivity

Workflow Actions

Workflow actions are the processing steps assigned to events in the Event Routing configuration.

Outbound actions (platform → FIRS)

Action IDEndpointDescription
transformPOST /api/v1/workflow/transformTransform the ERP invoice payload into FIRS UBL format
validatePOST /api/v1/workflow/validateValidate the transformed invoice against FIRS schema and business rules
signPOST /api/v1/workflow/signDigitally sign the validated invoice using tenant FIRS credentials
generate_irnPOST /api/v1/workflow/irn/generateGenerate an Invoice Reference Number (IRN)
transmitPOST /api/v1/workflow/transmitTransmit the signed invoice to the FIRS API
complete_outboundPOST /api/v1/workflow/outboundExecute the full outbound pipeline in one call: Transform → Validate → Sign → Transmit
process_credit_notePOST /api/v1/workflow/credit-noteProcess a credit note by fetching the original invoice and adapting it
sync_erpPOST /api/v1/workflow/erp-syncPush the processed invoice back to the tenant ERP using the configured sync endpoint and body template

Inbound actions

Action IDEndpointDescription
complete_inboundPOST /api/v1/workflow/inboundExecute the full inbound pipeline: receive, validate, and acknowledge an inbound invoice

Reporting actions

Action IDEndpointDescription
report_vatPOST /api/v1/workflow/vat-reportSubmit a VAT report for the invoice or reporting period to FIRS
confirm_invoice_statusGET /api/v1/workflow/status/:irnQuery FIRS to confirm the current status of a transmitted invoice
update_payment_statusPATCH /api/v1/workflow/invoices/outbound/:irn/payment-statusSubmit a VAT post-payment report to FIRS after payment is recorded on a delivered invoice

Event Routing Configuration

Event routing maps the event type from the incoming ERP webhook header to one or more workflow actions. You configure this per tenant from the Event Routing section under Webhooks in the admin settings, or via the admin API.

Get routing config

GET /v1/admin/tenants/{tenantId}/event-routing/
x-admin-key: YOUR_ADMIN_KEY

Set full routing config

PUT /v1/admin/tenants/{tenantId}/event-routing/
x-admin-key: YOUR_ADMIN_KEY
Content-Type: application/json

{
"routes": [
{
"event": "erp.invoice.submitted",
"actions": ["complete_outbound"],
"enabled": true,
"description": "Full outbound pipeline when ERP submits a new invoice"
},
{
"event": "erp.invoice.updated",
"actions": ["complete_outbound"],
"enabled": true,
"description": "Resubmit updated invoice through the full pipeline"
},
{
"event": "erp.payment.received",
"actions": ["update_payment_status"],
"enabled": true,
"description": "Submit FIRS VAT post-payment report when ERP records payment"
},
{
"event": "erp.creditnote.issued",
"actions": ["process_credit_note"],
"enabled": true,
"description": "Process credit note against the original IRN"
},
{
"event": "erp.debitnote.issued",
"actions": ["process_credit_note"],
"enabled": true,
"description": "Process debit note against the original IRN"
},
{
"event": "invoice.delivered",
"actions": ["sync_erp"],
"enabled": true,
"description": "Push completed invoice with IRN back to ERP after FIRS delivery"
}
]
}

Add a single route

POST /v1/admin/tenants/{tenantId}/event-routing/routes
x-admin-key: YOUR_ADMIN_KEY
Content-Type: application/json

{
"event": "erp.invoice.submitted",
"actions": ["complete_outbound"],
"enabled": true,
"description": "Full outbound pipeline on ERP invoice submission"
}

Clear all routes

DELETE /v1/admin/tenants/{tenantId}/event-routing/
x-admin-key: YOUR_ADMIN_KEY

Inbound Webhook — Receiving Invoices from Your ERP

Invoices enter the platform via an inbound webhook. The platform generates a unique webhook URL and webhook secret for each tenant. You copy these from the Webhooks settings page and register them in your ERP's outbound webhook configuration.

When your ERP fires an invoice event, it sends a POST request to the platform's webhook URL with:

  • The event type in the request headers
  • The invoice payload in the request body

The platform authenticates the request using the webhook secret, reads the event type from the headers, and executes the matching workflow actions from the Event Routing configuration. The invoiceIdKey is used to extract and store the unique invoice identifier from the payload.

Inbound webhook request format

POST https://platform.heirs.com/webhooks/{tenantId}
X-Event-Type: invoice.created
X-Webhook-Secret: whsec_...
Content-Type: application/json

{
"invoiceNumber": "INV-2026-001",
...
}

Outbound Webhook — Status Callbacks to Your ERP

After pipeline events fire (e.g. invoice.acknowledged), the platform can send status callbacks back to your ERP via a registered outbound webhook URL.

Registering an outbound webhook

PATCH /v1/tenants/{tenantId}
x-admin-key: YOUR_ADMIN_KEY
Content-Type: application/json

{
"webhookUrl": "https://yourapp.com/webhooks/heirs",
"webhookEnabled": true
}

Outbound webhook payload structure

{
"event": "invoice.acknowledged",
"tenantId": "ten_01j9ab2c3d4e5f6g",
"timestamp": "2026-06-17T10:30:00Z",
"data": {
"invoiceId": "INV-2026-001",
"irn": "IRN-2026-ACME-001",
"status": "acknowledged"
}
}

Delivery guarantees

PropertyDetail
ProtocolHTTPS POST only
Response timeout30 seconds — return 2xx within 30s
Retry policyUp to maxRetries (1–10) attempts, configurable
Test webhookPOST /v1/tenants/{tenantId}/webhook/test

:::caution Respond quickly Return a 2xx HTTP status immediately on receipt. If your processing takes longer, acknowledge first and handle in a background job. Failed deliveries are retried per your tenant's maxRetries setting. :::


ERP Sync

ERP Sync is the return-path configuration — it defines how the platform sends the finished invoice back to your ERP once FIRS has delivered and acknowledged it. It is implemented as the sync_erp workflow action (POST /api/v1/workflow/erp-sync), which pushes the completed invoice record (including the IRN and QR code stamp) to your ERP using a configured sync endpoint and Handlebars body template.

ERP Sync covers the outbound direction only (platform → ERP) and is a separate configuration menu from Event Routing. The typical trigger is mapping invoice.deliveredsync_erp in your Event Routing config.


Reference: Fetching Events and Actions at Runtime

Fetch the full event catalogue:

GET /v1/admin/config/reference/events
x-admin-key: YOUR_ADMIN_KEY

Filter by category or direction:

?category=lifecycle # lifecycle | payment | system | erp
?direction=inbound # inbound | outbound | both

Fetch all workflow actions:

GET /v1/admin/config/reference/workflow-actions
x-admin-key: YOUR_ADMIN_KEY

Filter by category:

?category=outbound # outbound | inbound | reporting