Marketing Journeys
Journeys (also called flows) are multi-step automations: a trigger enrolls a contact,
then the contact moves from step to step over time. You manage them with the journeys tRPC
router on the Platform API, called at
/api/trpc/journeys.<procedure> using the tRPC conventions. The
procedures (except tick) act on the current site of your session.
Today, only EMAIL steps have an effect. The SMS step is skipped, and the other action
steps only move the contact forward. A WEBHOOK step does not emit an outbound request.
Check the step types table below before you design a journey.
Procedures
| Procedure | Purpose | Permission |
|---|---|---|
list |
List the site's journeys, with step and enrollment counts. | automation:read |
get |
Fetch one journey and its steps. | automation:read |
create |
Create a journey (inactive, no steps). | automation:write |
update |
Update journey metadata (name, description, priority). | automation:write |
updateSteps |
Replace the journey's ordered steps (up to 50). Inactive journeys only. | automation:write |
activate |
Activate a journey (it starts firing). | automation:write |
pause |
Pause a journey. | automation:write |
setActive |
Set the active state explicitly. | automation:write |
listTemplates |
List ready-made templates. | automation:read |
createFromTemplate |
Create a journey from a template. | automation:write |
listEnrollments |
List enrollments. | automation:read |
enroll |
Enroll a contact manually. | automation:write |
getStats |
Site statistics: number of journeys, active journeys, enrollments by status. | automation:read |
tick |
Advance enrollments that are due. The platform already calls it on a regular schedule. | automation:write |
Input parameters
| Procedure | Input |
|---|---|
list |
activeOnly? (boolean). |
get, activate, pause |
id (journey UUID). |
create |
name (1 to 100 characters), description? (up to 500), trigger? (defaults to MANUAL), priority? (1 to 1000, default 100), maxDurationDays? (1 to 365), templateKey?. |
update |
id, then name?, description?, priority?. |
updateSteps |
id, steps: an array of steps (see "Steps and timing" below). |
setActive |
id, isActive (boolean). |
createFromTemplate |
templateKey (the template key), name?. If the name already exists on the site, a (2), (3)… suffix is added. |
listEnrollments |
journeyId?, status? (ACTIVE, PAUSED, COMPLETED, EXITED, ERROR), limit? (1 to 500, default 100). Newest first. |
enroll |
journeyId, then a contact: clientId, leadId or email (with firstName?, lastName?). |
Common errors:
| Code | Case |
|---|---|
NOT_FOUND |
The journey does not exist on the current site. |
BAD_REQUEST |
updateSteps on an active journey (pause it first), unknown template key, or enroll without clientId, leadId or email. |
Triggers
A journey starts when its trigger occurs for a contact:
| Trigger | Occurs on |
|---|---|
NEWSLETTER_SIGNUP |
A newsletter signup, a public signup form, or a consented opt-in on a contest or Wi-Fi portal. |
CART_ABANDONED |
A cart detected as abandoned. |
ORDER_MINTED |
An order being paid. |
DATE_WINBACK |
A customer becoming inactive. |
MANUAL |
An explicit journeys.enroll call. |
Steps and timing
Each step has a name (1 to 120 characters), a stepType, a delayMinutes value (an
integer from 0 to 525,600, i.e. one year) and, depending on the type, an actionData object.
The delay is counted from when the previous step ran: a step with delayMinutes: 4320 runs
three days after the one before it. The first step's delay is counted from enrollment.
The status column describes each step type's current behaviour:
| Step type | Status |
|---|---|
EMAIL |
Active: the only step that sends. |
WAIT |
Flow control: does nothing itself; use its delay to space out the next step. |
CONDITION |
Flow control: marker only, no branching is evaluated. |
GOAL |
Flow control: goal marker. |
SMS |
No effect: skipped, no SMS is sent. |
WEBHOOK |
No effect: emits no outbound request. |
UPDATE_FIELD |
No effect. |
ADD_TO_SEGMENT |
No effect. |
REMOVE_FROM_SEGMENT |
No effect. |
CREATE_TASK |
No effect. |
SEND_NOTIFICATION |
No effect. |
A "no effect" step is traversed (the enrollment moves on to the next step), but it changes nothing and sends nothing. Do not rely on it for a business action. When the last step has run, the enrollment is completed.
EMAIL step
The actionData of an EMAIL step accepts:
| Key | Purpose |
|---|---|
emailType |
Email type. If an email template is configured for this type on the site, it takes precedence. |
fallbackSubject |
Subject used when no template is configured (defaults to "Notification"). |
fallbackHtml |
HTML used when no template is configured. With neither a template nor fallbackHtml, the send fails. |
variables |
Extra variables for the configured email template. {{firstName}} and {{lastName}} are always provided. fallbackHtml is sent as is, without variable substitution. |
The email goes to the contact's address; unsubscribed recipients are filtered out. If the send fails (contact without an address, no content), the failure is recorded and the enrollment still moves on to the next step.
updateSteps replaces the whole list: array order becomes step order. A step sent with its
existing id is updated in place (in-flight enrollments keep it); a step without an id is
created; a step missing from the array is deleted, and enrollments sitting on it are
completed.
curl -X POST "https://manage.inklura.fr/api/trpc/journeys.updateSteps" \
-H "Authorization: Bearer $INKLURA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"json":{"id":"<journey-id>","steps":[
{"name":"Welcome","stepType":"EMAIL","delayMinutes":0,
"actionData":{"emailType":"journey.welcome.intro",
"fallbackSubject":"Welcome",
"fallbackHtml":"<p>Hello,</p>"}},
{"name":"Follow-up","stepType":"EMAIL","delayMinutes":4320,
"actionData":{"fallbackSubject":"Getting started",
"fallbackHtml":"<p>A few resources to get started.</p>"}}
]}}'
Maximum duration
maxDurationDays (on create, or set by the template) caps an enrollment's lifetime: once
that many days have passed since enrollment, it is completed without running the remaining
steps.
Ready-made templates
listTemplates exposes ready-made journeys; createFromTemplate creates one:
| Template | Trigger | Sequence | Maximum duration |
|---|---|---|---|
welcome |
NEWSLETTER_SIGNUP |
Emails at D+0, D+3 and D+10, then a GOAL. |
30 days |
abandoned-cart |
CART_ABANDONED |
Emails 1 h after enrollment, then 24 h after enrollment. | 7 days |
post-purchase |
ORDER_MINTED |
Thank-you at D+0, review request at D+7. | 30 days |
win-back |
DATE_WINBACK |
D+0, then D+3. | 21 days |
Template emails carry an emailType and French fallback content; configure an email
template for that type, or replace the steps with updateSteps, to adapt the text.
create and createFromTemplate create an inactive journey. Nothing fires until an
admin activates it with activate.
How enrollment happens
Automatic enrollment only targets an active journey with the matching trigger (if several
match, the one with the lowest priority value). A contact is enrolled only once per journey.
| Trigger | Enrollment | Default |
|---|---|---|
NEWSLETTER_SIGNUP |
At the time of the public signup. The contact is found or created as a lead from their email. | On. |
CART_ABANDONED |
A regular search for non-empty carts of an identified customer, idle for more than 1 hour (and less than 14 days), processed in batches. | On. |
DATE_WINBACK |
A regular search for customers whose orders are all older than 90 days, processed in batches. | On. |
ORDER_MINTED |
When the order is paid. | Off: this trigger does not enroll automatically yet. |
MANUAL |
By calling journeys.enroll with a journeyId and a contact (clientId, leadId or email). |
n/a |
With enroll, clientId wins, then leadId; with only email, the matching lead is found
or created. enroll does not check that the journey is active. The response (under
result.data.json) reports the outcome:
{ "enrolled": true, "enrollmentId": "<enrollment-id>", "journeyId": "<journey-id>" }
When nothing happens, enrolled is false and reason says why: already-enrolled (the
contact is already in this journey) or journey-has-no-steps.
Once a contact is enrolled, the platform advances due enrollments with a
scheduled task that calls journeys.tick. You do not need to call
it yourself.
pause stops new automatic enrollments, but enrollments already in progress keep advancing
and sending their emails.
Defining and activating a journey
journeys.createFromTemplate (or: journeys.create + journeys.updateSteps)
│
▼
journeys.activate
To change the steps of an active journey: pause, then updateSteps, then activate.
After activate:
- enrollment happens automatically according to the trigger (see the table above);
- or you enroll contacts manually with
journeys.enroll(theMANUALtrigger).
Related
- Scheduled Jobs
- Email & MJML
- tRPC Procedures: how to call
journeys.*