Webhooks
Get notified when things happen. Add HTTPS endpoints below and subscribe each to the events you care about (or '*' for all). Tax Star POSTs a signed JSON payload to your URL on every invoice status change — sending and receiving. Each delivery carries an X-Taxstar-Signature header: 't=<unix_ts>,v1=<hex>' where <hex> is HMAC-SHA256 of '{t}.{raw_body}' keyed with your signing_secret; respond with a 2xx to acknowledge. Webhooks are managed right here — sign in, add your URL, send a test delivery to verify the connection, and track deliveries in the charts.
Manage webhooks
Add webhook endpoints to your application, then send a test event to verify the connection before going live. Tax Star will POST a signed payload to your URL on every invoice status change — sending and receiving.
How delivery works
For each event matching one of your subscriptions, Tax Star sends an HTTP POST to your url with a JSON body and an X-Taxstar-Signature header. Return a 2xx status to acknowledge. Always verify the signature before trusting a payload.
{
"event": "invoice.sent",
"created_at": "2026-06-21T10:00:00Z",
"data": {
"direction": "sent",
"invoice_id": "6a3e3e160c9fbfd76f261711",
"invoice_number": "INV-1001",
"entity_id": "6a3e388e7a5b528a20bc5149",
"status": {
"code": "SENT_TO_PEPPOL",
"message": "Invoice sent to Billberry successfully",
"created_at": "2026-06-21T10:00:00Z"
}
}
}// Node.js (Express) — verify an incoming Taxstar webhook
import crypto from "crypto";
function verify(req, signingSecret) {
// header: "X-Taxstar-Signature: t=<unix_ts>,v1=<hex hmac-sha256>"
const header = req.headers["x-taxstar-signature"] || "";
const parts = Object.fromEntries(
header.split(",").map((kv) => kv.split("="))
);
const t = parts.t;
const signed = `${t}.${req.rawBody}`; // raw, unparsed JSON body
const expected = crypto
.createHmac("sha256", signingSecret)
.update(signed)
.digest("hex");
// constant-time compare; optionally reject if |now - t| is too large
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1 || "")
);
}Received-invoice events carry invoice_number and receiver_registry_code in data instead of invoice_id, with direction: "received".