API Reference

Complete reference for the HostWebhook REST API — ingress, webhook management, additional targets, and event operations.

Base URL

https://api.hostwebhook.com
Management webhooks require an authenticated session. Log in at hostwebhook.com or use hostwh login — the dashboard and CLI handle authentication automatically.

Ingress (webhook receiver)

This is the only public webhook. No authentication required — the ingress token in the URL identifies the webhook.
POST/api/in/:tokenpublic

Accept an incoming webhook. Responds immediately with 202 Accepted. The payload is stored and queued for delivery.

Path / query params

tokenstringrequiredIngress token from the webhook
HTTP 202 Accepted
{ "eventId": "64f1a2b3c4d5e6f7a8b9c0d1" }

Webhooks

List webhooks

GET/webhooks

List all webhooks for the authenticated user/organization.

[{ "id": "...", "name": "Stripe prod", "targetUrl": "https://...", "isActive": true, ... }]

Create webhook

POST/webhooks

Create a new webhook. Returns the webhook with its ingress URL and signing secret.

Request body

namestringrequiredFriendly label
targetUrlstringYour server's webhook handler URL (optional — leave empty for notification-only webhooks)
descriptionstringOptional description
isActivebooleanWhether to accept deliveries (default: true)
maxRetriesnumber0–20 (default: 3)
retryDelaySecondsnumberBase delay for exponential backoff (default: 60, min: 10)
rateLimitPerMinutenumberMax deliveries per minute — 0 = unlimited (default: 0)
incomingSignatureTypestringVerify inbound signatures: none | stripe | github | custom (default: none)
incomingSignatureSecretstringSecret used to verify inbound signatures (required if type ≠ none)
payloadFiltersPayloadFilter[]Rules to discard events before delivery
degradedAfternumberConsecutive failures before health → degraded (default: 2)
downAfternumberConsecutive failures before health → down (default: 4)
{
  "id": "...",
  "name": "Stripe prod",
  "targetUrl": "https://yourapp.com/webhooks",
  "ingressToken": "tok_...",
  "signingSecret": "whsec_...",
  "isActive": true,
  "maxRetries": 3,
  "retryDelaySeconds": 60,
  "rateLimitPerMinute": 0,
  "incomingSignatureType": "stripe",
  "payloadFilters": [],
  "healthStatus": "healthy",
  "createdAt": "2024-05-01T12:00:00.000Z"
}

Get webhook

GET/webhooks/:id

Get a single webhook by ID.

Path / query params

idstringrequiredWebhook ID

Update webhook

PUT/webhooks/:id

Update any webhook field. All fields are optional — only provided fields are updated.

Path / query params

idstringrequiredWebhook ID

Request body

namestring
targetUrlstring
descriptionstring
maxRetriesnumber
retryDelaySecondsnumber
rateLimitPerMinutenumber
isActiveboolean
incomingSignatureTypestring
incomingSignatureSecretstring
payloadFiltersPayloadFilter[]Replaces the full filter list

Delete webhook

DELETE/webhooks/:id

Permanently delete a webhook and all its events.

Path / query params

idstringrequiredWebhook ID
204 No Content

Toggle active

PATCH/webhooks/:id/toggle-active

Toggle the webhook's isActive status (pause/activate).

Path / query params

idstringrequiredWebhook ID
{ "isActive": false }

Rotate ingress token

PATCH/webhooks/:id/rotate-token

Generate a new ingress token. The old ingress URL stops working immediately.

Path / query params

idstringrequiredWebhook ID
{ "ingressToken": "tok_newtoken..." }

Rotate signing secret

PATCH/webhooks/:id/rotate-signing-secret

Generate a new signing secret. The old secret stops working immediately.

Path / query params

idstringrequiredWebhook ID
{ "signingSecret": "whsec_newsecret..." }

Payload Filters

Payload filters discard events before delivery. Only events matching all rules are delivered — non-matching events are marked filtered.

PayloadFilter object

FieldTypeDescription
fieldstringDot-notation path (e.g. data.object.status)
operatorstringeq | neq | contains | gt | lt | exists | not_exists | in | not_in
valuestring?Comparison value — not required for exists / not_exists

Example

{
  "payloadFilters": [
    { "field": "type", "operator": "eq", "value": "invoice.paid" },
    { "field": "data.object.amount_paid", "operator": "gt", "value": "1000" }
  ]
}

Additional targets

Additional targets are separate resources linked to one or more webhooks. When an event arrives, all active additional targets attached to it are delivered in parallel — each with its own retry budget, filters, and optional payload transform.

Additional target object

