Skip to content

Events and stream

Everything that happens in a universe is recorded as an event: mail delivered, a reply planned, a link clicked, a login failed. The same events drive the dashboard’s Activity view and webhooks, which lists every type.

An event:

{
"id": 4182,
"at": "2026-10-10T14:32:05Z",
"kind": "persona.sent",
"data": { "persona": "Dana Reyes", "persona_id": "p_3fa2b1c9d0", "kind": "reply", "subject": "Re: Your house on Clark Street", "…": "…" }
}

id grows with each event. at is simulated time.

Events after a point, oldest first.

ParameterDefaultMeaning
since0Only events with an id above this.
limit300How many, at most 1000.

To page through the log, pass the last id you got as the next since.

The live stream, as Server-Sent Events. Each event arrives as:

id: 4182
event: persona.sent
data: {"id":4182,"at":"2026-10-10T14:32:05Z","kind":"persona.sent","data":{…}}
ParameterMeaning
sinceFirst send up to 500 earlier events with an id above this, then carry on live.

A comment line, : ping, comes every 20 seconds to keep the connection open.

Terminal window
curl -N -s "https://c1.simmail.dev/api/events" -H "Authorization: Bearer smk_your_key"

In a browser, EventSource cannot set headers, so pass the key as ?token=:

const es = new EventSource(`https://c1.simmail.dev/api/events?token=${key}`);
es.addEventListener("persona.sent", e => console.log(JSON.parse(e.data)));

Only do that with a key you are happy to expose to that page, such as a viewer key.