Send your own scores
A streaming input is a per-user value that arrives already worked out, such as a churn score, an engagement band or
a count over a time window. Your server sends a batch of them for one site, and EdgeKit stores the latest value for
each user on that site. A profile field reads it, and so does a Paywall rule, as streaming.<pipeline>.<field>.
Both read it at Computed trust.
A pipeline names one stream of values. Each pipeline has a source: EdgeKit’s own analytics, or your organization. This page covers pipelines whose source is your organization.
1. Have the pipeline declared
Section titled “1. Have the pipeline declared”EdgeKit staff declare pipelines. Ask EdgeKit to declare yours with your organization as its source, and give each
field a name and a type: string, integer, number or boolean. Pipeline and field names are lowercase letters,
digits and underscores, starting with a letter. user_id, site_id and window_end are on every row already and
cannot be declared.
The declaration is part of your draft, so it reaches requests after the next deploy, and that deploy rebuilds every profile. The Streaming tab of Identity › Audience › Profile shows each declared pipeline, its source and its fields, read-only.
2. Issue a key with streaming:write
Section titled “2. Issue a key with streaming:write”- Open the site from Delivery › Delivery › Sites and go to API keys.
- Select Can send streaming scores (streaming:write) and issue the key. See Issue and revoke API keys.
The values are written for the key’s site. To send values for two sites, issue a key on each. Keep the key on your server; this route is never called from a page.
3. Send a batch
Section titled “3. Send a batch”POST /v1/streaming/<pipeline> on your tenant host takes up to 1000 rows. Each row carries:
user_id: the user’s EdgeKit user id.window_end: the end of the window the values describe, as an ISO-8601 UTC timestamp or epoch milliseconds.- The pipeline’s declared fields. A field you leave out keeps its stored value,
nullclears it, and an undeclared field is ignored.
A site_id in a row is ignored: the site is always the key’s.
curl -X POST https://your-tenant-host/v1/streaming/churn_model \ -H 'Authorization: Bearer ek_your_key' \ -H 'Content-Type: application/json' \ -d '{"rows": [{"user_id": "01928c4e-7d3a-7b2e-9f10-3c5d2a1b0e9f", "window_end": "2026-10-17T00:00:00Z", "churn": 0.42}]}'const response = await fetch( 'https://your-tenant-host/v1/streaming/churn_model', { method: 'POST', headers: { Authorization: `Bearer ${process.env.EDGEKIT_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ rows: [ { user_id: '01928c4e-7d3a-7b2e-9f10-3c5d2a1b0e9f', window_end: '2026-10-17T00:00:00Z', churn: 0.42, }, ], }), },);
const { received, rejected } = await response.json();200 means the batch was read. received counts the rows that landed, and rejected counts the rest by reason.
The counts add up to the batch size.
| Reason | The row |
|---|---|
missing_user_id |
has no user_id. |
missing_window_end |
has no window_end, or one that is not a timestamp. |
unknown_site |
was sent with a key whose site is not in your newest deployment. |
unknown_user |
names no user in your organization. |
erased |
names an erased user. Values for an erased user are never stored. |
stale |
wrote no field: each one it carries is older than the stored value, or none is declared. |
type_mismatch |
carries a value of the wrong type for its field. |
Accept a reason not in this list: new ones can be added.
The request is safe to retry. A row sent again with the same window_end writes the same values again, and a row
older than the stored values is stale, never written over them.
Each landed row rebuilds that user’s profile on that site. The Streaming tab’s Activity shows when each field last received a value, and refused deliveries counted by reason.
Errors
Section titled “Errors”| Status | Code | When |
|---|---|---|
400 |
bad_request |
The body is not valid JSON. |
401 |
unauthorized |
The key is missing, unknown, revoked or expired. |
403 |
forbidden |
The key does not hold streaming:write, or the pipeline’s source is not your organization. |
404 |
not_found |
No pipeline of that name is in your newest deployment. |
413 |
payload_too_large |
The batch has more than 1000 rows. |
422 |
unprocessable_entity |
The body is not { "rows": [...] }. |
See the operation reference.
Read the value
Section titled “Read the value”- In a profile field,
streaming.<pipeline>.<field>is listed on Available data. See Define a profile field. - In a Paywall rule, a condition can read
streaming.<pipeline>.<field>directly. The value is the last one written. For a signed-in user with no value yet, the condition that reads it does not hold, and nothing errors.