FieldTypeDescription
idstringUnique ID
namestringFriendly label
urlstringDestination URL
isActivebooleanEnable/disable without removing (default: true)
maxRetriesnumber?Override retry count (plan-limited: Free max 3, Pro max 10)
inputNodes{ nodeType, nodeId }[]Upstream nodes that feed this one. nodeType is the node kind (webhook, scheduledWorkflow, filter, …)
filtersPayloadFilter[]Per-target payload filters
payloadTransformstring?JSON template with {{path}} interpolation — reshapes payload before delivery
notifyPrimaryOnFailurebooleanWhen true: POST a target.failed notification to the webhook's primary targetUrl if this additional target exhausts all retries (default: false)

List additional targets

GET/additional-targets

List all additional targets for the authenticated user/organization.

[{ "id": "...", "name": "Stripe → Discord", "url": "https://discord.com/...", "inputNodes": [{ "nodeType": "webhook", "nodeId": "..." }], ... }]

Create additional target

POST/additional-targets

Create a new additional target linked to one or more webhooks.

Request body

namestringrequiredFriendly label
urlstringrequiredDestination URL
isActivebooleanDefault: true
maxRetriesnumberAdditional attempts after a failure (plan-limited: Free max 3, Pro max 10)
filtersPayloadFilter[]Per-target payload filters
payloadTransformstringJSON template string with {{path}} expressions
notifyPrimaryOnFailurebooleanPOST a target.failed notification to the webhook's primary targetUrl when this additional target permanently fails (default: false)
{
  "id": "...",
  "name": "Stripe → Discord",
  "url": "https://discord.com/api/webhooks/...",
  "isActive": true,
  "inputNodes": [{ "nodeType": "webhook", "nodeId": "ep_abc123" }],
  "filters": [],
  "payloadTransform": "{ \"embeds\": [...] }",
  "createdAt": "..."
}

Get additional target

GET/additional-targets/:id

Get a single additional target by ID.

Path / query params

idstringrequiredAdditional target ID

Update additional target

PUT/additional-targets/:id

Update an additional target. All fields are optional.

Path / query params

idstringrequiredAdditional target ID

Request body

namestring
urlstring
isActiveboolean
maxRetriesnumber
filtersPayloadFilter[]Replaces the full filter list
payloadTransformstring | nullSet to null to remove the transform
notifyPrimaryOnFailureboolean

Delete additional target

DELETE/additional-targets/:id

Permanently delete an additional target.

Path / query params

idstringrequiredAdditional target ID
204 No Content

Events

List events

GET/events

List events with optional filters. Returns paginated results.

Path / query params

webhookIdstringFilter by webhook
statusstringpending | delivered | retrying | failed | filtered
eventTypestringMatch the top-level type or event field in the payload
dateFromstringISO 8601 date (inclusive)
dateTostringISO 8601 date (inclusive)
pagenumberPage number (default: 1)
limitnumberResults per page (default: 15, max: 100)
{
  "data": [{ "id": "...", "status": "delivered", "createdAt": "...", ... }],
  "total": 142,
  "page": 1,
  "limit": 15
}

Get distinct event types

GET/events/types

Get all distinct event types (top-level type field) seen on a webhook. Used to populate filter dropdowns.

Path / query params

webhookIdstringFilter to one webhook
["payment_intent.succeeded", "payment_intent.created", "customer.subscription.updated"]

Get event

GET/events/:id

Get a single event with its full payload.

Path / query params

idstringrequiredEvent ID

Delivery attempts

GET/events/:eventId/deliveries

List all delivery attempts for an event, including response body, latency, and target info.

Path / query params

eventIdstringrequired
[{
  "id": "...",
  "targetUrl": "https://yourapp.com/webhooks",
  "isAdditionalTarget": false,
  "attempt": 1,
  "statusCode": 200,
  "responseBody": "ok",
  "latencyMs": 143,
  "success": true,
  "attemptedAt": "2024-05-01T12:00:00.000Z"
}]

Replay event

POST/events/:eventId/replay

Manually replay an event. Creates a new delivery attempt with the original payload.

Path / query params

eventIdstringrequired
{ "ok": true }

Replay all failed

POST/events/replay-all

Replay all failed events for a webhook.

Path / query params

webhookIdstringrequiredQuery param
{ "queued": 12 }

Cancel event

POST/events/:eventId/cancel

Cancel a pending or retrying event. Cannot be undone, but can be replayed.

Path / query params

eventIdstringrequired
204 No Content

Delivery stats

GET/events/stats

Aggregate delivery stats for the current user.

Path / query params

webhookIdstringFilter to one webhook
{ "total": 1200, "delivered": 1180, "failed": 20, "successRate": 98.3 }

Latency stats

GET/events/latency

Latency percentiles (ms) for successful deliveries.

Path / query params

webhookIdstringFilter to one webhook
{ "avg": 210, "p95": 580, "p99": 1240 }

