/v1. The moment configuration returns inbound URLs; use those addresses as sender destinations.
1. Prepare media and credentials
fileId, filename, and type. Store fileId as WOKU_FILE_ID. Keep the API key and sender secret in server configuration.
2. Create four moments
Save this code asjourney.mjs. It creates a disabled journey and configures two woku-issued token URLs and two moments using sender signatures. Each moment can have a URL even when it usually advances after a delay.
Run node journey.mjs to create and review the draft. The example disables tickets and plans. In a real program, enable each independently with recipients.ticketsEnabled and recipients.plansEnabled. Tickets use ticketEmails; plans use planMembers with company users and admin or assignee roles. The creator stays as a group administrator.
contentMode selects the content source independently of trigger. JavaScript is a function body receiving payload and returning a string. Imports, network and filesystem access are unavailable. A bounded schema validates the payload before resolving content. Paths cannot contain constructor, prototype or __proto__.
A dynamic Woku image must be a public HTTPS URL. If a secondary wait runs without a webhook, the moment uses its static name, variables and media; that is why the example retains toolSpec.fileId. Missing folders are created. Names are optional and fall back to their keys, within folder-name limits.
3. Preview and activate
Append these steps to the same file aftersendMoment. Use an authorized test email address.
200, evaluates JavaScript against the supplied payload, shows composed CSAT/CES/NPS questions where applicable, and never enrolls or sends. Change deliveryMode to exercise another branch. Preview does not verify signatures; send a real event after activation to test them.
New v2 moments default to one initial invitation and one next-day reminder. The example declares this explicitly in sequence. A zero-day wait means one hour. You can change attempts and windows; existing definitions retain their values.
4. Send events with a stable reference
WithSTART_MODE=operator, enroll the case before its confirmations:
START_MODE=webhook, skip enrollment. The Purchase webhook starts the case. All senders use the same order.id; email identifies the contact, while the reference connects that case’s events.
Later events may arrive early and wait for their prerequisite. A webhook advances a timed moment and cancels its wait; a late event does not repeat an instrument already sent. Execution exclusion does not rely only on X-Woku-Event-Id.
These credentials are different. Connection reads return a credential-free URL and readiness, never the stored token or sender secret.
5. First-response entry
This is an alternative to step 4 enrollment. Run the setup withSTART_MODE=response for a fresh journey or use a new case before sending its events. Customer QR/link entry is also available for operator-mode v2 journeys. Reading or preparing the entry does not start it. Do not prepare another entry for a case already running.
dispatchToken; Woku needs identified text or audio feedback. A valid saved response confirms entry once. Preparation stays pending and does not send another invitation for the first instrument.
6. Tracking, retries and stopping
nextCursor appears only when another page exists. Each case retains its version, history and next action. Editing creates a version for future cases and preserves separately stored credentials; running participations use their earlier snapshot.
A cycle completes on the last instrument’s response or 30 days after its first send. Manual enrollment can reuse the key after the prior cycle completes or finishes stopping. Stopping cancels that exact case’s waits and reminders, preserves feedback and other cases, and cannot recall delivery already accepted by a provider.
For management POST operations accepting
X-Woku-Idempotency-Key, use a new key for a new operation and retain its key for retries. Reusing a key with another body replays the original response; using it for a different operation returns 422.
The same contract in MCP and SDKs
In MCP, requestwoku_guide with topic=customer_journeys. create_journey and update_journey accept the same advanced moments but call sequence cadence. Connect them with preview_journey_moment, get_journey_connections, mint_journey_moment_url and set_journey_sender_secret. Credential mutations and stopping require explicit confirmation; writes require mcp:write.
JavaScript and Python SDKs keep /v1, expose generated moment types, and do not activate a journey on creation. See the MCP reference and journey concepts.
Returning from the same QR or link
Keep requestId stable while preparing/retrying the same first tool. If the API returns HTTP 409 with codejourney_entry_closed, a completed/stopped cycle was
identified. For a new cycle without an external reference, prepare again with a
new requestId. Never renew the ID just because of a timeout, network error or an
active-evaluation conflict. An explicit purchase reference continues to identify
that same case and must change for a different purchase.