Skip to main content
Journey API Triggers let you start a customer journey from anywhere outside the Tappd dashboard — your backend server, a payment webhook, a cron job, or any third-party integration. Instead of waiting for an in-app event, you send a single POST request with a customer identifier and an optional payload, and Tappd queues the enrollment immediately. All of the journey’s steps — messages, delays, conditions, and webhooks — then execute according to the journey’s configured rules.

Prerequisites

Before you make your first API trigger call, make sure you have:
  1. An API key — Generate one in Settings → API Keys inside the Tappd dashboard.
  2. An active journey — The journey must be published and configured with API as its trigger type.
  3. An existing customer — The customer must already exist in your workspace. Use the SDK’s identify() method or the Customers API to create them first.

Endpoint

POST https://sdk.gotappd.com/api/v1/journeys/:workspaceId/:journeyId/trigger

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Replace :workspaceId and :journeyId with the IDs found in your Tappd dashboard.

Request Parameters

Single Customer

Use these fields to trigger a journey for one customer at a time.
external_id
string
Your internal user ID (also accepted as externalId). This is the most common identifier to use — it matches the value you pass to identify() in the SDK.
email
string
The customer’s email address. Use this as an alternative to external_id when you only have the email available.
customerId
string
The Tappd customer ID. Use this when you already have the Tappd customer record and want the most direct lookup.
payload
object
A custom JSON object sent alongside the trigger (also accepted as properties). Values are available in Liquid templates throughout the journey using {{ api.properties.* }} or {{ api.payload.* }}.

Bulk Operations

Use these fields to enroll multiple customers in a single request.
external_ids
string[]
An array of your internal user IDs (also accepted as externalIds). Maximum 1,000 entries. Customers whose IDs are not found are silently skipped — no error is returned for individual missing IDs.
segment_ids
string[]
An array of Tappd segment IDs (also accepted as segmentIds). Enrolls every customer who belongs to those segments. Maximum 10 segments per request. An invalid segment ID returns an error for the entire request.
exclude_external_ids
string[]
An array of external IDs to exclude from enrollment (also accepted as excludeExternalIds). Applied after any intersection logic. Maximum 1,000 entries.
payload
object
A custom JSON object shared with all enrolled customers (also accepted as properties). Available in Liquid templates as {{ api.properties.* }}.
If you supply both external_ids and segment_ids, only customers who appear in both sets are enrolled (intersection). Use exclude_external_ids to remove specific customers from the final list regardless of how they were matched.

Code Examples

curl -X POST \
  'https://sdk.gotappd.com/api/v1/journeys/WORKSPACE_ID/JOURNEY_ID/trigger' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "external_id": "user_12345",
    "payload": {
      "orderId": "ORD-12345",
      "orderTotal": 99.99,
      "currency": "USD"
    }
  }'

Response Format

Single customer success:
{
  "success": true,
  "message": "Journey triggered successfully",
  "data": {
    "customerId": "507f1f77bcf86cd799439011",
    "journeyId": "507f1f77bcf86cd799439012",
    "status": "queued",
    "queued": true,
    "jobId": "enroll-507f1f77bcf86cd799439012-507f1f77bcf86cd799439011-1704067200000",
    "note": "Enrollment is queued and will be confirmed after entry rules validation"
  }
}
Bulk operation success:
{
  "success": true,
  "message": "Journey triggered successfully",
  "data": {
    "journeyId": "507f1f77bcf86cd799439012",
    "status": "queued",
    "queued": true,
    "customersEnrolled": 3,
    "customerIds": [
      "507f1f77bcf86cd799439011",
      "507f1f77bcf86cd799439012",
      "507f1f77bcf86cd799439013"
    ],
    "jobIds": [
      "enroll-507f1f77bcf86cd799439012-507f1f77bcf86cd799439011-1704067200000",
      "enroll-507f1f77bcf86cd799439012-507f1f77bcf86cd799439012-1704067200001",
      "enroll-507f1f77bcf86cd799439012-507f1f77bcf86cd799439013-1704067200002"
    ],
    "note": "Enrollments are queued and will be confirmed after entry rules validation"
  }
}

Error Responses

