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.
Import your historical data
Import historical game analytics from GameAnalytics, PlayFab, Firebase, Unity Analytics, or any CSV into PlayGenus, so churn and LTV models train on your real history.