Skip to content

Read your app's event journal

OpenAPI JSON
GET
/events
Code sample: Python
import os, requests, time
cursor, since = None, "2026-09-10T00:00:00Z"
while True:
params = {"cursor": cursor} if cursor else {"since": since, "types": "app_user.*,extension.*", "limit": 100}
r = requests.get(
"https://api.eu.apigami.com/events",
headers={"Authorization": f"Bearer {os.environ['APIGAMI_API_KEY']}"},
params=params,
).json()
for event in r["events"]:
handle(event) # by event["id"], skipping the ones already seen
cursor = r["next"] or cursor
if not r["events"]:
time.sleep(30)

The journal of everything that changed for your app’s users: a user connected or disconnected, their approvals changed, a browser was attached to or detached from them, came online or went offline. Events are kept 30 days, ascending by (created_at, id). Only your app’s own events come back — the key names the app, and there is no parameter to name another one. Use it to catch up after your own deploy, to reconcile a state you doubt, or instead of a webhook endpoint if your service has no public URL. API keys only: a dashboard session, a personal access token or an OAuth token is refused with 401.

since
string format: date-time

An ISO 8601 timestamp. Events strictly after it. Default: 30 days ago. Ignored when cursor is given.

Example
2026-09-10T00:00:00Z
cursor
string

The next of a previous answer: an opaque encoding of (created_at, id). It needs no row to still exist, so a cursor kept across the 30-day purge keeps working. Wins over since.

types
string

Comma-separated list of types or <namespace>.* patterns. An unknown type matches nothing. Omitted: every type.

Example
app_user.*,extension.offline
limit
integer
default: 100 >= 1 <= 1000

How many events at most. Default 100, clamped to 1000.

A page of events, oldest first. next is the cursor of the following page, or null when there is nothing more right now.

Media typeapplication/json
object
events
required
Array<object>
Event

One thing that happened, as your app sees it. The same body is posted to your webhook endpoints. An app_user event carries the user’s whole set of approvals, not the change alone, so a consumer replaces its copy instead of diffing.

object
id
required

Unique to your app. Two apps never share an id, and it is the idempotency key of a delivery.

string format: uuid
type
required

One of the types of GET /events/catalogue.

string
created_at
required

The ordering key, for every type. Compare it, never arrival order.

string format: date-time
app_id
required

Your app.

string format: uuid
user_ref
required

The user the event is about, as POST /connect/token returned it. Null on an event about no user.

string | null
install_ref
required

The browser the event is about. Null on an event about the user as a whole, or about no browser.

string | null
data
required

Depends on the type — see GET /events/catalogue.

object
key
additional properties
any
next
required

Pass it back as cursor. Keep it: it survives the purge.

string | null
Example
{
"events": [
{
"id": "6f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
"type": "app_user.updated",
"created_at": "2026-09-10T10:12:31.128Z",
"app_id": "2b7f6a41-0c9d-4a3e-9f21-8d5c4b3a2109",
"user_ref": "usr_3f9c1a0e7b2d4c58a61e9f0b2d7c4e13",
"install_ref": null,
"data": {
"connected_at": "2026-09-01T08:00:00.000Z",
"grants": [
{
"domain": "acme.com",
"granted": false,
"decided_at": "2026-09-10T10:12:31.128Z"
},
{
"domain": "example.com",
"granted": true,
"decided_at": "2026-09-02T09:30:00.000Z"
}
],
"change": {
"domain": "acme.com",
"decision": "denied",
"was_granted": true
}
}
}
],
"next": "MjAyNi0wOS0xMFQxMDoxMjozMS4xMjhaLzZmMWM"
}

A query parameter could not be read.

Media typeapplication/json
object
error
required
string
consentPending

Present and true when the approval window is open and the user has not answered within 45 s.

boolean
Examples
{
"error": "since must be an ISO timestamp"
}

Missing, malformed or revoked API key — or a credential that is not one: a dashboard session, a personal access token and an OAuth token are refused here, like on /call.

Media typeapplication/json
object
error
required
string
consentPending

Present and true when the approval window is open and the user has not answered within 45 s.

boolean
Example
{
"error": "bad client credentials"
}