Sentry Issues
A worked webhook example: a package-owned inbound URL that accepts a Sentry issue POST, verifies HMAC on the platform, and starts triage without a model in the request path. Load this when someone asks how to hang a vendor webhook on a package they own.
This is the webhook example. Sentry (or any vendor that can POST JSON) knocks on a credentialed URL Minion hosts. The bound package export runs. No chat, no inference, no tokens spent on the delivery itself.
The package below is a pattern you build, not a package that ships with Minion. The HTTP contract is in Inbound webhooks . The "which trigger" guide is Jobs, workflows, and webhooks .
The knock
A new issue in a configured Sentry project POSTs to a minted URL. Minion verifies the HMAC against a named secret, then invokes the package export declared on that webhook. Fast skips stay synchronous. Durable triage (a mail to you, a note, a follow-up run) is extra work the package chooses to stage after the ack.
Your package can stop at "verify, store, notify" if you do not want anything else in the loop.
Sentry event text is untrusted data. Treat titles, breadcrumbs, and request bodies as attacker-controlled.
Package shape
Declare the webhook in package.json#minion.webhooks. One name binds one export. Declaring it does not open ingress; minting does.
{
"name": "@you/sentry-triage",
"exports": {
"./handle-sentry-webhook": "./src/handle-sentry-webhook.ts"
},
"minion": {
"webhooks": [
{
"name": "sentry",
"export": "./handle-sentry-webhook",
"responseMode": "ack",
"verification": {
"type": "hmac-sha256",
"header": "sentry-hook-signature",
"secretName": "sentryWebhookSecret",
"encoding": "hex"
}
}
]
}
} The handler sees the validated request, not a chat transcript:
export default async function handleSentryWebhook({ webhook, request }) {
const action = request.json?.action
const issue = request.json?.data?.issue
if (!issue?.id) return { ok: true, skipped: 'no-issue' }
// Stage durable work; the ack stays fast.
return { ok: true, issueId: issue.id, action, deliveryId: webhook.deliveryId }
} Setup, in order:
- Save Sentry's signing secret under the name
sentryWebhookSecreton the Secrets page, with the secure entry form. Do not paste the value into chat. An owner or admin must also turn on Allow webhook use for it, or deliveries fail closed. - Publish the package.
- Mint with
minion.webhooks.mint({ package: 'sentry-triage', name: 'sentry' }). The tool returns ahandle, not the URL. - For Sentry, the owner opens /app/webhooks , reveals the URL, and pastes it into the Sentry internal integration. MCP and execute never return the credential.
- Smoke-test before you trust production: run
minion.webhooks.dispatchSynthetic({ handle, request: { json: { action: 'created', data: { issue: { id: '1', title: 'smoke' } } } }, wait: true }), or send yourself one real delivery.
For anything slow, ack quickly, stage the body in packageStorage(), and hand the long work to minion.workflows.create with a small { payloadKey, issueId } object. A late, large Sentry POST does not have to finish triage inside the webhook budget.
Rotate, reveal, and the delivery log live on /app/webhooks . The rotate overlap window is in Inbound webhooks .
Example prompts
Build one
Search Minion for inbound webhooks. I want a package that accepts Sentry issue webhooks, verifies HMAC with a named secret, acks fast, and mails me the new issue id. Do not put the URL in chat. After publish, mint the webhook and tell me to copy the URL from the Webhooks page into Sentry.
Dry-run an existing copy
Runwebhooks.dispatchSyntheticagainst my sentry webhook with{ json: { action: "created", data: { issue: { id: "1", title: "smoke" } } } }and wait for the result. Show me what it would do.
What you see
- /app/webhooks: Mint, reveal, rotate, disable, enable, and the recent deliveries. Bodies are never stored
- /app/runs: Handler runs, with source
webhook - Chat (execute): Dry-run the handler with
webhooks.dispatchSyntheticand readwebhooks.deliveries
Where to go next
- Inbound webhooks : HMAC, replay windows, mint/rotate, trusted clients.
- Jobs, workflows, and webhooks : when a webhook is the right door versus a cron or a subscription.
- Agent inbox : the email sibling of this example.
- Package authoring : README, publish checks and exports.