Alerts don't need another channel. They need an owner

Digestron is a webhook-native operational inbox. POST an event, get a ticket someone owns — with a status, an assignee and an audit trail. One endpoint is the entire integration.

you POSTclient.send()
import { DigestronClient, blocks } from "@digestron/sdk"

const client = new DigestronClient({
  apiKey: process.env.DIGESTRON_API_KEY!,
  baseUrl: "https://inbox.acme.com", // your Digestron instance
})

const { id, jobId } = await client.send({
  channelId: "fraud-alerts",
  // optional — a repeat send updates the same ticket
  idempotencyKey: "CLM-9821",
  callbackUrl: "https://acme.com/hooks/digestron",
  // routing only, never rendered
  metadata: {
    severity: "critical",
    user_segment: "premium",
  },
  blocks: [
    blocks.header("Card testing detected"),
    blocks.section("5 declined authorizations in 90 seconds."),
    blocks.fields({ Card: "•••• 4412", Attempts: "5" }),
  ],
})

// 202 Accepted — the ticket renders on the queue, so a slow
// render never blocks the path the alert came in on.
you geta ticket someone owns
FRAUD-14IN_PROGRESSP1

Card testing detected

5 declined authorizations in 90 seconds.

Card
•••• 4412
Attempts
5
2 comments
Dana Whitfield14:11

Same BIN range as this morning. Blocking at the gateway, keeping this open until the retry window closes.

Rae Koval14:14

Confirmed — filed upstream with the issuer.

activity
  1. message.createdvia webhook · CLM-982114:02
  2. message.updatedassignee → D. Whitfield14:09
  3. message.updatedNEW → IN_PROGRESS14:09
D. Whitfieldfraud-alertsupdated 14:14

Four fields, one permanent contract

blocks
You control what the human sees. Block Kit compatible, so the payload you already render into Slack works here unchanged.
metadata
Never rendered. Key/value pairs reserved for routing, priority and assignment — the ops analyst never sees your internal flags.
idempotencyKey
Send the same event twice and it updates one ticket instead of creating two. Comments and assignment history survive the update.
callbackUrl
When a ticket reaches a terminal status we POST back, retried three times, with every attempt readable over the API.

Two teams, one inbox

The same ticket is a delivery receipt on one side of the webhook and a piece of work on the other. Neither side has to hold the other's tools.

Engineering

The side that emits the event.

  • One endpoint is the whole integrationA bearer key and a JSON body. The SDK is optional — zero runtime dependencies, anywhere fetch runs, typed so a payload that drifts from the server schema fails your build.
  • The payload you already produceBlock Kit objects render unchanged, so the alert you format for Slack needs no second formatter.
  • Retries cannot double-fileAn idempotency key makes a redelivered event update the ticket it already created, comments and assignment intact.
  • The loop closes back in your systemA terminal status POSTs to your callback, retried three times, with every attempt readable over the API.
  • Nothing new on your critical pathIngest answers 202 and renders on a queue, and keys are per workspace, so the alert path neither waits on the inbox nor shares a credential with anything else.

Operations

The side that has to do something about it.

  • A queue, not a channelEvery event arrives as a ticket with a status, an assignee and a priority — work you can pick up rather than a message that scrolls away.
  • Transitions are enforced, not suggestedNothing reaches RESOLVED without having been worked, and any terminal state can be reopened when an alert turns out to be live again.
  • The discussion sits on the alertThreaded comments live with the ticket, so the reasoning behind a decision is still there the next time the same alert fires.
  • An answer to who changed thisEvery move is timestamped in an immutable activity log, and roles decide who can move what.
  • None of the internal noiseSeverity flags, customer segments and routing hints stay in metadata and never reach the screen.

Statuses that mean something

  1. NEW
  2. IN_PROGRESS
  3. RESOLVED
  4. REJECTED
  5. ARCHIVED

Transitions are enforced, not suggested. Nothing reaches RESOLVED without having been worked, every terminal state can be reopened because a closed alert that turns out to be live again is routine, and ARCHIVED is the one-way exit. Every move is timestamped and logged.

Or skip the SDK entirely

The SDK is a convenience over one HTTP call. This is the same send, by hand: POST /webhooks with an Authorization: Bearer header and a JSON body.

{
  "channelId": "fraud-alerts",
  "idempotencyKey": "CLM-9821",
  "callbackUrl": "https://acme.com/hooks/digestron",
  "blocks": [
    {
      "type": "header",
      "text": { "type": "plain_text", "text": "Card testing detected" }
    },
    {
      "type": "section",
      "text": { "type": "mrkdwn", "text": "5 declined authorizations in 90 seconds." }
    },
    {
      "type": "section",
      "fields": [
        { "type": "mrkdwn", "text": "*Card*\n•••• 4412" },
        { "type": "mrkdwn", "text": "*Attempts*\n5" }
      ]
    }
  ],
  "metadata": [
    { "key": "severity", "value": "critical" },
    { "key": "user_segment", "value": "premium" }
  ]
}

Anything that can make an HTTP request can file a ticket — curl, a Lambda, a cron job, a language with no Digestron package at all. The call answers 202 with the accepted webhook and the job that renders it, so a slow render never blocks the path your alert came in on.

Why none of your existing tools do this

On-call tools are built around outages and page engineers at 3am. Support desks are built around customers writing in. Issue trackers still need a human to type the ticket. Chaining a webhook through an automation platform into one of them is plumbing, not a product.

Digestron sits in the layer none of them own: the human triage step between a system event and the tool where the work actually gets done.

Block Kit, unchanged

blocks is Slack Block Kit compatible. If you already render alerts into a Slack channel, you already have the payload — point it somewhere that keeps score. Slack's block reference is the payload reference: the objects it documents are the objects this accepts.

The ticket at the top of this page leaves two fields out: severity and user_segment were in the send but never reach the screen. Metadata is for routing, not for reading.

Where it is today

  1. spring 2026

    Ingest, end to end

    shipped

    One authenticated endpoint that accepts a Block Kit payload, queues it and renders it into a ticket without the caller waiting on the render.

    webhook ingest · block rendering · per-workspace API keys

  2. spring 2026

    A queue someone works

    shipped

    The part that makes it an inbox rather than a log: enforced transitions, an owner and a priority per ticket, the discussion attached to it, and a record of every move.

    the ticket lifecycle · assignment and priority · threaded comments · an immutable activity log · role-based access · volume and unassigned-aging analytics

  3. summer 2026

    The loop closes

    shipped

    A repeat send updates the ticket it already created instead of filing a second one, and a terminal status reports back to the system that raised the alert.

    idempotent rematerialization · terminal-status callbacks · delivery log

  4. fall 2026

    Rules that route

    in progress

    Metadata keys discovered from the traffic you actually send, multi-condition rules over them, and actions that set a priority, assign an owner or move a ticket to another channel before a human sees it.

    key auto-discovery · rule builder · rule actions

  5. winter 2027

    Rules you can audit

    in progress

    A rule that quietly matches nothing is worse than no rule, so each one carries a match log and a health indicator that says so out loud.

    match log · rule health

Self-hostable. A hosted version is not live yet.