What a journey is
A journey is a graph of steps (nodes) connected by paths (edges). A user enters the journey when an event matches its entry trigger, runs the step they land on, then waits at that step until a path out of it is satisfied. Crucially, the conditions live on the paths, not the steps — entering a step runs its action, then the engine takes the first outgoing path whose condition is true. This is what makes "wait for a purchase, otherwise remind after a day" a single step with two paths.
Note
Steps
| Step | What it does |
|---|---|
| Entry | The start. One per journey; users enter here. |
| Send message | Push, email, or SMS — fans out to every device the user has. |
| Wait (delay) | Pause for a fixed duration (minutes / hours / days). |
| Wait for event | Pause until an event fires or a timeout elapses — then branch. |
| Branch | Route by tag, segment, or rule. First matching path wins. |
| Update profile | Set a tag on the user (e.g. nurtured = true). |
| Webhook | Call an external system. |
| Exit | Marks the user complete and removes them from the journey. |
Path conditions
Each path between two steps carries one condition. Click a connection to set it:
| Condition | Takes the path when… |
|---|---|
| Always | Unconditional — the default/fallback path. |
| On event | The user fires the named event (e.g. purchase). |
| After delay | The step's wait timer elapses. |
| Tag matches | A profile tag compares true (plan = premium). |
| In segment | The user is a member of a saved segment. |
When several paths leave one step, lower priority numbers are tested first — so put specific conditions before an Always fallback.
Entry triggers
Set how users enter from the bar at the top of the builder:
- Any event — enroll on the first event a user fires (good for "new user" flows).
- Specific event — enroll only on a named event, e.g.
cart_created. - API-triggered — your backend enrolls a user explicitly (below).
From the SDK
Events from your app are the primary trigger. Tracking an event can enroll and advance users:
await Payghaam.instance.trackEvent('cart_created', {
'cartId': 'c_123',
'value': 49.0,
});From your backend
For data the app doesn't have (a payment confirmed by a webhook, a CRM change), call the REST API with a REST key. You can enroll into a specific journey:
curl -X POST https://api.yourhost.com/api/sdk/journeys/JOURNEY_ID/trigger \
-H "Authorization: Basic $REST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "externalId": "user-123", "properties": { "plan": "pro" } }'Or fire a server-side event that any matching journey listens for. If the user hasn't been seen yet, they're created on the fly, keyed by external_id:
curl -X POST https://api.yourhost.com/api/sdk/events \
-H "Authorization: Basic $REST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "externalId": "user-123", "name": "payment_succeeded" }'Templates
The fastest way to start is a template — a complete, working draft you can tweak. From Journeys → Start from a template:
| Template | Pattern it shows |
|---|---|
| Welcome series | Message → delay → message → exit. |
| Abandoned cart | Wait-for-event with an event path (purchased) vs a timeout path (remind). |
| Win-back | API entry + wait-for-return with an offer fallback. |
| Post-purchase review | Delays between asks across two channels. |
| Trial expiry nudge | Timed reminder + convert-or-last-chance branch. |
Each opens as a Draft. Edit the copy, durations, and conditions, fix any flagged validation issues, then Activate.
Build → activate
- Add steps from the palette and connect them; set each path's condition.
- Save stores the draft graph.
- Activate validates the graph (one entry, no orphan steps, wait-for-event steps need both an event path and a timeout path), compiles it to the execution graph, and sets the journey live. Pause stops new advancement.
Warning
Note
{{ tag.x }} for profile tags. Entry-event properties ({{ event.x }}) are on the roadmap. Manage audiences under Segments.