Log endpoints
| Method | Path | Action |
|---|---|---|
| GET | /api/v1/logs | Paginated accessible logs within the owner’s history window |
| POST | /api/v1/logs | Upload .ljson files using multipart form data |
| GET | /api/v1/logs/{sid} | Read log metadata |
| PUT | /api/v1/logs/{sid} | Replace notes on a log whose instance you own |
| DELETE | /api/v1/logs/{sid} | Archive a log whose instance you own |
| GET | /api/v1/logs/{sid}/status | Read processing status, processor progress and recent errors |
| GET | /api/v1/logs/{sid}/events | Read event summaries with cursor pagination |
| GET | /api/v1/logs/{sid}/events/{event} | Read an event’s full payload when available |
| GET | /api/v1/logs/{sid}/download | Download the original newline-delimited JSON |
The log list accepts page, per_page, instance and search. Search matches the original filename or notes. An instance filter uses the instance’s public SID. These query parameters apply to the log list; events use the separate cursor parameters described below.
Upload log files
Uploading requires a Read and write token and an instance owner, editor or admin role. Use multipart form data; curl sets the boundary for you.
| Field | Rules |
|---|---|
instance | Required: public SID of a writable instance. |
files[] | Required: 1–10 files with the .ljson extension. File size, storage, upload-count and ingestion limits follow the instance owner’s plan and server configuration. |
notes | Optional string up to 1,000 characters, applied to newly accepted log files. |
persistence_scope | Optional opaque ID returned by that instance’s persistence-scopes endpoint. Omit to use its latest open scope. Numeric persistence_scope_id is not accepted. |
curl --request POST "https://dzloggy.com/api/v1/logs" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json" \
--form "instance=INSTANCE_SID" \
--form "files[]=@/path/to/session.ljson" \
--form "notes=Evening session"
{
"data": [
{
"sid": "01K7S8T9V0W1X2Y3Z4A5B6C7DA",
"status_url": "https://dzloggy.com/api/v1/logs/01K7S8T9V0W1X2Y3Z4A5B6C7DA/status"
}
],
"errors": []
}
Repeat files[] to send more files. Follow each returned status_url. Identical content may reuse an existing log. A multi-file request can accept some files before reaching a plan limit: even with 202, inspect errors and the accepted SIDs before retrying the remaining files.
Read a log and monitor processing
{
"data": {
"sid": "01K7S8T9V0W1X2Y3Z4A5B6C7DA",
"instance": "01K7S8T9V0W1X2Y3Z4A5B6C7D8",
"persistence_scope": "o1_SCOPE_TOKEN",
"filename": "session.ljson",
"source_type": "upload",
"notes": "Evening session",
"received_bytes": 1024,
"indexed_events": 0,
"rejected_lines": 0,
"duplicate_events": 0,
"conflict_events": 0,
"indexing_status": "pending",
"enrichment_status": "pending",
"completed_at": null,
"created_at": "2026-10-15 00:00:00.000",
"updated_at": "2026-10-15 00:00:00.000"
}
}
The scope token above is abbreviated. The /status endpoint additionally returns processors, with processor, state and batch counts, and up to 20 recent processing errors. It also includes received-byte and event counters, indexing_status, enrichment_status and completed_at.
curl "https://dzloggy.com/api/v1/logs/LOG_SID/status" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json"
Surface indexing makes event summaries available first; enrichment supplies full event details later. Check both status fields and the reported errors before treating processing as complete. Poll at a modest interval within the shared account rate limit.
Read events with cursors
Event summaries use cursor pagination rather than page and per_page. They return data and next_cursor, without a total count. Summaries are ordered by event record ID, oldest first.
| Parameter | Rules |
|---|---|
limit | Integer from 1 to 100; default 100. |
cursor | Optional opaque next_cursor returned by a previous request for this same log. Numeric after parameters are not accepted. |
curl "https://dzloggy.com/api/v1/logs/LOG_SID/events?limit=50" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json"
{
"data": [
{
"id": "o1_EVENT_TOKEN",
"session": "o1_SESSION_TOKEN",
"sequence": 1,
"event": "CUSTOM",
"subname": "",
"occurred_at": "2026-10-15 00:00:00.000",
"actor_sid": null,
"position_x": null,
"position_y": null,
"position_z": null,
"detail_version": 0
}
],
"next_cursor": "o1_CURSOR_TOKEN"
}
curl --get "https://dzloggy.com/api/v1/logs/LOG_SID/events" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json" \
--data-urlencode "limit=50" \
--data-urlencode "cursor=NEXT_CURSOR_FROM_PREVIOUS_RESPONSE"
Every non-empty page returns a next_cursor, including the last page containing events. Request that cursor once more to receive an empty data array and next_cursor: null. Keep the most recent non-null cursor if you want to check for newly indexed events later. A cursor from another log returns 422.
Query events across an instance
GET /api/v1/instances/{sid}/events returns events across accessible, unarchived logs within the owner’s searchable history. Use /api/v1/logs/{sid}/admin-log-events for a single log. Compatibility aliases are /api/v1/instances/{sid}/admin-log-events and /api/v1/log-files/{sid}/admin-log-events.
Filters: event, sub_event, player_steam_id (the event actor), log_file_sid, date_from and date_to. Dates accept ISO timestamps with offsets; timestamps without an offset are interpreted as UTC. Date bounds are inclusive. Use order_dir=asc or desc and order_by=event_timestamp. Page pagination defaults to 50 records; Plus is capped at 50 and Pro at 500 using per_page. Invalid filters return 422.
Responses contain data, links and meta. Each event includes an opaque id, log_file_sid, sequence, event_timestamp (also timestamp) in UTC, event, sub_event, log_file, player, item and position summaries, and details_available. Set include_payload=true (or 1) to include stored event JSON. Payload is otherwise null and can also be null while enrichment is pending. Events shared by multiple visible logs appear once. Player identifiers use public SIDs instead of legacy database IDs.
curl --get "https://dzloggy.com/api/v1/instances/INSTANCE_SID/events" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json" \
--data-urlencode "event=PLAYER_MANAGEMENT" \
--data-urlencode "sub_event=connect" \
--data-urlencode "order_dir=desc"
Fetch full event details
Use the id from a returned event summary as the event path parameter. The ID must belong to an event in this log. A summary’s session token and next_cursor cannot be used as an event ID.
curl "https://dzloggy.com/api/v1/logs/LOG_SID/events/EVENT_ID_FROM_LIST" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json"
{
"data": {
"id": "o1_EVENT_TOKEN",
"detail_version": 0,
"payload": null
}
}
When details are available, the same endpoint returns 200 with the stored event JSON in payload. Its fields depend on the event type and log schema. If a payload stays null, inspect the log’s processing status and errors.
Update notes, download or archive
curl --request PUT "https://dzloggy.com/api/v1/logs/LOG_SID" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data '{"notes":"Reviewed by the moderation team"}'
Notes allow up to 1,000 characters. Omission or null clears them. A processed log cannot be moved to another instance; upload the original file to the correct instance instead.
curl "https://dzloggy.com/api/v1/logs/LOG_SID/download" \
--header "Authorization: Bearer YOUR_TOKEN" \
--output session.ljson
Downloads contain newline-delimited JSON, not a JSON data envelope. When rolling cleanup has removed older segments, the retained portion is returned with X-Raw-Log-Partial: true and a .retained.ljson filename. If no raw segments remain, or a retained file is missing, the response is 410. Reads, event access, status and downloads respect the instance owner’s searchable history window.
curl --request DELETE "https://dzloggy.com/api/v1/logs/LOG_SID" \
--header "Authorization: Bearer YOUR_TOKEN" \
--header "Accept: application/json"
Owners can update notes or archive logs even after they leave the searchable history window. Archiving hides a log without immediately deleting raw storage or processed evidence; archived raw bytes continue to count toward storage until purged.
Connecting a DayZ server
The user API above works with your account token. Detailed Logs streaming uses an instance ingestion key and the /api/v1/instances/{instance}/logs endpoint, with its own ingestion protocol. The two credential types are not interchangeable.
For server streaming, configure the instance’s live-streaming settings and copy its ApiConfig.json from API setup. Keys already on your servers keep working. DZLoggy generates new keys; the user API does not accept one you supply. See ingestion keys for creating and replacing them. The instance owner must have an active Plus or Pro plan for ingestion keys to read or write. The setup guide walks through the mod configuration. User API file uploads through POST /api/v1/logs require your own active Plus or Pro plan and remain subject to the instance owner’s limits.
Each ingestion key may send up to 6,000 requests per minute across all ingestion endpoints. After repeated failed key attempts from one IP address, such as a server still using a revoked key, further failed attempts from that address get 429 instead of 401 for up to a minute. Requests with a valid key from the same address are not affected. Both limits return 429 with a Retry-After header.
Open the server setup guide