cardano.deliveryCardano webhooks

Documentation

cardano.delivery pushes signed HTTP notifications to your endpoint when events are confirmed on Cardano mainnet. Free for everyone.

Getting started

  1. Create an account and sign in.
  2. Click New webhook, pick a trigger type, set your target URL and how many confirmations to wait for.
  3. Optionally add conditions to filter events - all conditions must match.
  4. Save. Deliveries start with the next matching confirmed event (usually within a block or two, ~20–40 seconds).
Need a quick test endpoint? Point your first webhook at a URL from webhook.site and watch events arrive live.

Webhook types

TypeFiresPayload contains
transactionfor each matching transaction in a confirmed blocktransaction details, inputs/outputs (UTxOs)
blockonce per confirmed blockblock header: height, hash, slot, pool, fees, …
delegationfor each matching stake delegationtransaction + delegation certificates and pool info
epochat each epoch transitionprevious and current epoch numbers
proposalwhen a new governance action is submitted on-chainfull proposal detail (type, deposit, expiration, …) + the submitting transaction
votewhen a vote is cast on a recent governance actionthe vote (voter, role, yes/no/abstain) + the proposal it belongs to
poolper confirmed block containing pool registrations, updates or retirementsthe transaction + pool certificates
withdrawalper confirmed block containing reward withdrawalsthe transaction + withdrawals (stake address, amount)
mintper confirmed block containing asset mints or burnsthe transaction + minted/burned assets (unit, policy, quantity, action)
scriptper confirmed block containing Plutus script executionsthe transaction + redeemers (script hash, purpose, execution units)
drepwhen a DRep registers (any DRep), or when a watched DRep deregisters or votesaction (registered/deregistered/voted), the DRep (id, voting power, status), and the vote + proposal id for voted
accountwhen a watched stake account changes (balance, rewards, delegation)previous and current account state
Delivery semantics: proposal, vote and drep events are delivered on detection (typically within a minute of on-chain inclusion) and have no confirmation setting; votes are watched on the most recent open proposals until their voting period expires. account webhooks require a stakeAddress = condition and are polled every ~5 minutes. drep registrations cover every DRep; deregistered and voted actions require a drepId = condition (the DRep is then watched every ~5 minutes). All other types follow your chosen confirmation depth like blocks and transactions.

Confirmations

Each webhook waits for the number of confirmations you choose (1–10) before firing. One confirmation means the event fires as soon as the block after it is minted; ten gives you near-certain finality at the cost of a few minutes of latency. If the chain rolls back before your confirmation depth is reached, the event is not delivered.

Conditions

Conditions filter which events fire your webhook. All conditions must match (logical AND). A webhook without conditions fires for every event of its type.

ConditionApplies toOperatorsExample value
recipienttransaction= !=addr1… or stake1…
sendertransaction= !=addr1… or stake1…
quantitytransaction< <= = > >= !=1000000 (lovelace)
policyIdtransaction= !=56-char hex policy ID
fingerprinttransaction= !=asset1…
assetHextransaction= !=policy ID + hex asset name
poolIdblock, delegation= !=pool1…
txCount size height totalFees totalOutputblock< <= = > >= !=500
epochepoch< <= = > >= !=600
governanceTypeproposal= !=treasury_withdrawals, parameter_change, hard_fork_initiation, info_action, no_confidence, new_committee, new_constitution
voterRolevote= !=drep, spo, constitutional_committee
votervote= !=drep1… / pool1…
votevote= !=yes, no, abstain
govActionIdvote= !=gov_action1…
actionpool, mint, drep= !=update/retire · mint/burn · registered/deregistered/voted
stakeAddresswithdrawal, account= !=stake1… (account requires =)
amountwithdrawal< <= = > >= !=lovelace
assetHexmint= !=policy ID + hex asset name
quantitymint< <= = > >= !=absolute amount
scriptHash purposescript= !=hex hash · spend/mint/cert/reward
unitMem unitStepsscript< <= = > >= !=execution budget
drepIddrep= !=drep1…
jsonPathall types< <= = > >= !=selector $.tx.hash, value to compare

jsonPath conditions evaluate a JSONPath selector against the event payload and compare the result to your value - an escape hatch for anything the built-in conditions don't cover.

Delivery payload

Your endpoint receives an HTTP POST with a JSON body:

{
  "id": "47668401-c3a8-42c3-93ed-6c0e1abcf1c0",   // unique event id (stable across retries)
  "webhook_id": "b592db93-4bb9-4bd0-a196-…",      // which webhook fired
  "created": 1754255963,                            // unix timestamp of the event
  "api_version": 1,
  "type": "block",                                 // transaction | block | delegation | epoch
  "payload": { /* event data for the type */ }
}

Requests are sent with User-Agent: cardano-delivery and time out after 10 seconds. Event ids are deterministic - if you ever receive a duplicate, deduplicate by id.

Verifying signatures

Every delivery includes a Delivery-Signature header so you can verify the request came from cardano.delivery and was not tampered with:

Delivery-Signature: t=1754255965,v1=f4d1ede9…

t is a unix timestamp, v1 is HMAC-SHA256(secret, `${t}.${rawRequestBody}`) in hex, using your webhook's secret (shown in the dashboard under Secret).

Node.js example

import { createHmac, timingSafeEqual } from 'node:crypto';

const verify = (rawBody, signatureHeader, secret) => {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map(kv => kv.split('=')),
  );
  const expected = createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');
  // reject stale timestamps to prevent replay (e.g. older than 10 minutes)
  if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 600) return false;
  return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
};

Retries & history

Use cases

Limits

PriceFree
NetworkCardano mainnet
Webhooks per account5
Conditions per webhook10
Confirmations1–10
Delivery timeout10 s
Target URLspublic http(s) endpoints only - private and internal addresses are rejected

FAQ

Which networks are supported?

Cardano mainnet. Preprod/preview support may come later if there's demand.

Can I get the same event twice?

Under rare failure conditions a delivery can be repeated. Event ids are deterministic, so deduplicating by id makes processing idempotent.

What happens during a chain rollback?

Events are only delivered once your chosen confirmation depth is reached. Higher confirmations (e.g. 5–10) make rollback delivery practically impossible.

Can AI agents use this without an account?

Yes. One unauthenticated POST creates a self-expiring webhook (up to 24h), and inbox mode lets the agent poll matched events instead of hosting an endpoint. See the ephemeral API and llms.txt.

Need help?

Write to support@cardano.delivery.

Is there an API?

Yes - manage webhooks programmatically with API keys. See the API reference.

Open the dashboard →