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.
GET /api/log
Section titled “GET /api/log”Events after a point, oldest first.
| Parameter | Default | Meaning |
|---|---|---|
since | 0 | Only events with an id above this. |
limit | 300 | How many, at most 1000. |
To page through the log, pass the last id you got as the next since.
GET /api/events
Section titled “GET /api/events”The live stream, as Server-Sent Events. Each event arrives as:
id: 4182event: persona.sentdata: {"id":4182,"at":"2026-10-10T14:32:05Z","kind":"persona.sent","data":{…}}| Parameter | Meaning |
|---|---|
since | First 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.
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.