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, the minute to send it, 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.
Send-time intelligence picks the action and the minute. 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.