Logs
Send, search and alert on structured events.
Send structured events from your server. Search them in the dashboard or through the API. Logs are included on every plan and count toward your storage quota. They are kept for the retention of your plan (see Plans and limits).
Send events
POST https://upload.basix.media/api/v1/logs, JSON.
curl -X POST https://upload.basix.media/api/v1/logs \
-H "Authorization: Bearer $BASIX_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataset": "economy",
"events": [
{
"level": "warn",
"message": "Suspicious money add",
"player": "license:3f9a2b...",
"resource": "esx_core",
"metadata": { "amount": 999999, "source": "admin" }
}
]
}'Response:
{ "accepted": 1, "used": { "bytes": "2097152" }, "quota": { "bytes": "10737418240" } }Body: { "dataset": "...", "events": [ ... ] }, a bare array of events, or a single event. dataset can also be passed as ?dataset=. Default: default.
| Event field | Type | Notes |
|---|---|---|
message (or body) | string | Required. Up to 8,000 characters. Events without one are skipped. |
level | string | trace, debug, info, warn, error, fatal. Anything else becomes info. |
player | string | Any identifier, up to 120 characters. Builds player profiles. |
resource | string | Up to 120 characters. |
metadata | object | Any JSON, up to 8,000 bytes once serialized. Larger metadata is dropped. |
timestamp | ISO string or ms | Optional. Must be within the last 365 days and not more than 1 day ahead, otherwise the server time is used. |
Limits: 500 events per request, 240 requests per minute per key. Batch your events. A full quota answers 413 QUOTA_EXCEEDED.
Search events
GET /api/v1/logs with any of: dataset (repeatable), level (repeatable), player, resource, search (text in the message), from, to (ISO dates), limit (1-200, default 50), cursor.
curl "https://upload.basix.media/api/v1/logs?dataset=economy&level=warn&level=error&player=license:3f9a2b...&limit=100" \
-H "Authorization: Bearer $BASIX_KEY"{
"events": [
{
"id": "...",
"dataset": "economy",
"level": "warn",
"message": "Suspicious money add",
"resource": "esx_core",
"player": "license:3f9a2b...",
"metadata": { "amount": 999999 },
"timestamp": "2026-10-25T14:00:00.000Z"
}
],
"nextCursor": null
}Categories
A category gives a dataset a label, color, icon, order, group and columns read from metadata. Datasets without a category are listed with "auto": true.
| Method | Path | Scope |
|---|---|---|
| GET | /logs/categories | upload |
| POST | /logs/categories (body includes key) | full |
| GET | /logs/categories/<key> | upload |
| PATCH | /logs/categories/<key> (creates it if missing) | full |
| DELETE | /logs/categories/<key> | full |
Fields: label (1-60 chars), color (#rrggbb), icon (activity, home, files, key, card, user, book, shield, upload, database, link, play, lock, bolt, code, layers, check, sparkle), order (integer), group (up to 40 chars or null), columns (up to 30 of { key, label, type, visible }, type one of text, number, bool, date, player, link; key is a metadata path such as vehicle.plate). Up to 100 categories.
curl -X PATCH https://upload.basix.media/api/v1/logs/categories/economy \
-H "Authorization: Bearer $BASIX_KEY" -H "Content-Type: application/json" \
-d '{ "label": "Economy", "color": "#22c55e", "icon": "card", "group": "Gameplay",
"columns": [ { "key": "amount", "label": "Amount", "type": "number", "visible": true } ] }'Players
Every player value gets a profile: first and last seen, event counts per category, and identifiers found in metadata (license, license2, discord, steam, fivem, xbl, live, rockstar, citizenid).
| Method | Path | Scope |
|---|---|---|
| GET | /logs/players?search=&page=0 | upload |
| GET | /logs/players/<player> | upload |
| PATCH | /logs/players/<player> | upload |
| DELETE | /logs/players/<player> | full |
PATCH accepts displayName, notes (up to 10,000 chars), identifiers and fields (objects, null removes a key, up to 50 each), or a single key + value. URL-encode the player in the path.
curl -X PATCH "https://upload.basix.media/api/v1/logs/players/license%3A3f9a2b" \
-H "Authorization: Bearer $BASIX_KEY" -H "Content-Type: application/json" \
-d '{ "displayName": "John", "identifiers": { "discord": "1234" }, "fields": { "job": "police" } }'Saved views
Stored filters and columns, shown in the dashboard. Full key required.
| Method | Path |
|---|---|
| GET, POST | /logs/views |
| GET, PATCH, DELETE | /logs/views/<id> |
Body: name (required on create), filters (categories, levels, player, resource, text, range one of 15m, 1h, 6h, 24h, 7d, 30d, or from/to), columns (metadata keys). shared defaults to true (visible to the whole team). false makes the view personal to the key's creator.
Alerts
A rule fires when threshold matching events arrive within windowMinutes. It then stays quiet for cooldownMinutes. It posts to a Discord webhook, to your webhook endpoints (event log.alert), or both. Rules are checked after each ingest. Full key required.
| Method | Path |
|---|---|
| GET, POST | /logs/alerts |
| GET, PATCH, DELETE | /logs/alerts/<id> |
| Field | Default | Notes |
|---|---|---|
name | required | 1-80 chars. |
enabled | true | |
conditions | match all | categories, levels, contains (text), metadata (up to 10 { key, equals }). |
threshold | 1 | 1-10,000 events. |
windowMinutes | 5 | 1-1,440. |
cooldownMinutes | 5 | 0-10,080. |
discordWebhookUrl | null | https://discord.com/api/webhooks/<id>/<token>. |
webhookIds | [] | Ids of your webhook endpoints. At least one target is required. |
curl -X POST https://upload.basix.media/api/v1/logs/alerts \
-H "Authorization: Bearer $BASIX_KEY" -H "Content-Type: application/json" \
-d '{
"name": "Money exploit",
"conditions": { "categories": ["economy"], "levels": ["warn", "error"], "contains": "money",
"metadata": [ { "key": "source", "equals": "admin" } ] },
"threshold": 3, "windowMinutes": 5, "cooldownMinutes": 15,
"discordWebhookUrl": "https://discord.com/api/webhooks/123456789/your-webhook-token"
}'The number of rules depends on your plan. Over the limit, creating one answers 403 PLAN_REQUIRED.
Get alerted on Discord
Create an alert rule with discordWebhookUrl (see Alerts). Example: 3 warn or error events in the economy dataset within 5 minutes.
Try it on your own server
Create a free account and your API key is ready in about two minutes. 3 GB included, bandwidth never billed, no card needed.