A channel is an inbound source attached to a project. Each channel has a type, a label, and a unique address or configuration Nevo manages for it. Every channel type emits events through the same SDK + endpoint surface.
Types
webhook
Nevo generates https://<token>.in.nevo.sh. Point any third-party webhook there (Stripe, GitHub, Linear, whatever). Produces webhook.received events.
- Secret: each channel gets a signing secret; Nevo HMAC-signs outbound delivery to your endpoints with it.
- Auth on inbound: an API key bearer token is required on
POST.
email
Nevo generates <token>@in.nevo.sh. Forward any mailbox there (e.g. a support alias) and the inbound mail becomes email.received events.
- Enrichment: the full body (text + HTML) is fetched and attached before the event lands in your handler.
- Replies thread into the original conversation via RFC 5322
In-Reply-To+References.
slack
A Slack channel is a subscription against a Connection — the OAuth install to a Slack workspace. One connection can back many subscriptions; each subscription carries a kind describing which slice of the workspace’s events it listens to.
- Install first, subscribe second. Connect a Slack workspace from the Connections page, then add one or more channels against it from Channels → new channel → slack.
- Subscription kinds today:
{ "kind": "mention" }— only events where the bot is@mentioned. One per connection.{ "kind": "channel_messages", "slack_channel_id": "C01…" }— every non-bot message in one specific Slack channel. One per(connection, slack channel)pair. Requires inviting the bot to the channel in Slack (/invite @nevo).
- One workspace per project. The underlying connection enforces this globally — installing the same workspace into two Nevo projects returns a “workspace taken” error.
- Replies.
await event.reply(text="…")posts a threaded message viachat.postMessageback into the original channel/thread. - Scope upgrade. The default install grants
@mentionscope only. Creating achannel_messagessubscription needs additional Slack permissions; the dashboard detects the gap and offers a one-click reauthorize. See Connections → Reauthorize. - Delete. Deleting a Slack channel (subscription) just removes that listener; the connection and bot token stay so other subscriptions keep working. To actually uninstall the bot, delete the connection from the connections page.
cron
A schedule that fires events on a cadence — useful for waking an agent on an interval. Produces cron.fired events.
- Expression: standard 5-field Unix cron (
minute hour dom month dow). Seconds are not supported — minute resolution only.@hourly,@daily,@weeklydescriptors are accepted. - Presets: the dashboard ships quick-pick presets — every hour, every day at 9am, weekdays at 9am, every thursday 2pm, first of month 00:00 — for people who don’t want to reach for the five-field syntax.
- Timezone: IANA name (
America/New_York,Africa/Lagos, etc.).0 14 * * THUinAmerica/New_Yorkfires at 14:00 NYC time, which is 18:00 UTC — Nevo stores the computed UTC instant and recomputes the next occurrence in your timezone after each firing. - Payload: an optional static JSON object attached to every firing. Reachable in your handler via
event.data.payload. - Payload templates: string values in the payload can contain
{{token}}markers that are substituted at fire time. See Template tokens below. - Minimum interval: 1 minute today. Scheduler ticks once a minute; sub-minute cadence isn’t meaningful at this resolution.
- Concurrency: each tick fires exactly once across workers. If your handler takes longer than the interval, the next firing still arrives on schedule. Use the event
idas an idempotency key if that matters to you.
Cron template tokens
Embed any of these tokens inside a string value in the payload JSON and Nevo will substitute them when the schedule fires:
| Token | What gets substituted |
|---|---|
{{fired_at}} | RFC 3339 UTC timestamp when the scheduler ran. |
{{scheduled_at}} | RFC 3339 UTC timestamp the tick was scheduled for. |
{{iso_date}} | YYYY-MM-DD in UTC. |
{{iso_time}} | HH:MM:SS in UTC. |
{{local_iso_date}} | YYYY-MM-DD in the schedule’s timezone. |
{{local_iso_time}} | HH:MM:SS in the schedule’s timezone. |
{{epoch_seconds}} | Unix timestamp (integer). |
{{epoch_ms}} | Unix milliseconds (integer). |
{{uuid}} | A fresh UUID v4 — handy as an idempotency key. |
Example payload:
{
"run_id": "daily-digest-{{local_iso_date}}",
"key": "{{uuid}}",
"t_scheduled": "{{scheduled_at}}",
"t_fired": "{{fired_at}}"
}
Only string values are substituted. Tokens inside numbers/booleans aren’t touched. Unknown tokens are left verbatim, so {{my_literal}} passes through untouched if it doesn’t collide with a reserved name.
Coming soon
discord— Discord bot eventstelegram— Telegram bot eventss2 streams— S2 stream subscriptions- Custom domains — bring your own
ingest.yourdomain.comfor webhook and email channels (enterprise)
Common fields
All channels share these fields on the dashboard + API:
id— UUID; stable across the channel’s lifetime.type— one of the supported kinds above.label— display name. Shows on events in the dashboard; for Slack channels this is the workspace name.status—activeordisabled. Disabling pauses both inbound ingest and (for cron) scheduled firings.lastEventAt/eventCount30d— stats for the dashboard.
Type-specific fields
| Type | Extra fields |
|---|---|
| webhook | url, signingSecret |
emailAddress | |
| slack | connectionId, subscription (see Connections) |
| cron | cronExpr, cronTimezone, cronNextFireAt |
url, emailAddress, and signingSecret are server-minted at create
time and stable for the channel’s lifetime. If you need a different
inbound URL or address, create a new channel and delete the old.
Rotating a signing secret is done from the channel’s page in the dashboard: open the channel, click Rotate secret, and the new value appears once on screen. Copy it into your HMAC-verification code before closing the dialog — the previous secret stops working immediately, and Nevo doesn’t retain the plaintext.
Plan availability
| Tier | webhook | cron | slack | |
|---|---|---|---|---|
| Hobby | ✅ | |||
| Hacker | ✅ | ✅ | ✅ | |
| Pro | ✅ | ✅ | ✅ | ✅ |
| Scale | ✅ | ✅ | ✅ | ✅ |
| Enterprise | ✅ | ✅ | ✅ | ✅ |
Slack is a Pro+ feature — it needs an OAuth-installed workspace app, which is a heavier-weight surface than the single-URL channels. See Billing for full plan details.