ErrorHTTP StatusCause
Customer not found404No customer matched the supplied external_id, email, or customerId
Journey not found404The journey ID doesn’t exist or the journey is not active
Invalid journey type400The journey’s trigger type is not set to API
Missing required parameter400No customer identifier was supplied in the request body
Array size exceeded400external_ids contains more than 1,000 entries
Error resolving segments400One or more segment_ids don’t exist in the workspace
Missing entries in the external_ids array are silently skipped. Invalid segment_ids, however, fail the entire request — verify your segment IDs before sending bulk calls.

Using Payload Data in Journeys

The payload (or properties) object you include in the trigger request is available in every Liquid template inside the journey. Access payload values using either syntax:
{{ api.properties.orderId }}
{{ api.payload.orderId }}
Example — trigger payload:
{
  "external_id": "user_123",
  "payload": {
    "orderId": "ORD-12345",
    "orderTotal": 99.99,
    "productName": "Premium Plan"
  }
}
Example — Liquid template in an in-app message:
Thank you for your purchase!

Order ID: {{ api.properties.orderId }}
Total: ${{ api.properties.orderTotal }}
Product: {{ api.properties.productName }}
Rendered output:
Thank you for your purchase!

Order ID: ORD-12345
Total: $99.99
Product: Premium Plan
You can also forward payload data through journey webhook steps:
{
  "url": "https://example.com/webhook",
  "method": "POST",
  "body": {
    "orderId": "{{ api.properties.orderId }}",
    "customerEmail": "{{ customer.email }}",
    "orderTotal": "{{ api.properties.orderTotal }}"
  }
}

Journey Configuration

1

Create a Journey

Open the Tappd dashboard and create a new journey, or open an existing draft journey.
2

Set Trigger Type to API

In the journey’s settings panel, set the Trigger Type to API. Only journeys with this trigger type can be started via the API endpoint.
3

Configure Entry Rules

Optionally, set entry rules to control how customers enter the journey:
  • Maximum entries per customer — how many times a single customer can enroll
  • Re-enrollment — whether customers can re-enter after completing the journey
  • Entry conditions — additional attribute or event conditions that must be met before enrollment is confirmed
4

Add Steps

Build out the journey with messages, delays, conditions, webhooks, and any other steps your workflow requires.
5

Publish the Journey

Publish the journey to make it live. The API endpoint will return an error for unpublished or inactive journeys.

Re-Enrollment Behavior

Understanding how re-enrollment works helps you avoid unexpected behavior when triggering the same journey for a customer more than once. Multiple entries allowed (maxEntriesPerCustomer > 1): If the customer has fewer completed entries than the maximum, any active enrollment is exited and a new one is created immediately. Single entry only (maxEntriesPerCustomer is 1 or not set): If the customer has an active or completed enrollment, the API returns an “already enrolled” status. Enable re-enrollment in the journey settings to allow customers to re-enter after they complete the journey.

Rate Limiting

The Journey Trigger API enforces a limit of 100 requests per minute per API key. Requests that exceed this limit receive a 429 Too Many Requests response. Check the rate limit headers in the response to track your current usage and implement exponential backoff in high-volume scenarios.

Use Cases

E-Commerce Order Confirmation

Trigger an order confirmation journey immediately after checkout completes. Pass order details — ID, total, items, shipping address — in the payload and use them to personalize every step.
await triggerJourney(workspaceId, journeyId, order.customerId, {
  orderId: order.id,
  orderTotal: order.total,
  items: order.items,
  shippingAddress: order.shippingAddress,
});

Subscription Management

Fire a journey when a customer upgrades, downgrades, or cancels their subscription. Use the payload to tailor messaging based on their previous and new plan tiers.
await triggerJourney(workspaceId, journeyId, user.externalId, {
  subscriptionTier: "premium",
  upgradeDate: new Date().toISOString(),
  previousTier: "basic",
});

Event Registration

Enroll registrants into a confirmation and reminder journey the moment they sign up for an event. Include event details in the payload so the messages feel personal and timely.
await triggerJourney(workspaceId, journeyId, user.email, {
  eventId: event.id,
  eventName: event.name,
  eventDate: event.date,
  ticketType: "vip",
});

Webhook Integration (Stripe, etc.)

Receive a webhook from a payment processor or any third-party service and immediately enroll the customer in the appropriate journey — no manual intervention needed.
app.post("/webhook/stripe", async (req, res) => {
  const { customer, amount } = req.body;
  await triggerJourney(workspaceId, journeyId, customer.id, {
    paymentAmount: amount,
    paymentMethod: "stripe",
    timestamp: new Date().toISOString(),
  });
  res.json({ success: true });
});