Build a welcome journey
Start a journey when someone signs up, wait, check what they did, nudge them, and stop when they reach the goal.
A journey reacts to what each person does. This one starts at sign-up, waits a day, and sends a nudge only to people who have not connected yet. It ends early when the person sends their first campaign.
What you need first
Your app sending
Signed upandSent first campaignevents (see Track events).An email template for the nudge and a connection to send it through.
A key with
workflows:writeandevents:write.
1. Create the journey
curl -s -X POST "$BASE/v1/workflows" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: wf-welcome-1" \
-d '{"name":"Welcome: sign-up to first campaign","purpose":"marketing","mode":"journey",
"definition":{
"triggers":[{"type":"event","name":"Signed up","reentry":{"mode":"once"}}],
"settings":{"purpose":"marketing","timezoneSource":"profile","timezone":"America/New_York",
"goal":{"kind":"event","eventName":"Sent first campaign","windowDays":14,"onReach":"exit"}},
"graph":{"start":"wait_1d","nodes":[
{"id":"wait_1d","type":"delay","config":{"duration":{"amount":1,"unit":"days"}}},
{"id":"connected","type":"if_else","config":{"condition":{"kind":"field","field":"attributes.provider_connected","op":"eq","value":true}}},
{"id":"done","type":"exit","config":{"reason":"provider_connected"}},
{"id":"nudge","type":"send_email","config":{"templateId":"<templateId>","route":{"connectionId":"<connectionId>"}}},
{"id":"end","type":"end","config":{}}],
"edges":[
{"id":"e0","source":"wait_1d","sourceHandle":"next","target":"connected"},
{"id":"e1","source":"connected","sourceHandle":"yes","target":"done"},
{"id":"e2","source":"connected","sourceHandle":"no","target":"nudge"},
{"id":"e3","source":"nudge","sourceHandle":"next","target":"end"}]}}}'Give every send step a route. A send step without one fails the enrollment, with "No route" as its lastError.
To add an SMS fallback, branch on consent first: an if_else node with {"kind":"consent","channel":"sms","purpose":"marketing"}, then a send_sms node on its yes edge.
2. Validate and dry-run
curl -s "$BASE/v1/workflows/<workflowId>/validate" -H "Authorization: Bearer $HERMETICA_API_KEY"
curl -s -X POST "$BASE/v1/workflows/<workflowId>/simulate" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"start":"2026-11-03T14:00:00Z","until":"2026-11-10T14:00:00Z",
"profiles":[{"id":"p1","fields":{"attributes":{"provider_connected":false}},"consents":["email:marketing"]}]}'The simulation shows each step a sample person would take. Nothing is sent.
3. Optional: a holdout
curl -s -X POST "$BASE/v1/holdouts" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Welcome holdout (10%)","percent":10,"scopeType":"workflow","scopeId":"<workflowId>"}'Held-out people go through the journey for measurement but get no marketing message. Compare their goal rate with everyone else's.
4. Publish
curl -s -X POST "$BASE/v1/workflows/<workflowId>/publish" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" -d '{}'After later edits, check GET /v1/workflows/<id>/publish-impact, then publish with {"inFlight":"stay"} to keep people where they are. Pause with POST .../pause.
5. Feed it and watch
curl -s -X POST "$BASE/v1/events" \
-H "Authorization: Bearer $HERMETICA_API_KEY" -H "Content-Type: application/json" \
-d '{"name":"Signed up","profile":{"email":"ada@example.com"},"dedupeKey":"signup-ada"}'GET /v1/workflows/<id>/enrollmentslists who is in it.GET /v1/workflows/<id>/enrollments/<enrollmentId>/stepsshows one person's path.GET /v1/workflows/<id>/reportand/goalsshow results.
When Sent first campaign arrives, that person leaves with goal_reached. Every send step still checks consent and suppression first.
Next: Consent and suppression.