Skip to main content

Webhook events reference — Telm real-time events and HMAC

Full reference for Telm webhook events: spam.detected, user.banned, user.kicked, user.muted, user.joined and more. Payloads, headers and HMAC signatures.

6 min read
In short

Telm can push moderation events to your server in real time. You register an endpoint, choose which events to receive, and Telm sends a signed POST for each one. Every delivery carries an HMAC-SHA256 signature you verify with your endpoint secret. Failed deliveries are retried on a schedule; a permanently unreachable endpoint is auto-disabled.

Webhook events are managed from the Developers page.

1The event envelope

Every webhook is an HTTP POST with a JSON body in a common envelope. The envelope has an id (a unique delivery identifier for de-duplication), a type (the event name), a created_at timestamp, the group_id the event belongs to, and a data object whose shape depends on the event type.

The id is deterministic for real events, so if the same event is delivered twice — for example after a retry — you receive the same id both times. Use the X-Telm-Delivery header (which mirrors this id) as an idempotency key so your handler processes each event only once.

  • Envelope fields: id, type, created_at, group_id, data.
  • type is one of the event names from the catalog below.
  • data carries the event-specific fields.
  • Use id (and the X-Telm-Delivery header) to de-duplicate retries.

2Event catalog

You subscribe an endpoint to any subset of the catalog. spam.detected fires when the engine flags a message as spam. message.suspicious fires in monitoring mode, when the engine would have acted but only shadow-scored the message. The member events cover people entering, leaving, and being punished.

The ping event is special: it is not part of the subscribable catalog and is only sent when you trigger a test delivery for an endpoint, so you can confirm your receiver and signature check work end to end.

  • spam.detected — a message was classified as spam.
  • message.suspicious — a shadow (monitoring-mode) detection.
  • user.banned, user.kicked, user.muted — a moderation action was applied.
  • user.joined, user.left — a member entered or left the group.
  • ping — a manual test event, never fired by real activity.

3Payload fields per event

For spam.detected and message.suspicious, the data object carries message_id, user_id, username, the message text (truncated for very long messages), the action taken, a category, a reason, the detected language, and a confidence score. message.suspicious additionally carries the shadow score.

For the member events (user.joined, user.left, user.banned, user.kicked, user.muted), the data object carries user_id, username, first_name, an optional message_id, and a reason where one applies. One underlying event can produce more than one webhook — a spam message that triggers a ban is delivered as both spam.detected and user.banned.

  • Spam events: message_id, user_id, username, text, action, category, reason, language, confidence (plus score for message.suspicious).
  • Member events: user_id, username, first_name, message_id, reason.
  • A single incident may emit several events; correlate them by user_id and group_id.

4Verifying the HMAC signature

Each delivery is signed so you can be sure it really came from Telm and was not tampered with. You get an endpoint secret (it starts with whsec_) once, when you create the endpoint. Store it and use it to verify every incoming request.

To verify, take the X-Telm-Timestamp header value, append a dot, then append the exact raw request body, and compute an HMAC-SHA256 of that string using your endpoint secret as the key. Hex-encode the result and prefix it with v1= — it must equal the X-Telm-Signature header. Compare with a constant-time comparison, and reject the request if the timestamp is older than a few minutes (five is a good cut-off) to block replays.

  • X-Telm-Event — the event type.
  • X-Telm-Delivery — the delivery id (idempotency key).
  • X-Telm-Timestamp — unix seconds, signed to prevent replays.
  • X-Telm-Signature — v1= plus the hex HMAC-SHA256 of timestamp, a dot, and the raw body.
Verify against the raw request bytes, before any JSON parsing or re-serialisation. Reformatting the body changes the signature and makes valid deliveries look invalid.

5Delivery, retries and auto-disable

A delivery counts as successful only if your endpoint responds with a 2xx status. Anything else — a non-2xx code, a timeout, or a connection error — is treated as a failure and retried on a fixed schedule: immediately, then after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, for six attempts spanning roughly eight and a half hours before the delivery is closed as failed.

If an endpoint keeps failing — at least twenty consecutive failures with no successful delivery for three days — Telm automatically disables it so it stops sending to a dead URL. You can re-enable it from the dashboard once your receiver is healthy again.

  • Success = HTTP 2xx. Respond fast (within about ten seconds) and do heavy work asynchronously.
  • Retry schedule: immediate, +1m, +5m, +30m, +2h, +6h (six attempts).
  • Auto-disabled after 20 straight failures with no success in 72 hours.
  • Registering webhooks requires the Pro plan or higher.
Webhook endpoints are part of the full API and require the Pro plan or higher. See API rate limits and quotas for the metering that applies to API calls.
Was this article helpful?

Ready to protect your group?

Add Telm to your Telegram group and let it handle the spam.