---
title: "Real-time state for typed decisions | Snowplow Signals"
description: "Your decisions are fast. Your state is a day old. Signals hands the model what this customer has been doing, as JSON or narrative, read in 6ms."
source: https://signals.snowplow.io/lp/decision-state
---

Context for System One models

# A typed decision is only as good as the state you hand it. 

Signals turns the events your app already sends into agentic context: what this customer has been doing, as JSON or a short narrative, read in 6ms.

* **6ms** p50 serve, in-region
* **2** shapes, JSON or narrative
* **Free** tier, no card

## Start free

5M events a month · unlimited attributes · no card 

Work email Continue

A work address, please. We cannot provision on a personal domain.

Or [talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=decision-state).

[ Try it on yourself ↓ ](#live-panel) 

Below is your own visit to this page, computed by Signals as you read.

### Signals, about you 

connecting 

See live events firing as you browse this page on the left; what Signals computed about you on the right, refreshed every few seconds.

Implement this

this page · events 0 writes 

Product Solutions Developers Pricing Start free 

Start free Engineer 

this panel

the rest of the page

nothing sent yet

write 

attribute store · your session no read yet 

reading\_now 

pages\_last\_5\_min 

seconds\_since\_last\_action 

sections\_read 

seconds\_engaged 

pricing\_views 

menus\_explored 

features\_wanted 

cta\_clicks 

arrived\_from 

waiting for the first computed value… 

Your first events are in flight through a real Snowplow pipeline. Attributes appear as the stream computes them, usually within a few seconds.

hand it to your agent one prompt 

Add the Signals MCP server to Claude Code, Cursor or any MCP client, then run this. The agent adds the SDK, defines the attribute and wires the read into your own app.

$ npx plugins add snowplow/skills

> Use the Snowplow MCP server and Signals skill, then help me plan and implement a use case. Make sure everything is tested and works as intended.

Copy the prompt[How to connect the MCP server](https://docs.snowplow.io/docs/llms-support/snowplow-mcp/) 

or 

write it yourself three steps 

01 Track the event once, in your app 

trackPageView(); // browser tracker, already on this page

02 Define the attribute once, in Signals 

Attribute(name="pages_last_5_min", events=["page_view"],
  aggregation="category_count", property="page_urlpath",
  period=timedelta(minutes=5))

03 Read it back every request 

await signals.getServiceAttributes({
  name: "signals_site_session_service",
  attribute_key: "domain_sessionid",
  identifier: "…", // your session id, once set
});

Why the decision is guessing

## The state describes your app. It does not describe your customer. 

Before 

### Route, props, cart, nothing else

The customer's last four minutes are in an event stream your code cannot read from a render.

`state = { route, cart }` 

With Signals 

### Their session, shaped for a model

One call returns what this customer has been doing, as JSON or a narrative.

`getAgenticContext()` 

Result 

### The decision sees the session

The panel, offer or ranking is picked against what is happening right now.

`state = { route, cart, session }` 

What it is worth

## Four decisions that only work on live state. 

Each is a typed question asked on every render. The model does not change the answer. Whether the state describes this visit or last night's does.

### Adaptive generative UI

The page composes itself around the job in hand. Give the model what this customer compared, abandoned and came back to, and it picks the components that fit them, not the average visitor.

`engagement rate · conversion rate` 

### Real-time decisioning

Which offer, flow or message, chosen against what is happening now instead of a segment computed overnight. A rule over the same activity fires the moment the condition is met.

`offer acceptance · revenue per session` 

### In-session ranking

Results and recommendations reorder against three price filter changes and two failed searches in this visit, not what this customer wanted last week.

`click-through · add to cart · search exit rate` 

### Routing and triage

Which flow the customer belongs in, when to escalate, and whether the question needs a frontier model at all. The cheapest decision is the one the live state already answers.

`escalation rate · cost per conversation` 

How it works

## Describe what the model should know. Read it where you decide. 

Nothing extra to instrument. Agentic context is the activity you already collect, as JSON for the state object or a narrative for the prompt.

1. 01 **Collect.** Add a Snowplow SDK to your app and events start flowing in.
2. 02 **Shape.** Choose what belongs in the context, and whether it arrives as JSON or a narrative.
3. 03 **Read.** What the customer just did is in the context <1s later. Your code reads it in 6ms p50 from the Node.js or Python SDK, the REST API or the MCP server.

Signals → your app 6ms p50 

name checkout\_session 

format json or narrative 

events last 30 this session 

started\_at\_ms session start 

prompt ready for the system prompt 

Trigger high\_intent\_stalled delivered to your app 

Questions

## Before you sign up

### Does Signals decide anything?

No. Signals computes what the customer is doing and hands it over. Which panel renders, which offer fires and which flow runs is your model's call, in your code.

### Which model or framework does it work with?

Any of them. One call over the REST API, the Node.js or Python SDK, or the MCP server returns the context as JSON for a state object or as a string for a prompt.

### Why not send the raw event history instead?

Accuracy. TypeSafe's documentation says accuracy falls as state fills with material the question does not need, and to retrieve and filter in code first. Agentic context is that filter, applied before the call.

### Do I need an event stream already?

No. Collection is part of Signals. Add a Snowplow SDK and events start flowing. If you already run Snowplow, Signals reads the pipeline you have.

### Where does it run?

Managed SaaS, or a private deployment in your own AWS or GCP account. Same architecture either way.

### What does the free tier include?

The full product against your own traffic, up to 5 million events a month, with no card and no sales call. You should see an attribute updating in the first session.

## Put the session in your next decision.

Add the SDK, define one context, read it from the code that decides what to render. The panel at the top of this page is that call, running against you.

[Start free](https://signals.snowplow.io/start?lp=decision-state) [Talk to an engineer](https://signals.snowplow.io/start?intent=engineer&lp=decision-state) 

The real engine · no card · no sales call 

Or hand it to your coding agent 

$ `npx plugins add snowplow/skills` Copy Copied 

Then: Add Snowplow Signals to this app. Work out what the customer is doing that would change what we render, define an agentic context for it, then read it as JSON and pass it in as the state the decision runs on.
