Sending events
What your server must include in each event so the Logs ingest API accepts it.
Sending events
The ingest API is forgiving but not infinitely so. Each event must include three fields. The rest are optional but recommended.
The minimum required
Every event POSTed to /v1/logs must include:
| Field | Type | Notes |
|---|---|---|
dataset | string | Lowercase letters, digits, hyphens, underscores. Max 64 characters. Matches ^[a-z0-9_-]{1,64}$. |
message | string | Human-readable summary line. This is what shows up in the result row's message column. |
severity | string | One of trace, debug, info, warn, error, fatal. Defaults to info if you omit it. |
If dataset or message are missing, the API returns a 400 error (dataset_required or message_required) and the event is not stored. Severity is the one field with a default.
A minimal valid event
{
"dataset": "player-actions",
"severity": "info",
"event": "player_connected",
"message": "CharlesSmith connected from 76.40.12.5",
"actor": "player:CharlesSmith",
"source": "fivem-redm:server",
"payload": {
"player": "CharlesSmith",
"steam_id": "76561198012345678",
"ip": "76.40.12.5",
"region": "EU-W"
}
}Highly recommended fields
These are not strictly required, but every Logs feature works better when they are present.
| Field | Why it matters |
|---|---|
event | The short identifier like player_connected or chat_rate_limit_hit. Drives the Top events facet and the click-to-filter behaviour. |
actor | Who or what produced the event. The player:<name> form unlocks the actor profile page. |
source | Which resource emitted the event (e.g., fivem-redm:server, chat-bridge). Drives the SOURCE facet. |
ts | The wall-clock moment the event happened. Defaults to ingest time if omitted; set it explicitly when your server's clock and the API receive time can drift apart. See Timestamp formats. |
Payload conventions
payload is a free-form object. Stick to flat key-value shapes where possible: each payload entry becomes one filterable field in SOQL as payload.<key>.
Common payload keys we see across customers:
player,player_id,steam_id,discord_idfor identityip,regionfor networkweapon,vehicle,itemfor game objectserror,stackfor failures
You do not need to register payload keys anywhere. They appear automatically in the dataset schema view after a few events carry them.
What is rejected
The API rejects events for these reasons (returns 4xx):
- Missing
dataset - Missing
message - Invalid
dataset(does not match the regex) - Event payload too large (per-event cap 64 KiB)
- Batch too large (max 1000 events per POST, 4 MiB total)
- Unknown / unparseable
ts(see Timestamp formats)
Batching
You can POST a single event as {...} or a batch as [{...}, {...}, ...]. Batching is encouraged: it reduces the per-event ingest cost (in your monthly request budget) and keeps your server's network usage tidy.
The cap is 1000 events per request. For very busy servers, batch every 100ms or every 100 events, whichever comes first.
Idempotency
If you retry an event on a network blip and the original actually landed, you would create a duplicate by default. To avoid this, set an Idempotency-Key header on the POST. Events with the same key within 24 hours are deduped server-side. See the API reference for the exact behaviour.