Skip to main content

Webhook Tools

These tools let an AI client manage your workspace's webhook subscriptions — arrangements to POST an event to a URL when something happens in CheckFlow — and look at what was actually delivered. They mirror the Webhooks REST routes. Subscriptions have no page in the app, so the API and these tools are the only way to see them.

Three things about webhooks shape every tool on this page:

  • Event names are opaque identifiers, matched exactly, case included. Six are snake_case — new_checklist, task_completed, file_uploaded, checklist_completed, comment_created, task_assigned — and three are dotted — data_set.record.created, data_set.record.updated, data_set.record.deleted. A plausible correction such as task.completed is refused.
  • Every key in a subscription's scope is a template-level key. A checklist's task carries the key of the template task it was made from, so a subscription scoped to a task fires for that task in every checklist started from the template, not for one task on one checklist. There is no way to subscribe to a single occurrence. The exception is a standalone task, whose key is its own.
  • The signing secret never passes through these tools. Deliveries are signed with a CF-Signature header, but a tool result ends up in a transcript, so create_webhook does not return the secret and there is no tool to rotate it. Whoever owns the integration calls POST /v3/webhooks/{id}/rotate-secret over the REST API, which issues a secret and returns it once. Until they do, the receiving end cannot check the signature.

A delivery that fails is posted again — up to five attempts over about three hours, every one carrying the same CF-Delivery-Id — and then dropped; nothing is replayed automatically. Ten consecutive events that fail to be delivered switch a subscription off. For the product-level introduction, see Web Hooks.

How to Read This Page​

Every tool acts on the workspace your API key belongs to, as the member (or the workspace) the key acts as. There is no workspace argument. See Connecting.

  • The Read/Write column in the summary table says whether a tool can change anything.
  • Annotations are the hints a tool publishes to your client: readOnlyHint, destructiveHint and idempotentHint. A hint a tool does not declare is left out of its definition, and the MCP specification tells a client to assume the cautious default in that case — that the tool may write, may be destructive and is not idempotent. See Tool Annotations.
  • idempotencyKey appears on the write tools that accept it. It is optional and at most 255 characters. If a call times out or its answer is lost, send it again with the same key and the same arguments: the first call's answer comes back, marked checkflow.io/idempotentReplay in the result's _meta, instead of the work happening twice. The same key with different arguments is refused with CONFLICT, and so is a retry while the first call is still running. See Idempotency.
  • Refusals come back as an ordinary tool result with isError set. structuredContent carries the v3 error body — code, message, requestId and field — and the text block summarises it. See Errors and How It Works.
  • A tool that returns nothing, such as a delete, answers with a result that is not flagged isError and carries no data.

Two REST routes have no tool. GET /v3/webhooks/{id}/deliveries/{deliveryId} returns a delivery's payload — your workspace's own data — and is left to a person rather than put into a transcript. POST /v3/webhooks/{id}/rotate-secret returns a secret, for the reason above.

Tool Summary​

ToolWhat it doesRead/Write
list_webhooksLists the workspace's webhook subscriptionsRead
get_webhookReturns one subscriptionRead
list_webhook_deliveriesLists a subscription's delivery attemptsRead
replay_webhook_deliveryPosts one delivery again, nowWrite
create_webhookCreates a subscriptionWrite
update_webhookChanges a subscription's target, label or active stateWrite
delete_webhookDeletes a subscriptionWrite

list_webhooks​

Lists the workspace's webhook subscriptions, newest first. It is the way to find out whether an integration that thinks it subscribed actually did. The description tells the model how to read each row:

  • isActive false means the subscription is skipped when its event fires; nothing is queued while it is paused and nothing is replayed when it resumes.
  • On an inactive row, a disabledReason means the platform switched it off after ten consecutive failed events; no disabledReason means a person paused it. Those need opposite advice.
  • consecutiveFailures above zero on an active row means the receiver is currently missing events.

Reactivating is update_webhook with isActive true, which clears the counter and the reason and replays nothing.

