Pull events
curl --request GET \
--url https://api.inboxbase.ai/v1/identities/{handle}/events \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.inboxbase.ai/v1/identities/{handle}/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.inboxbase.ai/v1/identities/{handle}/events"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"identity": "<string>",
"events": [
{
"seq": 123,
"id": "<string>",
"type": "email.sent",
"ts": 123,
"data": {},
"convId": "<string>",
"tsIso": "2023-11-07T05:31:56Z"
}
],
"cursor": 123,
"hasMore": true
}{
"error": "<string>",
"details": {}
}{
"error": "<string>",
"details": {}
}Endpoints
Events stream
Cursor-based stream of every customer-observable event on an identity. Long-poll up to 25 seconds.
GET
/
v1
/
identities
/
{handle}
/
events
Pull events
curl --request GET \
--url https://api.inboxbase.ai/v1/identities/{handle}/events \
--header 'Authorization: Bearer <token>'const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.inboxbase.ai/v1/identities/{handle}/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.inboxbase.ai/v1/identities/{handle}/events"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text){
"identity": "<string>",
"events": [
{
"seq": 123,
"id": "<string>",
"type": "email.sent",
"ts": 123,
"data": {},
"convId": "<string>",
"tsIso": "2023-11-07T05:31:56Z"
}
],
"cursor": 123,
"hasMore": true
}{
"error": "<string>",
"details": {}
}{
"error": "<string>",
"details": {}
}Same data as the webhooks stream, served pull-mode for environments
that can’t expose a public URL — agents, MCP servers, dev environments
behind a firewall. Each event carries the same
The same event is never returned twice on the same connection.
When
If your
See Reacting to replies for the full
push/pull pattern.
seq and id as the
matching webhook delivery, so you can mix push and pull and dedup
trivially.
The cursor
seq is a monotonic per-identity integer. It strictly increases and is
never reused. Pass cursor from the response back as since on the
next call:
let cursor = 0;
while (running) {
const r = await fetch(
`https://api.inboxbase.ai/v1/identities/${handle}/events?since=${cursor}&timeoutMs=25000`,
{ headers: { Authorization: `Bearer ${KEY}` } },
).then((r) => r.json());
for (const ev of r.events) await handle(ev);
cursor = r.cursor;
}
Long-poll
timeoutMs is the long-poll window, capped at 25 seconds. With
long-poll on, the call returns as soon as a new event lands; if
nothing arrives within the window, you get an empty response and you
call again immediately.
The loop above doesn’t busy-wait — the long-poll absorbs idle time.
When hasMore: true
If your limit was smaller than the number of events available beyond
your since cursor, hasMore is true on the response. Loop without
long-polling until hasMore: false, then resume long-polling from there.
Recovery from missed webhooks
If you also use webhooks and your receiver was down, this endpoint is how you backfill. Walk from the lastseq you persisted; both delivery
modes share the cursor.
let cursor = await db.getLastWebhookSeq(handle);
for (;;) {
const r = await fetch(
`https://api.inboxbase.ai/v1/identities/${handle}/events?since=${cursor}&limit=200`,
{ headers: { Authorization: `Bearer ${KEY}` } },
).then((r) => r.json());
for (const ev of r.events) await handle(ev);
cursor = r.cursor;
if (!r.hasMore) break;
}
await db.setLastWebhookSeq(handle, cursor);
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Identity handle, URL-encoded.
Example:
"alice.acme@inboxbase.ai"
Query Parameters
Cursor. Returns events with seq > since. Default 0 walks the whole log.
CSV of event types to filter on.
Example:
"email.replied,email.no_reply"
Maximum events per response, 1..200.
Required range:
1 <= x <= 200Long-poll window. Hold the connection up to this many milliseconds for new events when the response would otherwise be empty. Capped at 25,000.
Required range:
0 <= x <= 25000