Routers

GET/routers

List all routers.

POST/routers

Create a router with conditional routing rules.

Request body

namestringrequiredRouter name
routesRoute[]Array of {field, operator, value, outputWebhookId}
PATCH/routers/:id

Update a router.

Path / query params

idstringrequired
DELETE/routers/:id

Delete a router.

Path / query params

idstringrequired
204 No Content

Filter Nodes

GET/filter-nodes

List all filter nodes.

POST/filter-nodes

Create a filter node.

Request body

namestringrequiredFilter name
filterModestring'and' | 'or' (default: 'and')
filtersFilter[]Array of {field, operator, value}
PATCH/filter-nodes/:id

Update a filter node.

Path / query params

idstringrequired
DELETE/filter-nodes/:id

Delete a filter node.

Path / query params

idstringrequired
204 No Content

Transform Nodes

GET/transform-nodes

List all transform nodes.

POST/transform-nodes

Create a transform node.

Request body

namestringrequiredTransform name
transformModestring'handlebars' | 'jq' | 'javascript'
templatestringTransform template string
PATCH/transform-nodes/:id

Update a transform node.

Path / query params

idstringrequired
DELETE/transform-nodes/:id

Delete a transform node.

Path / query params

idstringrequired
204 No Content

Schema Validators

GET/schema-validators

List all schema validators.

POST/schema-validators

Create a schema validator.

Request body

namestringrequiredValidator name
strictModebooleanReject payloads with extra fields (default: false)
fieldsField[]Array of {path, type, required, constraints}
PATCH/schema-validators/:id

Update a schema validator.

Path / query params

idstringrequired
DELETE/schema-validators/:id

Delete a schema validator.

Path / query params

idstringrequired
204 No Content

Delay Nodes

GET/delay-nodes

List all delay nodes.

POST/delay-nodes

Create a delay node.

Request body

namestringrequiredDelay name
delaySecondsnumberrequiredSeconds to delay before forwarding
PATCH/delay-nodes/:id

Update a delay node.

Path / query params

idstringrequired
DELETE/delay-nodes/:id

Delete a delay node.

Path / query params

idstringrequired
204 No Content

Merge Nodes

GET/merge-nodes

List all merge nodes.

POST/merge-nodes

Create a merge node.

Request body

namestringrequiredMerge name
modestring'wait_all' | 'first' (default: 'wait_all')
expectedBranchCountnumberNumber of branches to wait for
PATCH/merge-nodes/:id

Update a merge node.

Path / query params

idstringrequired
DELETE/merge-nodes/:id

Delete a merge node.

Path / query params

idstringrequired
204 No Content

Approval Nodes

GET/approval-nodes

List all approval nodes.

POST/approval-nodes

Create an approval node.

Request body

namestringrequiredApproval gate name
timeoutMinutesnumberAuto-action after timeout (default: 60)
autoActionOnTimeoutstring'approve' | 'reject' (default: 'reject')
notifyEmailsstring[]Emails to notify for approval
POST/approval-nodes/:id/approve

Approve a pending event at this gate.

Path / query params

idstringrequired
POST/approval-nodes/:id/reject

Reject a pending event at this gate.

Path / query params

idstringrequired
PATCH/approval-nodes/:id

Update an approval node.

Path / query params

idstringrequired
DELETE/approval-nodes/:id

Delete an approval node.

Path / query params

idstringrequired
204 No Content

Email Actions

GET/email-actions

List all email actions.

POST/email-actions

Create an email action.

Request body

namestringrequiredEmail action name
tostringrequiredRecipient email
subjectstringEmail subject (supports templates)
bodystringEmail body (supports templates)
triggerOnstring'success' | 'failure' | 'always'
PATCH/email-actions/:id

Update an email action.

Path / query params

idstringrequired
DELETE/email-actions/:id

Delete an email action.

Path / query params

idstringrequired
204 No Content

Gmail

GET/gmail-actions

List all Gmail nodes.

POST/gmail-actions

Create a Gmail node.

Request body

namestringrequiredGmail node name
credentialIdstringConnected Google account
operationstringOne of the 17 operations (default: 'send')
operationConfigobjectParameters for the chosen operation (supports templates)
aiEnabledbooleanExpose the 16-tool toolkit to an AI Node
triggerOnstring'success' | 'always'
PATCH/gmail-actions/:id

Update a Gmail node.

Path / query params

idstringrequiredGmail node ID
DELETE/gmail-actions/:id

Delete a Gmail node.

Path / query params

idstringrequiredGmail node ID
GET/gmail-actions/labels/:credentialId

List the account's Gmail labels.

Path / query params

credentialIdstringrequiredConnected Google account

HTTP Actions

GET/http-actions

List all HTTP actions.

