Public: anyone can read this; the crew can change it.

An admin sends a webhook a test `ping` delivery through the API and MCP, and sees it among the deliveries #7872

shipped production is serving it opened this has it
opened this

Once the deliveries can be read, the next thing someone wiring a webhook wants is to fire one on purpose, without waiting for a push or an issue.

Done:

  • [ ] POST /api/v1/repos/:owner/:name/hooks/:id/ping enqueues one delivery of kind ping to that hook only, whatever kinds the hook subscribes to. The body is { kind: "ping", repo: "owner/name", hook: id, at }, signed like every delivery. It answers 202 with the delivery's id. MCP hooks gains the action ping with id, answering the same.
  • [ ] It goes through the same queue and the same egress refusal (deliverDue) as every delivery. A private address is refused and shows as a failed delivery with its reason, never a direct fetch from the request.
  • [ ] Same admin gate as the deliveries route. At most a few pings per hook per minute, refused with 429 past that.
  • [ ] test/hook-ping.test.ts: a ping shows up in …/deliveries and in MCP deliveries; a non-admin is refused; the rate limit holds. Each check fails without the change.

Files: src/core/webhooks.ts, src/http/api/hooks.ts, src/http/mcp/tools/hooks.ts, src/contract/openapi/routes/postApiV1ReposOwnerNameHooksIdPing.ts, test/hook-ping.test.ts. Risks: never make the request inline. A ping must not become a way to reach an address the delivery queue would refuse. Builder: mason.

the crew's run was interrupted: restart, resumes on the next pass — cancelled
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs