Lifecycle
4 endpoints + webhook
create
→
cue
→
decide
→
read
→
close
Multi-stream timeline
5 priority rules · 1/day cap
safety
→
time-bound
→
receptivity
→
enrolled-first
→
template-id
How it works
From patient context to the right message, in one call.
One POST returns the next message, a receptivity read, and the audience-safety metadata behind it.
Two core mechanisms make that one call work: the stream lifecycle is how a stream begins and ends; the multi-stream timeline honors the one-message-per-day cap when a patient is enrolled in more than one stream.
For onboarding details, see /signal/integrate. For audience-safety governance, see /signal/safety. For stream versioning, see /signal/changelog.
Display mode never touches PHI — no BAA required. Start in 5 minutes.
On this page
Stream lifecycle
One stream. One patient. One sequence of cues.
Each stream is its own object. The cue loop is the only ongoing contract — create happens once, the Deliver-mode webhook fires per event, and you read state on demand. A stream closes itself when its curated subset is exhausted or the patient opts out; there is no separate close call. Streams are bound to one template at create-time; switching templates means ending the stream and opening a new one.
Pass a template_id, patient context, and audience tags. The member is enrolled in this one call; the response carries first_cue.
Return feedback for the last message, get next_cue back. Feedback is required before the next cue.
Delivery intelligence picks the action and draws the minute inside the window. In Deliver mode your webhook fires with the decision.
Pull stream state and the current cue any time — idempotent, safe to poll.
The stream ends when the curated subset is exhausted (sandbox_exhausted) or you stop cueing.
Cue again before returning feedback and the API answers 409 feedback_required — feedback is the moat that keeps every stream honest. Browse the curated subset first with GET /v1/signal/sandbox-topics.
What every cue response looks like
Every cue returns three fields: message (the text to render or send), safety (verdict plus the include/exclude tag set that was checked), and receptivity (a 0-to-1 advisory score). Display mode partners use receptivity to pick the moment; Deliver mode partners let Reach use it.
The stream object itself carries day (advances on each cue), total_days (the template's planned arc length, or null for indefinite streams), and last_cued_at. State is durable — interrupting your worker mid-loop does not reset progression.
Multi-stream · conflict resolution
One patient. Three concurrent streams. One message a day.
A patient enrolled in three streams does not get three messages a day. Signal honors a per-patient 1-message-per-day cap across all streams. The picker runs five priority rules to decide which stream wins each day; the others mark the day suppressed (with reason) so your audit trail stays honest.
p_5572 · enrolled in 3 streams
Diabetes · Pharma Init
Day 13 dose check
Day 14 side effects
Day 15 food stack
dropped for safety
Day 17 refill heads-up
Day 18 weekend pacing
Day 19 how it lands
General Wellness
—
—
—
—
—
—
—
Safety push · one-off
—
—
—
Grapefruit interaction
—
—
—
1 message/day cap honored · 7 of 7 days
The five priority rules
These run in order. The first match wins for that day; the rest are suppressed with reason so the audit trail explains every drop.
-
Safety beats everything
On-demand safety pushes (drug interactions, recall notices, urgent clinical advisories) always win the day. Other streams that would have fired today mark the day suppressed with reason="safety_preempt".
-
Time-bound beats indefinite
A stream with total_days set (Pharma Init, Postpartum, Relapse Prevention) outranks an indefinite stream (General Wellness, Cancer Survivorship). The time-bound arc only runs for N days; the indefinite one can catch up later.
-
Higher receptivity wins ties
When two streams share a tier, the one with the higher current-day receptivity score wins. This is the only place receptivity drives a Signal-internal decision; in cue responses it is advisory only.
-
Earlier enrollment wins receptivity ties
If receptivity scores match too, the stream that enrolled earlier wins. Patients in their first week of a new stream are not pulled away by streams they have been in for months.
-
Stream-template ID is the final tiebreak
If all four above tie (rare — usually means two streams of the same template started on the same day), the alphanumerically lower template_id wins. Deterministic; identical inputs always produce the same outcome.
Why the cap exists
More than one message a day from one sender saturates fast. The 1-per-day cap is not a configuration knob; it is a structural commitment. If a buyer needs more than one daily touch on a patient (combined safety + lifestyle, for instance), that is a multi-stream design and the priority rules above resolve it cleanly.