n8n + Tevyr
n8n is the developer-friendly automation tool — cloud or self-hosted, fair-code license, 500+ integrations. Tevyr fires webhooks, n8n catches them in a workflow and routes the payload anywhere. The self-hosted option means payload data never has to leave your infrastructure — useful for events with confidentiality requirements (medical, legal, financial speakers).
n8n builds automations called workflows — graphs of nodes (trigger node + action nodes connected by wires). The visual builder is closer to a flowchart than Zapier's linear steps, with full conditional branching, loops, and code nodes for transformations. Self-hosted is free; n8n Cloud has paid tiers. Get started at n8n.io.
What you can do
Auto-create sessions from your calendar
Calendly invitee created → n8n workflow fires → Tevyr session created with meeting title, attendee name, and duration. Pre-loaded controller before doors open.
Post Q&A to a private Slack with no data egress
Self-hosted n8n means the audience submission, speaker context, and full Tevyr payload never leave your infra before reaching Slack. Compliance-friendly for sensitive events.
Code-node transformations on payloads
n8n's Code node lets you reshape Tevyr's payload with arbitrary JS before forwarding. Useful for matching the exact schema your internal system expects.
Log every session to your own database
Tevyr fires session.completed → n8n's Postgres / MySQL / Mongo node writes a row to your private analytics DB. No SaaS spreadsheet, no third-party retention.
Pattern 1 — Tevyr → n8n (Tevyr webhook is the trigger)
This is the most common direction. Tevyr fires a webhook on every meaningful event; n8n catches it and runs your workflow.
n8n exposes two webhook URLs per Webhook node and they behave differently:
- Test URL — only fires while the workflow editor is open and you've clicked Listen for Test Event. Use this while you're building.
- Production URL — only works after you activate the workflow with the top-right toggle.
The #1 stumbling block setting up n8n is pasting the Test URL into Tevyr, closing the editor tab, and then wondering why the workflow doesn't fire later. Paste the Production URL into Tevyr and activate the workflow.
Setup
- In n8n, click New Workflow
- Click the + to add a node, search Webhook, pick the Webhook trigger node
- Set HTTP Method to
POST - Set Path to something descriptive (e.g.
tevyr-session-events) - Set Response Mode to Immediately — this returns 200 to Tevyr without waiting for downstream nodes to finish. Critical for low-latency macro fires; see Troubleshooting below.
- Click Listen for Test Event to capture a real Tevyr payload for testing
- In Tevyr, open Settings → Webhooks for your event
- Click Add Webhook, paste the n8n Test URL for now, choose which events to send
- Save. Click Test in Tevyr's webhook panel — n8n captures the payload and shows the fields
- Add downstream nodes (Slack, Sheets, Postgres, anything)
- Activate the workflow with the top-right toggle, then swap Tevyr's webhook URL from Test → Production
Recipe — Q&A submitted → Slack message
- Trigger: Webhook node (
POST /tevyr-session-events) - Add node: Slack → Send a message
- Channel:
#qa-moderation - Message text — use n8n's expression editor to drop in
{{ $json.body.question.text }}and{{ $json.body.question.submitter_name }} - Activate the workflow
Every Q&A submission now lands as a Slack ping with the question text and the submitter's name when available.
Recipe — session.completed → Postgres row
-
Trigger: Webhook node
-
Add node: Postgres → Execute Query
-
Pick or create the credential pointing at your DB
-
Query:
INSERT INTO session_log (date, title, speaker, planned_sec, actual_sec, overrun_sec) VALUES ( '{{ $json.body.session.completed_at }}', '{{ $json.body.session.title }}', '{{ $json.body.session.speaker_name }}', {{ $json.body.session.duration_seconds }}, {{ $json.body.session.actual_duration_seconds }}, {{ $json.body.session.overrun_seconds }} )
Run an event end-to-end — your private DB has a complete log without anyone touching it.
Recipe — timer.warning → email speaker
- Trigger: Webhook node
- Add node: IF — only continue if
{{ $json.body.session.speaker_email }}is not empty - Add node: Send Email (or Gmail / Microsoft Outlook)
- Subject:
5 minutes left — please start wrapping up - Body:
Hi {{ $json.body.session.speaker_name }}, the timer just hit your warning threshold. About {{ $json.body.remaining_seconds }} seconds remaining.
Useful for remote speakers on Zoom who can't see a confidence monitor.
Pattern 2 — n8n → Tevyr (n8n workflow calls Tevyr's API)
The reverse direction. n8n triggers off something else (Calendly, Notion, a cron schedule, anything in its catalog) and uses Tevyr's API to take action.
Setup
- In n8n, New Workflow
- Set the trigger to whatever app you're listening to (e.g. Calendly Trigger → Invitee Created)
- Add the next node: HTTP Request
- Method:
GET - URL: the Tevyr API endpoint (recipes below)
- Drop in query parameters with n8n expressions to map the trigger app's fields
Recipe — Calendly booking → create Tevyr session
- Trigger: Calendly Trigger → Invitee Created
- Action: HTTP Request
- URL:
https://api.tevyr.com/v1/session/create - Query parameters:
room_id: your Tevyr room IDapi_key: your Tevyr API keytitle:{{ $json.event_type.name }}speaker_name:{{ $json.invitee.name }}duration_seconds:{{ $json.event.duration }}scheduled_start_time:{{ $json.event.start_time }}
Every Calendly booking auto-creates a Tevyr session. Open the controller — your day's lineup is already loaded.
Recipe — Schedule trigger → fire a Tevyr macro every Monday morning
- Trigger: Schedule Trigger → cron
0 9 * * 1(every Monday 9am) - Action: HTTP Request → GET
https://api.tevyr.com/v1/macros/run?macro_id=YOUR_MACRO_ID&room_id=YOUR_ROOM_ID&api_key=YOUR_API_KEY
A recurring weekly cue fires from n8n with no human in the loop.
Pattern 3 — Tevyr macro fires a workflow (native template path)
Use this when you want a Tevyr macro step to fire an n8n workflow inline — branch on the timer, the session, or prior step output before firing. Faster than the webhook fan-out path and the macro builder gives you per-fire field interpolation against {{ctx.*}}.
Setup
- In n8n, New Workflow → add a Webhook trigger node, set
POST, give it a path, set Response Mode to Immediately - Activate the workflow with the top-right toggle
- Copy the Production URL (NOT the Test URL — the Test URL only listens while the editor is open)
- In Tevyr, Settings → Integrations → Add new → n8n, paste the URL, name the connection (e.g. "n8n — speaker reminder"), click Save
The URL format depends on where your n8n lives:
| Host | URL pattern |
|---|---|
| n8n Cloud | https://your-tenant.n8n.cloud/webhook/<id> |
| Self-hosted | https://your-n8n.example.com/webhook/<path> |
Verify the wiring
- Click Test on the new Tevyr connection — Tevyr POSTs a test payload to your n8n webhook URL
- Open the workflow's Executions tab — the test run should appear with the full Tevyr payload
- Finish wiring downstream nodes
Use the connection in a macro
- Drag
flow.http_requestinto any macro - Pick your n8n connection from the dropdown
- Pick the Fire workflow action
- Fill the fields:
| Field | Value |
|---|---|
| Event name | session_started (free-form label your workflow branches on with an IF or Switch node) |
| Message | {{ctx.session.name}} just started at {{ctx.now.local}} |
| Extra payload (optional) | {"speaker":"{{ctx.session.name}}","remaining":{{ctx.timer.remaining}}} (valid JSON, also interpolated) |
Payload shape n8n receives
Every fire ships this body:
{
"event": "session_started",
"message": "Round 1 just started at 4:24 PM",
"extra": { "speaker": "Round 1", "remaining": 1741 },
"ctx": {
"session_name": "Round 1",
"event_name": "Boxing Rounds",
"timer_remaining": 1741,
"now_iso": "2026-05-16T04:24:18.442Z"
}
}
In the workflow, this body shows up as {{ $json.body.event }}, {{ $json.body.ctx.session_name }}, etc. Use a Switch or IF node to branch on event for routing, and pull structured values from extra and ctx for downstream actions.
Common payload reference
When Tevyr fires a webhook, the payload includes structured fields you can map in n8n. Below are the most-used field paths for each event type:
| Event | Useful fields |
|---|---|
| session.started | session.title, session.speaker_name, session.duration_seconds, session.started_at |
| session.completed | session.title, session.actual_duration_seconds, session.overrun_seconds, session.completed_at |
| session.changed | session.title, session.previous_title, changed_fields |
| timer.warning | session.title, session.speaker_name, remaining_seconds, threshold_seconds |
| timer.critical | session.title, remaining_seconds |
| timer.finished | session.title, overrun_seconds |
| question.submitted | question.text, question.submitter_name, question.is_anonymous, question.submitted_at |
| display.blackout_enabled | triggered_by, triggered_at |
In n8n expressions these are accessed as {{ $json.body.<path> }} (the webhook body is wrapped in a top-level body field by the Webhook node).
See the Webhooks reference for the full payload shape of every event type.
Troubleshooting
"Workflow doesn't trigger when Tevyr fires"
- 95% of the time this is Test URL vs Production URL. The Test URL only listens while the workflow editor is open and Listen for Test Event is active. For long-running production wiring, you need the Production URL and the workflow must be activated with the top-right toggle.
- Check the workflow's Executions tab. If failed executions land there with a 500, n8n received the request but a node failed — debug from there.
- If nothing lands in Executions, n8n never received the request. Check Tevyr's webhook delivery log for the response code.
"Self-hosted instance behind a firewall"
- For Tevyr → n8n webhooks to work, your n8n instance must be reachable from the public internet. Behind-NAT or private-VLAN deploys won't receive the request.
- Options: expose via Cloudflare Tunnel, ngrok, or a reverse proxy; or move to n8n Cloud; or run a public-facing relay (e.g. a Cloudflare Worker that re-POSTs to a private n8n).
"n8n returns 500 on receive"
- The Webhook trigger node's Response Mode matters:
- Immediately — n8n returns 200 as soon as the webhook is received, then runs the workflow async. Use this for Tevyr macro fires; it minimizes the round-trip and Tevyr doesn't care about the workflow result.
- When Last Node Finishes — n8n waits for the entire workflow to complete before responding. For long workflows this exceeds Tevyr's HTTP timeout and Tevyr marks the delivery failed.
- For Pattern 3 (macro fires), Response Mode must be Immediately.
"Authentication on the webhook node"
- n8n's Webhook node has an optional Authentication field — Basic Auth, header auth, or none. If you enable it, encode the credential into the URL pasted into Tevyr:
- Basic Auth:
https://user:pass@your-n8n.example.com/webhook/<id> - Header auth: not directly supported by Tevyr's URL field — leave Authentication on
Nonefor catch-hook use cases.
- Basic Auth:
Context variables
When Tevyr → n8n via a macro step (using the n8n template or Generic HTTP), the body fields support {{ctx.*}} interpolation. n8n receives whatever fields you stitched in. See the full context-variable reference. Common ones: {{ctx.event.title}}, {{ctx.session.title}}, {{ctx.session.speaker_name}}, {{ctx.timer.remaining_seconds}}, {{ctx.now.iso}}.
Triggered by webhook events
For the inverse — fire a workflow on every Tevyr event — use a webhook in Integration mode with your n8n connection, OR use URL mode and paste the n8n Production URL directly. Both work; integration mode is friendlier when you have multiple workflows to manage.
Related
- Zapier — alternative catch-hook pattern with a larger app catalog
- Make — alternative catch-hook pattern with a visual scenario builder
- Macros — fire an n8n workflow from a specific macro step (mid-show, conditional, etc.)
- API reference — every endpoint n8n can call
- Webhooks — every event Tevyr can fire
- Integrations Overview — other tools you can wire alongside n8n