Properties
| Name | Type | Description |
|---|---|---|
| name | string | Friendly name for the webhook (e.g. "CF Pages deploy hook") |
| url | string | Target URL — POSTed on subscribed events |
| events | array | Subscribed event names. Empty array = all events fire this webhook. Known events: `listing.created`, `listing.updated`, `listing.deleted` — fired on writes via either admin or public API; `submission. |
| isActive | boolean | Disable without deleting |
| secret | string | Shared secret for HMAC-SHA256 payload signing. When set, every dispatch includes an `X-ED-Signature: sha256= |
| debounceMs | number | Debounce window in milliseconds. Multiple events within the window collapse to a single dispatch — useful for collapsing bulk imports into one rebuild. NULL inherits the global default (30 000ms / 30s |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/api-evangelist/epicdirectories/main/json-schema/epicdirectories-create-webhook-dto-schema.json",
"title": "CreateWebhookDto",
"x-generated": "2026-10-02",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/epicdirectories-openapi.json#/components/schemas/CreateWebhookDto",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Friendly name for the webhook (e.g. \"CF Pages deploy hook\")"
},
"url": {
"type": "string",
"description": "Target URL — POSTed on subscribed events"
},
"events": {
"type": "array",
"description": "Subscribed event names. Empty array = all events fire this webhook. Known events: `listing.created`, `listing.updated`, `listing.deleted` — fired on writes via either admin or public API; `submission.received` — an anonymous suggestion or feedback item needs review. Fired ONLY for items that reach `pending`; spam (honeypot or failed Turnstile) is stored silently and never notifies, so the channel stays worth reading. Payload: `{ submissionId, kind, listingId }`; `review.received` — a public review is waiting for moderation. Like `submission.received`, fired ONLY for items that reach `pending`. Payload: `{ reviewId, listingId, rating }`; `review.approved` — a review was published and the listing's rating average moved. Consumers that render ratings from a build-time export need this one to know to rebuild. Payload: `{ reviewId, listingId, rating }`; `review.rejected` — a review that WAS published is no longer public, because it was unpublished, rejected or filed as spam. The mirror of `review.approved`, and the more urgent of the pair: it is what a consumer rebuilds on to take defamatory or abusive text off their site. Fired ONLY on the `approved` -> not-approved transition — rejecting a pending review was never public and fires nothing. Payload: `{ reviewId, listingId, rating }`; `comment.received` — a page comment is waiting for moderation. Fired ONLY for items that reach `pending`. Payload: `{ commentId, path }`; `comment.approved` — a page comment was published. A static site that renders comments rebuilds on this. Payload: `{ commentId, path }`; `comment.rejected` — a page comment that WAS published is no longer public (rejected, unpublished or filed as spam). Fired ONLY on the `approved` -> not-approved transition; subscribe to it if you render comments, since it is what takes one down. Payload: `{ commentId, path }`; `comment.updated` — the editors' reply on a currently-approved comment was set, changed or cleared. Not fired for replies on unpublished comments. Payload: `{ commentId, path }`; `listing.boosted` — a listing became a premium listing, by purchase or by an operator grant. Payload: `{ listingId, paymentId?, amountCents?, currency? }`. A `listing.updated` is ALWAYS fired alongside it, so a consumer already subscribed to that will rebuild without subscribing to this one; subscribe to this if you want to treat a boost specially. `test.ping` — only fired from the test endpoint, bypasses debounce. Unknown names are REJECTED with 400. They used to be accepted for forward-compat, but a typo then produced a webhook that looked healthy and never fired — subscribe to a new event once it exists.",
"items": {
"type": "string",
"enum": [
"listing.created",
"listing.updated",
"listing.deleted",
"submission.received",
"review.received",
"review.approved",
"review.rejected",
"comment.received",
"comment.approved",
"comment.rejected",
"comment.updated",
"listing.boosted",
"order.received",
"order.delivered",
"directory.updated",
"test.ping"
]
}
},
"isActive": {
"type": "boolean",
"description": "Disable without deleting"
},
"secret": {
"type": "string",
"description": "Shared secret for HMAC-SHA256 payload signing. When set, every dispatch includes an `X-ED-Signature: sha256=<hex>` header — verify on your end by computing HMAC-SHA256 of the raw request body using this secret. Verify each ATTEMPT on its own bytes: a retry re-serialises the body with a fresh `timestamp`, so the signature legitimately differs between attempts of the same delivery. To deduplicate, use `X-ED-Delivery-Id`, which is stable across all attempts — see §13 of the integrator changelog. If unset, no signature header is sent (delivery still works). Write-only: no endpoint ever returns it, not even the create response. Responses carry `hasSecret: true|false` instead. Store your copy at the point you generate it — if you lose it, PATCH a new one rather than expecting to read the old one back."
},
"debounceMs": {
"type": "number",
"description": "Debounce window in milliseconds. Multiple events within the window collapse to a single dispatch — useful for collapsing bulk imports into one rebuild. NULL inherits the global default (30 000ms / 30s). Range: 0 (no debounce) to 600 000 (10 minutes) — the full range is honoured, including values ABOVE the global default, which used to be silently capped. When multiple webhooks for a directory specify different values, the smallest wins for the directory as a whole; webhooks leaving it NULL express no preference and do not drag the others down — v1 limitation.",
"minimum": 0,
"maximum": 600000
}
},
"required": [
"url"
]
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/epicdirectories-create-webhook-dto"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.