Once you’ve connected real-time events in Step 1, you can configure the bot to reach out to users before they ask — based on what they’re doing in your product. Everything is driven by yourDocumentation Index
Fetch the complete documentation index at: https://developers.autoplay.ai/llms.txt
Use this file to discover all available pages before exploring further.
products.json config. No code changes are needed.
Step 1 — Configure agent states
Why agent states are needed
Without a state layer, a proactive trigger would fire on every URL change, every background poll — indefinitely. The result is a bot that spams users every time they navigate. Agent states solve this by tracking what mode the session is in right now and enforcing strict rules about when the bot is allowed to speak first. Think of it as a circuit breaker: chips can only fire in one specific state, and after the user ignores them a cooldown blocks re-firing.The three states
SessionState (agent state v2) is a finite state machine that runs alongside every active user session.
Direct
PROACTIVE ↔ REACTIVE transitions are never allowed. The only way to exit either active state is via idle timeout — this is enforced by the FSM, not by your code.THINKING
The bot is watching. It evaluates triggers every few seconds. If a trigger fires and no cooldown is active, chips are delivered to the user.
PROACTIVE
Chips have been shown. The bot is waiting. Any interaction — chat message, chip tap, or tour step — resets the idle timer. Silence for
interaction_timeout_s returns the session to THINKING with a cooldown.REACTIVE
The user opened the chat themselves. The bot responds normally via the RAG pipeline. The same idle timeout applies — silence returns to THINKING.
Why the cooldown matters
After returning toTHINKING from either active state, cooldown_period_s prevents the bot from immediately re-offering. Without it, a user who ignores the chips would be re-prompted on the very next URL change. The cooldown enforces a respectful wait.
Configuration
Both timing values live at the top level ofintegration_config in your products.json:
| Field | Default | Meaning |
|---|---|---|
interaction_timeout_s | 20.0 s | How long the user can go without any interaction (chat, chip tap, or tour step) before the session returns to THINKING. Applies in both PROACTIVE and REACTIVE. |
cooldown_period_s | 60.0 s | After returning to THINKING, how long before a proactive trigger can fire again. Auto-clears once the period elapses. |
Per-tour overrides for both values are possible via the tour registry. If a tour is active and a matching registry entry exists, the tour’s values take precedence over the session defaults above.
Step 2 — Define proactive triggers
There are two separate config keys that work together to make proactive messaging work:proactive_triggers.builtins— the detection side: which built-in rules watch the user’s behaviour and decide when to fire.proactive_intercom— the delivery side: what chips to show the user when a trigger fires.
integration_config. You need both.
Built-in triggers
The SDK ships three ready-to-use detection triggers you can enable with no code:| ID | Fires when | Notes |
|---|---|---|
canonical_url_ping_pong | User bounces between the same URLs | Active by default — no config needed |
user_page_dwell | User lingers on a page with few actions | Tunable via dwell_threshold_seconds |
section_playbook_match | User is in a section that has a playbook entry | Requires section_url_rules + section_playbook |
builtins array to integration_config.proactive_triggers. Each row requires id, name, and description:
Chip delivery (proactive_intercom)
proactive_intercom is where you define the chips shown to the user when any trigger fires. Triggers are defined in integration_config.proactive_intercom as a list — you can have multiple entries for different pages or conditions.
Each trigger has four fields:
| Field | Required | Meaning |
|---|---|---|
id | yes | Stable machine identifier — never change this once deployed |
name | yes | Human-readable label used in logs and dashboards |
proactive_criteria | yes | Detection rule — see criteria types below |
messages | yes | 1–3 chips shown to the user when the trigger fires |
Criteria types
A criterion is either a leaf (a single detection rule) or a group (logical combination of rules). Leaf — a single condition:AND or OR:
Chip messages
Each chip inmessages is shown as a quick-reply option when the trigger fires. Up to 3 chips per trigger.
| Field | Required | Meaning |
|---|---|---|
id | yes | Stable chip identifier — referenced by the tour registry |
label | yes | Text shown on the chip in Intercom |
user_tour_exists | yes | true if tapping this chip can launch a visual guidance tour |
user_tour_id | if user_tour_exists: true | Intercom flow ID for the tour — must match an entry in tour_registry |
Example trigger (no tour)
Example trigger (with a tour chip)
When one chip launches a visual tour, adduser_tour_exists: true and the Intercom flow ID. Other chips in the same trigger can still be tour-less.
Step 3 — Add a user tour (optional)
When a chip launches an Intercom visual guidance tour, the tour registry tells the session how long to keep the user inPROACTIVE while the tour is running — and what cooldown to apply once they finish (or go idle).
Why a separate registry?
The tour registry is kept separate from the trigger config by design. A single tour can be referenced by chips in multiple triggers, and different tours can have completely different timeout behaviours — independent of which trigger originally fired.How it works
When a user confirms a tour:SessionState.active_tour_idis set to theuser_tour_id(the Intercom flow ID).- On every background tick, the session looks up the active tour in the registry using
user_tour_id. - If found,
interaction_timeout_sandcooldown_period_sfrom the registry entry are used instead of the session defaults. - Any tour step (page advance, step complete) calls
record_tour_step()— this resets the idle timer so the tour keeps the session alive even if the user never types in the chat. - When the user goes idle for the tour’s
interaction_timeout_s, the session returns toTHINKINGand starts the tour’scooldown_period_s.
How the lookup works
When a user taps a chip withuser_tour_exists: true, the session reads user_tour_id from that chip and looks for a matching entry in the registry using the same value:
user_tour_id is the only lookup key — it must match the Intercom flow ID exactly. The id field in each registry entry is only for human readability and log correlation; it plays no role in the lookup.
Configuration
Add entries tointegration_config.tour_registry — a flat list, separate from proactive_intercom:
| Field | Required | Default | Meaning |
|---|---|---|---|
id | yes | — | Human-readable label for logs and dashboards — not the lookup key |
user_tour_id | yes | — | The lookup key. Must exactly match the Intercom flow ID set on the chip (messages[].user_tour_id). |
user_tour_name | no | — | Human-readable tour name for logs and dashboards |
interaction_timeout_s | no | session default | How long tour progress (or chat) keeps the session in PROACTIVE before it returns to THINKING. Omit to inherit the session-level value from Step 1. |
cooldown_period_s | no | session default | Cooldown applied after this specific tour ends or times out. Omit to inherit the session-level value from Step 1. |
You only need to set
interaction_timeout_s or cooldown_period_s when this tour requires different timing from the rest of the session. Omitting them falls back to the session-level defaults set in Step 1 (integration_config.interaction_timeout_s / cooldown_period_s).Full example config
This is the completeintegration_config for a product with one trigger and one tour — matching the structure used in production:
Checklist
Set session-level timeouts
Add
interaction_timeout_s and cooldown_period_s to integration_config. Start with the defaults (20.0 / 60.0) and tune from there.Add a trigger to proactive_intercom
Define at least one object in the
proactive_intercom list with an id, name, proactive_criteria, and messages (1–3 chips). Set user_tour_exists: false on any chip that doesn’t launch a tour.Mark tour chips (if applicable)
For any chip that launches an Intercom visual guidance tour, set
user_tour_exists: true and add the Intercom flow ID as user_tour_id.Add the tour to tour_registry (if applicable)
Add a matching entry to the
tour_registry list using the same user_tour_id. Set interaction_timeout_s and cooldown_period_s to control how long the tour keeps the session alive and how long the post-tour cooldown lasts.Back to overview: Intercom tutorial