POST/http-actions

Create an HTTP action.

Request body

namestringrequiredHTTP action name
urlstringrequiredTarget URL
methodstringGET | POST | PUT | PATCH | DELETE (default: POST)
headersobjectCustom headers
bodystringRequest body template
triggerOnstring'success' | 'failure' | 'always'
PATCH/http-actions/:id

Update an HTTP action.

Path / query params

idstringrequired
DELETE/http-actions/:id

Delete an HTTP action.

Path / query params

idstringrequired
204 No Content

MongoDB Actions

GET/mongo-actions

List all MongoDB actions.

POST/mongo-actions

Create a MongoDB action.

Request body

namestringrequiredAction name
connectionUristringrequiredMongoDB connection string (encrypted)
databasestringrequiredDatabase name
collectionstringrequiredCollection name
operationstring'insertOne' | 'updateOne' | 'replaceOne'
documentstringDocument template
PATCH/mongo-actions/:id

Update a MongoDB action.

Path / query params

idstringrequired
DELETE/mongo-actions/:id

Delete a MongoDB action.

Path / query params

idstringrequired
204 No Content

Notification Actions

GET/notification-actions

List all notification actions (Slack/Discord).

POST/notification-actions

Create a notification action.

Request body

namestringrequiredAction name
platformstringrequired'slack' | 'discord'
webhookUrlstringrequiredPlatform webhook URL
templatePresetstring'default' | 'detailed' | 'minimal' | 'custom'
triggerOnstring'success' | 'failure' | 'always'
PATCH/notification-actions/:id

Update a notification action.

Path / query params

idstringrequired
DELETE/notification-actions/:id

Delete a notification action.

Path / query params

idstringrequired
204 No Content

Google Sheets Actions

GET/sheets-actions

List all Google Sheets actions.

POST/sheets-actions

Create a Sheets action.

Request body

namestringrequiredAction name
spreadsheetIdstringrequiredGoogle Sheets spreadsheet ID
sheetNamestringSheet tab name (default: Sheet1)
operationstring'append_row' | 'update_cell'
columnsstring[]Template array mapping payload fields to columns
PATCH/sheets-actions/:id

Update a Sheets action.

Path / query params

idstringrequired
DELETE/sheets-actions/:id

Delete a Sheets action.

Path / query params

idstringrequired
204 No Content

Scheduled Workflows

GET/scheduled-workflows

List all scheduled webhooks.

POST/scheduled-workflows

Create a scheduled webhook (cron-based HTTP calls).

Request body

namestringrequiredName
cronExpressionstringrequiredCron expression (e.g. '0 */5 * * *')
urlstringTarget URL (or connect to a webhook)
methodstringHTTP method (default: POST)
headersobjectCustom headers
bodystringRequest body
isActivebooleanEnable/disable (default: true)
PATCH/scheduled-workflows/:id

Update a scheduled webhook.

Path / query params

idstringrequired
DELETE/scheduled-workflows/:id

Delete a scheduled webhook.

Path / query params

idstringrequired
204 No Content

Canvas Snapshots

GET/canvas-snapshots

List all canvas snapshots.

POST/canvas-snapshots

Save a canvas snapshot (nodes + edges layout).

Request body

namestringrequiredSnapshot name
nodesobject[]requiredReactFlow nodes array
edgesobject[]requiredReactFlow edges array
GET/canvas-snapshots/:id

Get a single snapshot.

Path / query params

idstringrequired
DELETE/canvas-snapshots/:id

Delete a snapshot.

Path / query params

idstringrequired
204 No Content

Time Travel

POST/events/:id/time-travel

Dry-run replay an event through a historical canvas snapshot.

Request body

snapshotIdstringrequiredCanvas snapshot ID to simulate against
{
  "steps": [{ "node": "schema-validator", "name": "...", "result": "pass" }, ...],
  "finalStatus": "delivered",
  "matchedNodes": 4
}

Contract Testing

GET/events/:webhookId/contract-health

Validate recent events against connected schema validators.

Path / query params

webhookIdstringrequiredWebhook ID
limitnumberNumber of recent events to check (default: 100)
{
  "score": 94,
  "totalChecked": 100,
  "passed": 94,
  "failed": 6,
  "validators": [{ "id": "...", "name": "...", "passRate": 94 }]
}

Errors

All error responses follow a consistent shape:

{
  "statusCode": 400,
  "message": "targetUrl must be a URL address",
  "error": "Bad Request"
}
StatusMeaning
400Bad Request — invalid or missing parameters
401Unauthorized — missing or expired session
403Forbidden — resource belongs to another user, or plan limit exceeded
404Not Found — resource doesn't exist
429Too Many Requests — rate limit exceeded
500Internal Server Error — something went wrong on our end