Journey API Triggers
Trigger customer journeys programmatically via API endpoints. This allows you to integrate Tappd journeys with external systems, webhooks, and custom automation workflows.
Overview
API-triggered journeys enable:
- External System Integration: Trigger journeys from your backend services
- Webhook Callbacks: Trigger journeys from third-party webhooks
- Real-time Activation: Trigger journeys immediately based on events
- Custom Automation: Build custom workflows that trigger journeys
Prerequisites
- API Key: Get your API key from Settings > API Keys in the Tappd dashboard
- Active Journey: Create a journey with API trigger type in the dashboard
- Customer Exists: Ensure the customer exists in your workspace (identified via SDK or API)
Endpoint
Trigger Journey
Endpoint: POST /api/v1/journeys/:workspaceId/:journeyId/trigger
Base URL: https://sdk.gotappd.com/api/v1/journeys (or your custom API URL)
Authentication: API Key via Authorization header
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonRequest Format
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | String | Yes | Your workspace ID |
journeyId | String | Yes | The journey ID to trigger |
Request Body
{
"external_id": "user_12345",
"payload": {
"orderId": "ORD-12345",
"orderTotal": 99.99,
"productName": "Premium Plan"
}
}Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
external_id or externalId | String | Yes* | External customer identifier (your internal user ID) |
email | String | Yes* | Customer email address |
customerId | String | Yes* | Tappd customer ID (ObjectId) |
payload or properties | Object | No | Custom payload data (available in Liquid templates) |
Note: At least one of external_id, email, or customerId must be provided to identify the customer.
Examples
Example 1: Using External ID
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",
"items": [
{
"name": "Product A",
"quantity": 2,
"price": 49.99
}
]
}
}'Example 2: Using Email
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 '{
"email": "customer@example.com",
"payload": {
"eventType": "purchase_completed",
"amount": 199.99
}
}'Example 3: Using Customer ID
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 '{
"customerId": "507f1f77bcf86cd799439011",
"payload": {
"subscriptionTier": "premium",
"upgradeDate": "2024-01-15"
}
}'Example 4: JavaScript/Node.js
async function triggerJourney(workspaceId, journeyId, customerId, payload) {
const response = await fetch(
`https://sdk.gotappd.com/api/v1/journeys/${workspaceId}/${journeyId}/trigger`,
{
method: 'POST',
headers: {
'Authorization': `Bearer YOUR_API_KEY`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
external_id: customerId,
payload: payload
})
}
);
const result = await response.json();
return result;
}
// Usage
await triggerJourney(
'workspace_123',
'journey_456',
'user_789',
{
orderId: 'ORD-12345',
orderTotal: 99.99
}
);Example 5: Python
import requests
def trigger_journey(workspace_id, journey_id, external_id, payload):
url = f"https://sdk.gotappd.com/api/v1/journeys/{workspace_id}/{journey_id}/trigger"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"external_id": external_id,
"payload": payload
}
response = requests.post(url, json=data, headers=headers)
return response.json()
# Usage
result = trigger_journey(
"workspace_123",
"journey_456",
"user_789",
{
"orderId": "ORD-12345",
"orderTotal": 99.99
}
)Response Format
Success Response
{
"success": true,
"message": "Journey triggered successfully",
"data": {
"customerId": "507f1f77bcf86cd799439011",
"journeyId": "507f1f77bcf86cd799439012",
"status": "queued",
"queued": true,
"jobId": "enroll-507f1f77bcf86cd799439012-507f1f77bcf86cd799439011-1704067200000",
"note": "Enrollment will be created by worker after entry rules validation"
}
}Error Responses
Customer Not Found
{
"success": false,
"error": "Customer not found",
"message": "Customer with external_id \"user_12345\" not found in this workspace. Please ensure the customer exists before triggering the journey."
}Journey Not Found or Inactive
{
"success": false,
"error": "Journey not found",
"message": "Journey not found or is not active"
}Invalid Journey Type
{
"success": false,
"error": "Invalid journey type",
"message": "This journey is not configured for API triggering. Current trigger type: event. Only journeys with API trigger type can be triggered via API."
}Missing Required Parameter
{
"success": false,
"error": "Missing required parameter",
"message": "external_id (or externalId) is required"
}Using Payload Data in Journeys
The payload data you send is available in Liquid templates throughout the journey.
Accessing Payload Data
In Liquid templates, access payload data using:
{ { api.properties.* } }- Access payload properties{ { api.payload.* } }- Alternative access method
Example: Using Payload in In-App Message
Payload sent:
{
"external_id": "user_123",
"payload": {
"orderId": "ORD-12345",
"orderTotal": 99.99,
"productName": "Premium Plan"
}
}
```text
**Liquid template in message:**Thank you for your purchase!
Order ID: { { api.properties.orderId } } Total: ${ { api.properties.orderTotal } } Product: { { api.properties.productName } }
**Rendered output:**
```text
Thank you for your purchase!
Order ID: ORD-12345
Total: $99.99
Product: Premium PlanExample: Using Payload in Webhook
Webhook configuration:
{
"url": "https://example.com/webhook",
"method": "POST",
"body": {
"orderId": "{ { api.properties.orderId } }",
"customerEmail": "{ { customer.email } }",
"orderTotal": "{ { api.properties.orderTotal } }"
}
}Journey Configuration
Setting Up API-Triggered Journey
- Create Journey in the Tappd dashboard
- Set Trigger Type to "API"
- Configure Entry Rules (optional):
- Maximum entries per customer
- Re-enrollment settings
- Entry conditions
- Add Steps to your journey
- Publish Journey
Entry Rules
API-triggered journeys respect entry rules:
- Max Entries Per Customer: Limits how many times a customer can enter
- Re-enrollment: Controls whether customers can re-enter completed journeys
- Entry Conditions: Additional conditions that must be met
Re-enrollment Behavior
Multiple Entries Allowed
If maxEntriesPerCustomer is set (e.g., 5), and the customer has fewer completed entries:
- The system will exit any active enrollment
- Create a new enrollment
- Process the new enrollment
Single Entry Only
If maxEntriesPerCustomer is 1 or not set:
- If customer has an active enrollment: Returns "already enrolled"
- If customer has a completed enrollment: Returns "already enrolled" (unless re-enrollment is enabled)
Rate Limiting
API journey triggers are rate-limited to prevent abuse:
- Default Limit: 100 requests per minute per API key
- Rate Limit Headers: Check response headers for rate limit information
- 429 Response: Returns 429 status code when rate limit is exceeded
Best Practices
- Identify Customers First: Ensure customers are identified via SDK before triggering journeys
- Use External IDs: Use your internal user IDs (
external_id) for consistency - Include Payload Data: Send relevant data in payload for personalization
- Handle Errors: Implement proper error handling for API responses
- Monitor Journey Performance: Track journey enrollment and completion rates
- Test Before Production: Test journey triggers in a development environment
- Use Webhooks: Configure webhooks in journeys to receive notifications
Use Cases
E-commerce Order Confirmation
// Trigger journey after order completion
await triggerJourney(workspaceId, journeyId, order.customerId, {
orderId: order.id,
orderTotal: order.total,
items: order.items,
shippingAddress: order.shippingAddress
});Subscription Upgrade
// Trigger journey when user upgrades subscription
await triggerJourney(workspaceId, journeyId, user.externalId, {
subscriptionTier: 'premium',
upgradeDate: new Date().toISOString(),
previousTier: 'basic'
});Event Registration
// Trigger journey when user registers for event
await triggerJourney(workspaceId, journeyId, user.email, {
eventId: event.id,
eventName: event.name,
eventDate: event.date,
ticketType: 'vip'
});Webhook Integration
// Trigger journey from webhook
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 });
});Troubleshooting
Journey Not Triggering
- Verify Journey Status: Ensure journey is active and published
- Check Trigger Type: Journey must have API trigger type
- Verify Customer Exists: Customer must exist in workspace
- Check Entry Rules: Verify entry rules allow enrollment
- Check API Key: Verify API key has correct permissions
Customer Not Found
- Identify Customer First: Use SDK
identify()method before triggering - Check External ID: Verify external_id matches your system
- Check Workspace: Ensure customer exists in correct workspace
Payload Not Available
- Check Payload Format: Ensure payload is a valid JSON object
- Use Correct Template: Use
{ { api.properties.* } }in Liquid templates - Verify Payload Keys: Check that property names match in templates
Related Documentation
- In-App Bridge - Bridge functionality for in-app messages
- In-App Messages - Complete in-app message guide
- API Reference - SDK API documentation
