Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.firstflow.app/llms.txt

Use this file to discover all available pages before exploring further.

Webhooks

Firstflow delivers webhook events via Svix — a signed, retried webhook platform.

Enable webhooks

Webhooks are workspace-level. Events are not sent until you enable them.
  1. Go to Integrations in the sidebar
  2. Click Webhooks
  3. Click Enable webhooks
This creates your Svix delivery app and opens the webhook portal inline. From the portal you can:
  • Add and manage endpoint URLs
  • Select which events each endpoint receives
  • View delivery history and retry failed events
The portal is embedded directly in the Integrations page. No external Svix account is required.

Events

EventWhen it fires
experience.createdAn experience is created
experience.updatedAn experience is updated (content or settings)
experience.deletedAn experience is deleted
experience.startedA user begins an experience
experience.completedA user completes all nodes in an experience
experience.dismissedA user dismisses an experience
survey.submittedA user submits a survey
survey.answerA user answers a survey question
announcement.clickedA user clicks an announcement CTA
experience.logic_action.webhookA flow node’s webhook action fires (see Logic actions)

Payload format

{
  "event": "experience.completed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "agentId": "agent_abc123",
    "experienceId": "exp_xyz789",
    "experienceType": "tour",
    "userId": "user_abc123",
    "completedAt": "2024-01-15T10:30:00Z"
  }
}
Survey submission:
{
  "event": "survey.submitted",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "agentId": "agent_abc123",
    "experienceId": "exp_survey456",
    "userId": "user_abc123",
    "answers": {
      "nps_score": 9,
      "open_feedback": "Love the product"
    }
  }
}

Verifying signatures

Every webhook is signed with HMAC-SHA256. The signature is in the svix-signature header.
import { Webhook } from "svix";

const wh = new Webhook(process.env.FIRSTFLOW_WEBHOOK_SECRET!);

export async function POST(req: Request) {
  const rawBody = await req.text();
  const headers = Object.fromEntries(req.headers);

  let event;
  try {
    event = wh.verify(rawBody, {
      "svix-id": headers["svix-id"],
      "svix-timestamp": headers["svix-timestamp"],
      "svix-signature": headers["svix-signature"],
    });
  } catch {
    return new Response("Invalid signature", { status: 400 });
  }

  // process event
  return new Response("OK", { status: 200 });
}
Find your signing secret in the portal: Integrations → Webhooks → your endpoint → Signing secret.

Retry policy

AttemptDelay after failure
1Immediate
21 minute
35 minutes
430 minutes
After 4 failed attempts the event is marked failed in the portal delivery log. Your endpoint must return 2xx to confirm delivery.

Idempotency

Use the svix-id header as an idempotency key to guard against duplicate deliveries on retries.

Slack

Send Firstflow events to a Slack channel.

Connect Slack

  1. Go to Integrations in the sidebar
  2. Click Slack
  3. Click Connect to Slack
  4. Authorize with your Slack workspace
  5. Select a default channel from the dropdown
  6. Optionally send a test message to confirm delivery
To disconnect, expand the Slack panel and click Disconnect.
If the bot is not a member of the selected channel, messages will fail. Fix it by running /invite @YourBotName in the channel.

Default channel

The default channel is set in Integrations → Slack → Default channel. Individual flow node Slack actions can target different channels (see Logic actions).

Logic actions

Logic actions fire automatically when a flow node’s trigger condition matches — as the user moves through the experience in the widget. They are configured per-node in the flow editor. Each trigger group can chain multiple actions in sequence.

Configuring logic actions

  1. Open the flow editor for an experience
  2. Select a node
  3. In the editor sidebar, expand Actions
  4. Click Add action and choose a type

Action types

Emits experience.logic_action.webhook to your workspace webhook subscribers when the trigger fires.When to use: Push data to your backend at a specific point in the flow — for example, after a user answers a key question or clicks a CTA. Your endpoint receives the event and can update a CRM, trigger an automation, or log the interaction.Requirements: Webhooks must be enabled in Integrations. The flow editor shows a notice if webhooks are off and links to the Integrations page.Idempotency: The SDK sends an idempotencyKey per logic webhook call. The server de-duplicates calls with the same key so retries don’t double-fire.Payload:
{
  "event": "experience.logic_action.webhook",
  "data": {
    "agentId": "agent_abc123",
    "experienceId": "exp_xyz789",
    "nodeId": "node_456",
    "userId": "user_123"
  }
}
Sends a message to a Slack channel when the trigger fires.When to use: Alert your team at a specific point in the flow — for example, when a user selects a low NPS score, post to your support channel immediately.Requirements: Slack must be connected in Integrations. If not connected, the action type is shown disabled in the editor.Configuration:
  • Channel — select from the channels in your connected workspace
  • Message template — static text with optional dynamic variables like {{userName}}
Logic action Slack messages go to the channel configured on the node, independent of the default channel in Integrations.
Triggers another experience to show after the current node fires.When to use: Chain experiences — for example, after completing an onboarding tour, push an NPS survey. The pushed experience must be active and still subject to its own eligibility rules (frequency, audience, schedule).
Adds the current user to an audience segment when the trigger fires.When to use: Dynamically classify users based on behavior — for example, assign users who clicked “interested in upgrade” to an upgrade-intent segment, then target them with a separate announcement.The segment must already exist in Audience → Segments. Membership updates on the next SDK config fetch (within 5 minutes, or immediately after refreshConfig()).

Security

  • Webhook endpoints must use HTTPS
  • All payloads are HMAC-SHA256 signed via Svix
  • Slack OAuth tokens are stored encrypted
  • Revoke webhook endpoints or disconnect Slack at any time from Integrations