Cockpitify Help

Send events to Slack, Discord or your server

Add a webhook per app in Cockpitify to post new users, purchases, low balances and more to Slack, Discord or a signed JSON endpoint.

Webhooks send the same events as push notifications to a Slack or Discord channel, or to your own server as signed JSON. Each app has its own webhooks, separate from push.

What it’s good for

  • A #signups or #revenue channel where the whole team sees new users and purchases as they happen.
  • An #alerts channel for low balances, AI limit alerts, a project that stops answering and crash spikes.
  • Your own backend or automation tool, to react to events: add a user to your CRM, post to another tool, start a workflow.

Get a Slack webhook URL

  1. Go to api.slack.com/apps and click Create New App → From scratch. Name it, for example “Cockpitify”, and pick your workspace.
  2. Open Incoming Webhooks and turn on Activate Incoming Webhooks.
  3. Click Add New Webhook to Workspace, pick the channel and click Allow.
  4. Copy the Webhook URL. It starts with https://hooks.slack.com/services/.

Get a Discord webhook URL

  1. In Discord, hover the channel and click Edit Channel (the gear).
  2. Open Integrations → Webhooks → New Webhook.
  3. Optionally rename it and give it an avatar, then click Copy Webhook URL.

Your own server

Any public https:// address that accepts a POST with a JSON body works. Private and local addresses are refused, and redirects aren’t followed. See JSON format below.

Add a webhook

  1. Open Settings → Notifications → Webhooks and tap the app.
  2. Tap Add webhook.
  3. Paste the Webhook URL. Cockpitify detects whether it’s Slack, Discord or JSON.
  4. Optionally give it a Name.
  5. Choose whether to Show user names. When off, messages say “A user”.
  6. Tap Save and send test.

Every event starts off. Check the channel for the test message, then turn on the events you want.

Choose the events

Each event can be Off or Instant; New users can also be Hourly:

  • New users
  • Premium
  • Balance and budget
  • Daily AI limit
  • Project reachability
  • Usage drop
  • Stability
  • Daily summary

What the messages look like

  • Slack: a short message with a bold title and one line of detail, for example the new user, the plan they bought or the service that runs low.
  • Discord: an embed with the title, the detail, a colour per event type and the time.
  • With Show user names off, people appear as “A user” in Slack, Discord and JSON alike.

JSON format

Your server receives one POST per event:

{
  "id": "…",
  "type": "signup",
  "app": { "id": "…", "name": "Studyloop" },
  "at": "2026-10-07T09:12:44.000Z",
  "user": { "id": "…", "label": null },
  "data": { },
  "title": "…",
  "text": "…"
}
  • type is the event, such as signup, premium_on, premium_cancel, low_balance or ai_limit. The same value is in the X-Ops-Event header.
  • user is null for events that aren’t about a user, such as a low balance. label is the user’s name or email only when Show user names is on.
  • data holds the event’s details; title and text are the same words as the push notification.
  • Answer with any 2xx status within 5 seconds.

Verify the signature

Every JSON request has an X-Ops-Signature header like t=1791393931,v1=5f2c…. v1 is the HMAC-SHA256, in hex, of the timestamp, a dot and the raw body, signed with the webhook’s Signing secret (copy it from the webhook’s page). In Node.js:

import { createHmac, timingSafeEqual } from 'node:crypto'

function verify(rawBody: string, header: string, secret: string) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')))
  const expected = createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex')
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300
  return fresh && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ''))
}

Use the raw request body exactly as received, before parsing it as JSON.

Paused webhooks

After 10 failed deliveries in a row, a webhook pauses itself. Fix the address, then tap Resume. Cockpitify sends a test first.

Limits and permissions

  • Up to 5 webhooks per app.
  • Only the workspace owner or an admin can add or change webhooks.