REST API & event format
The PlayGenus ingestion API — endpoints, authentication, the batch envelope, and the event JSON format shared by every SDK.
Every SDK speaks the same protocol: JSON batches POSTed to the ingestion API. If we don't generate an SDK for your stack yet, you can implement this yourself in an afternoon — it's one endpoint and two JSON shapes.
Your ingestion base URL is included with your API key when we generate your
SDK bundle. Keys look like pgn_live_... for production and pgn_test_...
for testing.
Endpoints
| Endpoint | Method | Max payload | Use case |
|---|---|---|---|
/v1/events | POST | 1 MB | Standard event batches — what the SDKs use |
/v1/events/bulk | POST | 10 MB | Large server-side batches and migrations |
/v1/events/validate | POST | 1 MB | Dry run — checks events against your tracking plan without storing anything |
Authentication: include your API key either in the request body
(api_key field) or as a header:
Authorization: Bearer pgn_live_abc123The payload caps above are the practical limits — batch your events rather than sending them one at a time, and you'll never think about it again.
Batch envelope
{
"api_key": "pgn_live_abc123",
"sdk": "server",
"sdk_version": "0.1.0",
"sent_at": "2026-03-11T13:15:00.000Z",
"events": [
{ "..." : "..." },
{ "..." : "..." }
]
}| Field | Type | Description |
|---|---|---|
api_key | string | Your API key (or use the Authorization header) |
sdk | string | "client" or "server" — the SDKs set this themselves |
sdk_version | string | SDK version; set automatically by generated SDKs |
sent_at | string | ISO 8601 timestamp of when the batch was sent |
events | array | Array of event objects (below) |
Event object
{
"event_name": "progression_complete",
"timestamp": "2026-03-11T13:14:58.123Z",
"player_id": "player-uuid-here",
"properties": {
"level_id": "world1_stage3_level12",
"score": 45200,
"stars": 3,
"duration_seconds": 87,
"attempt_number": 2,
"items_used": ["hammer", "extra_moves"]
}
}| Field | Type | Description |
|---|---|---|
event_name | string | The event name, e.g. "progression_complete" |
timestamp | string | ISO 8601, when the event occurred — not when it was sent. The distinction matters for batched and offline-queued events |
player_id | string | Your unique player identifier |
properties | object | Event-specific properties — schemas in the client and server references |
Client events — device context
Events sent by the Client SDK automatically carry device and app blocks:
{
"event_name": "session_start",
"timestamp": "2026-03-11T13:10:00.000Z",
"player_id": "player-uuid-here",
"device": {
"model": "iPhone 14 Pro",
"os_name": "iOS",
"os_version": "17.2",
"screen_width": 1170,
"screen_height": 2532,
"locale": "en_US",
"timezone": "America/New_York",
"connection_type": "wifi"
},
"app": {
"version": "1.2.3",
"build": "456"
},
"properties": {}
}If you're implementing a client integration over REST, include these blocks where you can — device context feeds the dashboards that break behaviour down by platform, OS, and connectivity.
Validation
POST /v1/events/validate takes the same batch envelope, checks every event
against your tracking plan, and returns per-event errors — wrong types,
missing required properties, unknown event names — without storing a thing.
Use it during development, in CI, or any time you're not sure a payload is
right. There's no cost to being wrong against this endpoint; that's what
it's for.
Tracking best practices
Naming conventions, event-volume hygiene, receipt validation, and the other habits that keep your PlayGenus data trustworthy.
Webhook alerts
Get an HMAC-signed HTTP POST when a critical signal fires in your game — DAU drops, retention slips, or revenue drift — filtered by the signals you care about and a minimum severity.