NameTypeRequiredDescription
eventTypestringNoOnly subscriptions to this event — one of the nine event names, matched exactly. Anything else is refused.
sourcestringNoOnly subscriptions carrying this label, ignoring case. ALL means the label ALL, not "no filter".
isActivebooleanNotrue for delivering subscriptions, false for paused ones. Omit for both.
sortstringNofield, field:asc or field:desc, where field is createdDateTime, eventType or targetUrl. Default createdDateTime:desc.
afterstringNoThe nextCursor from the previous page. Send the same filters with it.
pageSizeintegerNoResults per page, 1 to 100. Default 50. A value outside the range is not refused; the default of 50 is used instead.
  • Returns: the standard list envelope (see Pagination) holding Webhook objects, each with id, eventType, targetUrl, source, isActive, consecutiveFailures, scope, createdDateTime and, when it applies, disabledDateTime and disabledReason.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/webhooks.
  • Example prompt: "What webhooks are set up in our CheckFlow workspace, and are any of them failing?"

get_webhook​

Returns one subscription by the id create_webhook returned — the same row list_webhooks shows. It lets an integration holding an id check that its subscription still exists and is active without paging through the workspace. An id belonging to another workspace is refused with WEBHOOK_NOT_FOUND.

NameTypeRequiredDescription
webhookIdstringYesThe subscription's id, from list_webhooks or create_webhook.
  • Returns: a Webhook object.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/webhooks/{id}.
  • Example prompt: "Is the webhook we set up for the accounts system still active?"

list_webhook_deliveries​

Lists every attempt to deliver one subscription's events, newest first: what fired, what the receiving end answered, how long it took and what went wrong. The description calls it the first tool to reach for when somebody says a webhook is not working, because it separates two cases that look the same from everywhere else — an empty list means the subscription is not firing (a scope or event problem), and a list of failures means it is firing into an endpoint that will not accept it.

Each row's outcome is one of:

OutcomeMeaning
deliveredThe receiver answered with a 2xx.
failedRequests were made and none got a 2xx; the platform has stopped trying.
refusedNo request was made, because the target resolved to an address inside CheckFlow's own network. Retrying will not fix it.
pendingNot delivered yet and another attempt is queued. Not a failure, and not something to replay.

Rows carry no payload. The history goes back 30 days.

NameTypeRequiredDescription
webhookIdstringYesThe subscription's id, from list_webhooks.
outcomestringNodelivered, failed, refused or pending, ignoring case. Anything else is refused. Paging through pending can skip a row that lands while you read.
afterstringNoThe nextCursor from the previous page. Send the same filters with it.
pageSizeintegerNoResults per page, 1 to 100. Default 50. A value outside the range is not refused; the default of 50 is used instead.
  • Returns: the standard list envelope holding Delivery objects without payload or targetUrl, each with id, webhookId, eventType, outcome, statusCode, failure, attemptCount, durationMs, createdDateTime and lastAttemptDateTime, each present when it applies.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/webhooks/{id}/deliveries.
  • Example prompt: "Why isn't our task_completed webhook reaching the accounts system?"

replay_webhook_delivery​

Posts one delivery again, now. This makes a real HTTP request to the subscriber's endpoint while the model waits, so its effect is felt outside your workspace: your workspace's data arrives in somebody's system a second time. It is the same delivery rather than a new event — the same body under the same CF-Delivery-Id — so a receiver that deduplicates on that header recognises it and one that does not processes the event twice. The description tells the model to say which it knows before replaying, and never to call this in a loop.

The answer is the delivery as it now stands; the model is told to read its outcome, because an answer means the attempt was made, not that it arrived. A pending delivery is refused with CONFLICT (the platform is already retrying it), and so is a delivery on a subscription that is not active — reactivate it with update_webhook instead. A replay does not change consecutiveFailures. attemptCount goes up and can pass five, the limit the automatic retries keep to.

NameTypeRequiredDescription
webhookIdstringYesThe subscription's id, from list_webhooks.
deliveryIdstringYesThe delivery's id, from list_webhook_deliveries — the same value the subscriber received in CF-Delivery-Id. Only the last 30 days of deliveries exist.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the delivery, with the outcome of the attempt just made and its targetUrl.
  • Annotations: destructiveHint true, idempotentHint false.
  • REST equivalent: POST /v3/webhooks/{id}/deliveries/{deliveryId}/replay.
  • Example prompt: "The accounts system was down this morning — resend the failed task_completed delivery from 09:14."
warning

A replay cannot be taken back. If the receiving system does not deduplicate on CF-Delivery-Id, it processes the event again.

create_webhook​

