Appearance
Sequences API Documentation
The Sequences API allows external systems to trigger automated message sequences based on customer events. This API provides a secure, authenticated gateway for external integrations like e-commerce platforms, CRM systems, and custom applications to enroll customers in automated messaging sequences.
Base URL
https://api.talkingshops.com/v1Authentication
All API requests require authentication using an API key. Include your API key in the request header:
x-tenant-api-key: your_api_key_hereAPI keys are tenant-specific and automatically provide access to the correct sequence data for your business account.
Rate Limiting
The API implements rate limiting to prevent abuse. By default, each tenant is limited to 100 requests per minute.
Service Availability
If the Sequences service is unavailable, the API returns 503 ServiceUnavailable.
Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
POST | /sequences/events | Fire an event to trigger sequence enrollments |
POST | /sequences/events/batch | Process multiple events in a single request (max 100) |
GET | /sequences/triggers | List all available trigger types |
POST | /sequences/triggers | Create a custom trigger type |
DELETE | /sequences/triggers/{slug} | Delete a custom trigger type |
POST | /sequences/enroll | Enroll a customer directly by trigger type |
Trigger Types
The system supports the following built-in trigger types:
E-commerce
| Trigger Type | Description |
|---|---|
abandoned_cart | Customer adds items to cart but doesn't complete purchase |
order_completed | Customer completes an order |
order_delivered | Order is delivered to customer |
payment_success | Payment is successfully processed |
payment_failed | Payment processing fails |
first_purchase | Customer's first-ever purchase |
product_viewed | Customer views a product |
Customer Lifecycle
| Trigger Type | Description |
|---|---|
customer_inactive | Customer has been inactive for X days |
inactive_after_first_message | Customer inactive after first bot interaction |
Bookings & Appointments
| Trigger Type | Description |
|---|---|
booking_completed | Customer confirms a booking |
booking_cancelled | Customer cancels a booking |
Lead Management
| Trigger Type | Description |
|---|---|
lead_form_completed | Customer completes a lead capture form |
lead_document_uploaded | Customer uploads documents |
Support & Engagement
| Trigger Type | Description |
|---|---|
agent_handoff | Customer is transferred to a live agent |
support_requested | Customer requests live support |
message_no_reply | Customer doesn't reply within X hours |
Segments
| Trigger Type | Description |
|---|---|
segment_entered | Customer enters a specific segment |
segment_exited | Customer exits a specific segment |
Date-Based & Custom
| Trigger Type | Description |
|---|---|
date_based | Scan supported entities by date field (birthdays, anniversaries, expiry dates) |
recurring_date | Recurring date trigger (birthday, subscription reminders) |
custom_event | Generic custom event from external systems |
Task Management
| Trigger Type | Description |
|---|---|
task_due | Task due date approaches |
Fire Event
POST /sequences/events
Fire an event that may trigger enrollment in one or more sequences. The event type must match a sequence's trigger configuration.
Deduplication
Use deduplicationKey to prevent duplicate enrollments from retried webhook calls. If an event with the same key was already processed, it will be skipped.
Request
json
{
"eventType": "abandoned_cart",
"customerMobile": "+919876543210",
"customerId": "cust_12345",
"deduplicationKey": "cart:abcd1234:1704067200000",
"eventData": {
"cartId": "cart_abc123",
"items": [
{ "productId": "prod_001", "name": "Premium T-Shirt", "price": 29.99, "quantity": 2 }
],
"totalAmount": 59.98,
"currency": "USD"
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
eventType | string | Yes | Trigger type slug (e.g., abandoned_cart, order_completed) |
customerMobile | string | Yes | WhatsApp phone number with country code in E.164 format (e.g., +919876543210) |
customerId | string | No | Your internal customer ID |
deduplicationKey | string | No | Unique key to prevent duplicate event processing |
eventData | object | No | Arbitrary data passed to message templates |
Response (200 OK)
json
{
"success": true,
"enrollments": [
{
"sequenceId": "seq_cart_recovery_001",
"sequenceName": "Cart Recovery",
"enrollmentId": "enr_abc123def456",
"firstStepAt": "2024-01-01T10:00:00.000Z"
}
],
"skipped": [],
"errors": []
}Response Fields
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the event was processed |
enrollments | array | List of successful enrollments |
enrollments[].sequenceId | string | ID of the sequence the customer was enrolled in |
enrollments[].sequenceName | string | Name of the sequence |
enrollments[].enrollmentId | string | Unique enrollment ID |
enrollments[].firstStepAt | string | ISO 8601 timestamp when the first message will be sent |
skipped | array | Sequences that were skipped (e.g., customer already enrolled) |
errors | array | Any errors encountered during enrollment |
Batch Events
POST /sequences/events/batch
Process multiple events in a single request. Each event is processed independently. Maximum 100 events per request.
Batch Processing
Events are processed sequentially — batch size should be chosen based on your timeout requirements. For high-throughput scenarios, consider processing events in parallel from your client.
Request
json
{
"events": [
{
"eventType": "abandoned_cart",
"customerMobile": "+919876543210",
"deduplicationKey": "cart:abcd1234:1704067200000",
"eventData": { "cartId": "cart_001", "totalAmount": 59.98 }
},
{
"eventType": "order_completed",
"customerMobile": "+14155552671",
"customerId": "cust_67890",
"eventData": { "orderId": "order_xyz789", "totalAmount": 149.99 }
}
]
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
events | array | Yes | Array of event objects (1–100 items) |
events[].eventType | string | Yes | Trigger type slug |
events[].customerMobile | string | Yes | E.164 phone number |
events[].customerId | string | No | Internal customer ID |
events[].deduplicationKey | string | No | Deduplication key for this event |
events[].eventData | object | No | Event-specific data |
Response (200 OK)
json
{
"success": true,
"processed": 2,
"enrolled": 2,
"skipped": 0,
"errors": [],
"results": [
{
"eventType": "abandoned_cart",
"customerMobile": "+919876543210",
"status": "enrolled",
"enrollments": [
{
"sequenceId": "seq_cart_recovery_001",
"sequenceName": "Cart Recovery",
"enrollmentId": "enr_abc123def456"
}
]
},
{
"eventType": "order_completed",
"customerMobile": "+14155552671",
"status": "enrolled",
"enrollments": [
{
"sequenceId": "seq_thank_you_001",
"sequenceName": "Thank You",
"enrollmentId": "enr_def456ghi789"
}
]
}
]
}List Triggers
GET /sequences/triggers
Get all trigger types available for your tenant, including built-in system triggers and any custom triggers you've created.
Response (200 OK)
json
{
"triggers": [
{
"slug": "abandoned_cart",
"name": "Cart Created",
"description": "Triggered when customer creates/abandons a cart",
"category": "e-commerce",
"isBuiltIn": true,
"isScheduled": false
},
{
"slug": "recurring_date",
"name": "Date Trigger",
"description": "Birthday, anniversary, subscription expiry, or any custom date field",
"category": "date-based",
"isBuiltIn": true,
"isScheduled": true
},
{
"slug": "my_custom_trigger",
"name": "My Custom Trigger",
"description": "Custom event for my integration",
"category": "custom",
"isBuiltIn": false,
"isScheduled": false,
"eventDataSchema": {}
}
],
"dateTriggerEntities": [
{
"entityType": "customer",
"knownDateFields": ["created_at", "custom_fields.birthday", "custom_fields.subscription_end_date"],
"supportsCustomDateFields": true
},
{
"entityType": "booking",
"knownDateFields": ["booking_date", "booking_end_date"],
"supportsCustomDateFields": true
},
{
"entityType": "order",
"knownDateFields": ["order_date", "delivery_date"],
"supportsCustomDateFields": false
},
{
"entityType": "task",
"knownDateFields": ["due_date"],
"supportsCustomDateFields": true
}
]
}dateTriggerEntities
The dateTriggerEntities array is required by the ssp-ui dashboard for configuring date-based triggers. If you're building an integration that creates sequences programmatically, use entityType: "customer" with knownDateFields to determine which date fields are available.
Create Trigger
POST /sequences/triggers
Register a custom trigger type for your tenant. Custom triggers allow you to define event types specific to your business that can then be used to create sequences in the dashboard.
Trigger Slug Rules
The slug must be unique across your tenant and cannot conflict with built-in trigger slugs. It must follow the pattern: starts with a lowercase letter, followed by lowercase letters, numbers, or underscores (e.g., high_value_purchase, app_installed).
Request
json
{
"slug": "high_value_purchase",
"name": "High Value Purchase",
"description": "Triggered when customer completes a purchase over $500",
"eventDataSchema": {
"type": "object",
"properties": {
"orderId": { "type": "string" },
"totalAmount": { "type": "number" },
"currency": { "type": "string" }
},
"required": ["orderId", "totalAmount"]
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | Yes | Unique identifier (lowercase, ^[a-z][a-z0-9_]*$, 2–50 chars) |
name | string | Yes | Human-readable name (min 2 chars) |
description | string | No | Description of when this trigger fires |
eventDataSchema | object | No | JSON Schema for validating event data |
Response (201 Created)
json
{
"slug": "high_value_purchase",
"name": "High Value Purchase",
"description": "Triggered when customer completes a purchase over $500",
"category": "custom",
"isBuiltIn": false,
"isScheduled": false,
"eventDataSchema": {
"type": "object",
"properties": {
"orderId": { "type": "string" },
"totalAmount": { "type": "number" }
}
}
}Delete Trigger
DELETE /sequences/triggers/{slug}
Remove a custom trigger type. Built-in triggers cannot be deleted.
Cannot Delete In-Use Triggers
You cannot delete a trigger that is currently used by any active sequences. Pause or archive those sequences first.
Response (200 OK)
json
{
"success": true,
"message": "Trigger deleted successfully"
}Error Response (400 Bad Request)
json
{
"error": "Cannot delete trigger \"high_value_purchase\" - used by 2 active sequence(s)"
}Enroll Customer
POST /sequences/enroll
Enroll a customer directly in all sequences matching a given trigger type. This is equivalent to firing an event via POST /sequences/events but uses a simpler request format that specifies the trigger type explicitly rather than inferring it from the event.
Request
json
{
"customerMobile": "+919876543210",
"triggerType": "abandoned_cart",
"customerId": "cust_12345",
"orderId": "order_abc123",
"eventData": {
"cartId": "cart_xyz789",
"totalAmount": 129.99
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerMobile | string | Yes | E.164 phone number |
triggerType | string | Yes | Trigger type slug to match sequences against |
customerId | string | No | Internal customer ID |
orderId | string | No | Associated order ID |
eventData | object | No | Data passed to message templates |
Response (200 OK)
json
{
"success": true,
"enrollments": [
{
"sequenceId": "seq_cart_recovery_001",
"sequenceName": "Cart Recovery",
"enrollmentId": "enr_abc123def456"
}
]
}Response (400 Bad Request — Opted Out)
json
{
"success": false,
"error": "Customer has opted out of marketing messages"
}Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
400 | ValidationError | Invalid request body or parameters |
401 | Unauthorized | Missing or invalid API key |
404 | NotFound | Trigger not found |
400 | EnrollmentError | Cannot enroll customer (e.g., opted out) |
503 | ServiceUnavailable | Utility service not configured |
Integration Examples
E-commerce: Abandoned Cart Recovery
javascript
// After a user abandons their cart
async function onCartAbandoned(cartData) {
const response = await fetch('https://api.talkingshops.com/v1/sequences/events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-tenant-api-key': process.env.TALKINGSHOPS_API_KEY
},
body: JSON.stringify({
eventType: 'abandoned_cart',
customerMobile: cartData.mobile,
customerId: cartData.customerId,
deduplicationKey: `cart:${cartData.cartId}:${Date.now()}`,
eventData: {
cartId: cartData.cartId,
items: cartData.items,
totalAmount: cartData.total,
currency: cartData.currency,
checkoutUrl: cartData.checkoutUrl
}
})
});
const result = await response.json();
console.log(`Enrolled in ${result.enrollments?.length ?? 0} sequences`);
}E-commerce: Order Completion
javascript
async function onOrderCompleted(orderData) {
const response = await fetch('https://api.talkingshops.com/v1/sequences/events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-tenant-api-key': process.env.TALKINGSHOPS_API_KEY
},
body: JSON.stringify({
eventType: 'order_completed',
customerMobile: orderData.mobile,
customerId: orderData.customerId,
deduplicationKey: `order:${orderData.orderId}:${Date.now()}`,
eventData: {
orderId: orderData.orderId,
items: orderData.items,
totalAmount: orderData.total,
currency: orderData.currency
}
})
});
return response.json();
}CRM: Lead Form Submission
javascript
async function onLeadFormSubmitted(leadData) {
const response = await fetch('https://api.talkingshops.com/v1/sequences/enroll', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-tenant-api-key': process.env.TALKINGSHOPS_API_KEY
},
body: JSON.stringify({
customerMobile: leadData.mobile,
triggerType: 'lead_form_completed',
customerId: leadData.customerId,
eventData: {
formId: leadData.formId,
source: leadData.source,
interests: leadData.interests
}
})
});
return response.json();
}Custom Integration: Custom Event
javascript
// If you have a custom trigger "high_value_purchase" created via the dashboard
async function onHighValuePurchase(purchaseData) {
const response = await fetch('https://api.talkingshops.com/v1/sequences/events', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-tenant-api-key': process.env.TALKINGSHOPS_API_KEY
},
body: JSON.stringify({
eventType: 'high_value_purchase',
customerMobile: purchaseData.mobile,
customerId: purchaseData.customerId,
deduplicationKey: `purchase:${purchaseData.orderId}`,
eventData: {
orderId: purchaseData.orderId,
totalAmount: purchaseData.total,
currency: purchaseData.currency,
items: purchaseData.items
}
})
});
return response.json();
}Related Documentation
- Marketing Campaigns — Learn how to create and manage sequences in the dashboard
- WhatsApp Messaging API — Full API documentation
- Getting Started with WhatsApp Commerce — Platform overview