Skip to main content
Every journey starts with a trigger. You choose the trigger type when you create a journey, and it determines how people enter the workflow. Journeys support two trigger types: API and Segment.
APISegment
How it worksYour code sends a POST request to invoke a specific journeyCourier listens to your Segment event stream and starts the journey when a matching event arrives
Engineering effortRequires a code change to call the APINo new integration code; uses events you already send to Segment
Data contractYou define a typed schema; Courier uses it for editor autofill and variable hintsNo schema; Courier receives whatever Segment sends
Best forApp-triggered flows where you control the payload (signups, purchases, actions)Behavioral flows driven by events you already track (page views, feature usage, lifecycle events)

API Invoke

The API trigger introduces a contract between your application and Courier. You define a schema on the trigger (field names and types), and Courier uses it to power autofill and variable hints throughout the journey editor. Any field you declare becomes available as a variable in every downstream node. Courier does not reject invocations that omit schema fields. If your payload is missing a field that a node references, the journey will proceed until it reaches that node and then fail there. Defining an accurate schema keeps things predictable and makes building in the editor much faster.

Define a Schema

When you configure an API trigger, you add schema fields. Each field has a name and a type.
TypeDescriptionExample value
StringText value"ORD-9042"
NumberNumeric value (integer or decimal)49.99
BooleanTrue or falsetrue
DatetimeISO 8601 timestamp"2026-02-10T14:30:00Z"
Schema fields propagate as available variables throughout the journey. Any downstream node (send, branch, fetch, throttle) can reference them by name.

Invoke via API

Send a POST request to start the journey for a user. Endpoint: POST /journeys/{journeyId}/invoke The request body accepts three optional fields. At minimum, you must provide either user_id or a profile with contact information (like an email address).
FieldTypeRequiredDescription
user_idstringconditionalThe recipient’s Courier user ID. Required unless profile contains a user identifier or contact info.
profileobjectconditionalProfile data for the recipient. Merged with any stored profile data for the user.
dataobjectnoPayload data matching your schema. Available as variables throughout the journey.
curl -X POST https://api.courier.com/journeys/JOURNEY_ID/invoke \
  -H "Authorization: Bearer $COURIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "user_123",
    "data": {
      "order_id": "ORD-9042",
      "order_total": 49.99,
      "is_first_order": true,
      "order_date": "2026-02-10T14:30:00Z"
    }
  }'
The response returns a runId you can use to track the journey execution in Run Inspection.
{
  "runId": "1-67ab1234-a1b2c3d4e5f6"
}

Invoke with Profile Only

If you don’t have a stored Courier user, you can invoke with just a profile containing contact information. Courier will use the profile data to deliver messages without requiring a user ID.
curl -X POST https://api.courier.com/journeys/JOURNEY_ID/invoke \
  -H "Authorization: Bearer $COURIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "profile": {
      "email": "jane@example.com"
    },
    "data": {
      "signup_source": "landing_page"
    }
  }'

Profile Enrichment

When you invoke a journey with a user_id, Courier loads the user’s stored profile and merges it with any profile data you include in the request. Request fields override stored fields with the same key; stored fields not present in the request are preserved.
stored profile:  { "email": "stored@example.com", "first_name": "Jane" }
request profile: { "email": "new@example.com" }
result:          { "email": "new@example.com", "first_name": "Jane" }

Tenant-Scoped Profiles

If your application uses tenants, include the tenant ID in the profile context. Courier will load the user’s tenant-scoped profile data.
{
  "user_id": "user_123",
  "profile": {
    "context": {
      "tenant_id": "hospital-a"
    }
  },
  "data": {
    "appointment_time": "2026-02-15T09:00:00Z"
  }
}

cURL Preview

The journey editor generates a ready-to-use cURL command for every API-triggered journey. Click Show next to “Invoke cURL” in the trigger configuration panel to see the command with your journey ID and schema fields pre-filled.

Error Handling

StatusErrorMeaning
400Bad RequestMissing required fields, invalid types, or missing user identifier. Check your schema and ensure user_id or profile is provided.
404Not FoundThe journey ID doesn’t exist or hasn’t been published.
422Unprocessable EntityThe journey exists but can’t run. Common causes: trigger conditions not met, or the journey is archived.

Segment

The Segment trigger connects a journey to your existing Segment event stream. When Courier receives an event that matches your trigger configuration, the journey starts automatically. No API integration is required; if you already send events to Segment, those same events can trigger journeys in Courier. This makes Segment triggers useful for behavioral flows driven by events you already track: feature adoption, lifecycle milestones, or engagement signals. Segment acts as a centralized event bus; the same events that push to your analytics tools, CRM, and marketing platforms can now drive notification workflows in Courier.

Supported Event Types

Event TypeDescription
TrackFires when a user performs an action (Order Completed, Feature Used, Plan Upgraded)
IdentifyFires when a user’s traits are updated (new email, name change, plan change)
GroupFires when a user is added to or updated within a group

Event Filtering

You can narrow which events trigger the journey by adding conditions. Conditions evaluate fields from the Segment event payload (event name, properties, traits) and only start the journey when all conditions are met. For example, a journey triggered by Track events could filter for event = "Order Completed" and properties.total > 100 to only run for high-value orders.

Trigger Conditions

Both API and Segment triggers support optional conditions. Conditions are evaluated before the journey starts; if any condition fails, the invocation is rejected (API returns 422) or the event is ignored (Segment). Conditions use the same operators available in branch nodes: equals, not equals, greater than, less than, contains, and more. You can reference any field available in the trigger’s data context.

What’s Next