Subscribes a URL to an event. Every key in the scope is checked against your workspace before the subscription is written, so a mistake is refused now rather than surfacing weeks later as a subscription that never fires. There is no duplicate check: two identical subscriptions deliver every event twice. The event type and scope cannot be changed afterwards — delete the subscription and create another.

The answer does not include the signing secret. See the note at the top of this page.

NameTypeRequiredDescription
eventTypestringYesThe event to fire on — one of the nine names, matched exactly including case and punctuation. See Event Types.
targetUrlstringYesWhere to POST the event: an absolute https URL on the public internet, at most 1,000 characters, with no username or password in it. http is refused, and so is anything naming or resolving to an address inside CheckFlow's own network (loopback, private ranges, link-local, the cloud metadata endpoint).
scopeobjectNoWhat to narrow the subscription to: type and key. type is Workspace, Template, Task or Field; key is the template, task or field key from get_template, and is left out for Workspace. Omit scope for the whole workspace. A scope the event cannot fire under is refused, and the refusal lists the ones it accepts.
sourcestringNoA label for whoever is setting this up, such as zapier. At most 20 characters, default api. Nothing reads it except the source filter on list_webhooks.
isActivebooleanNoWhether to start delivering straight away. Default true. false sets the subscription up while the receiving end is still being built.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the new Webhook object, without secret.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/webhooks (which, unlike the tool, returns the secret once).
  • Example prompt: "When anyone completes the 'Approve payment' task in Invoice Review, post it to https://hooks.acme.example/checkflow."

Event Types​

EventFires whenScopes it accepts
new_checklistA checklist is started from a templateTemplate
task_completedA task is marked doneTask, Template or Workspace
file_uploadedA file is attached to a File Upload fieldField
checklist_completedA checklist is finished (not when it is reopened)Template or Workspace
comment_createdSomebody comments on a task; the delivery carries the comment text as typedTask or Workspace
task_assignedA task is given to somebody who did not already have it — one delivery per personTask, Template or Workspace
data_set.record.createdA Data Set record is createdWorkspace
data_set.record.updatedA Data Set record is updatedWorkspace
data_set.record.deletedA Data Set record is deletedWorkspace

new_checklist and file_uploaded have no workspace scope, so omitting scope for them is refused. The description warns the model that a comment_created subscription with no scope sends every comment anybody writes in the workspace out of CheckFlow, and tells it to narrow the scope to a task unless the whole workspace is the point.

update_webhook​

Changes where a subscription delivers, what it is labelled, or whether it delivers at all — those three and nothing else. The event type and scope define the subscription; to change them, delete it and create another. Sending none of the three is refused. Nothing here can be cleared.

NameTypeRequiredDescription
webhookIdstringYesThe subscription's id, from list_webhooks.
targetUrlstringNoThe new target. The same rules as create_webhook, including https only.
sourcestringNoThe new label, at most 20 characters.
isActivebooleanNoWhether to deliver. Pausing keeps everything else and skips the subscription when the event fires; nothing is buffered or replayed on resuming. Setting true also clears consecutiveFailures and disabledReason. Setting the value it already has is not refused.
  • Returns: the Webhook object as it now stands.
  • Annotations: idempotentHint true.
  • REST equivalent: PATCH /v3/webhooks/{id}.
  • Example prompt: "Switch the accounts system webhook back on."

delete_webhook​

Deletes a subscription: the row goes and the events stop. Nothing restores it, so pausing with update_webhook is the reversible alternative. An id that names nothing is refused with WEBHOOK_NOT_FOUND. An event raised just before the delete may still be delivered just after it.

NameTypeRequiredDescription
webhookIdstringYesThe subscription's id, from list_webhooks.
  • Returns: nothing.
  • Annotations: destructiveHint true, idempotentHint true.
  • REST equivalent: DELETE /v3/webhooks/{id}.
  • Example prompt: "Remove the Zapier webhooks we no longer use."
  • Webhooks — the REST routes behind these tools, including the delivery payload and secret rotation that the tools leave out.
  • Web Hooks — the product-level introduction to webhooks and the events CheckFlow raises.
  • Template Authoring Tools — get_template, where the template, task and field keys for a scope come from.
  • Data Set Tools — the record writes that raise the data_set.record.* events, and the one bulk write that does not.