Collection Overview
How the SDK detects, categorizes, and delivers analytics data from your Discord bot to the Dicolytics backend.
Three Data Categories
The SDK organizes all collected data into three categories based on the direction of the action and how it is detected:
| Category | What It Captures | Detection Method | Delivery Mode | Dashboard Metric |
|---|---|---|---|---|
| Interactions | User-initiated actions sent to your bot | interactionCreate gateway event | Per-event (immediate) | interactions |
| Actions | Bot-initiated REST API calls to Discord | REST method patching (post, patch, put, delete) | Per-event (immediate) | actions |
| Events | Server activity flowing through the gateway | Gateway event listeners (guildMemberAdd, messageCreate, etc.) | Aggregated (60-second counter flush) | discord_events |
How detection works
- Interactions are detected via a single
interactionCreatelistener. The SDK classifies each interaction by type and measures response latency by patchingreply(),deferReply(),editReply(), andfollowUp()on each interaction instance. - Actions are detected by patching
client.rest.post,.patch,.put, and.deletemethods. Each outbound REST call is matched against a route table to identify the action type. No request payload is ever inspected -- only the route and HTTP method matter. - Events are detected by registering listeners on discord.js client events. Each listener increments a counter, which is flushed every 60 seconds as an aggregated
data.countvalue.
Delivery Flow
Your Bot Process Dicolytics Backend
SDK captures event
|
v
Serialize & enqueue
(UUIDv7 id assigned)
|
v
Queue (max 5,000 events)
|
|-- 50 events pending? -------> Flush
|-- 5 second timer fires? ----> Flush
|
v
HTTP POST /v1/events
(batch: max 500 events / 1 MiB)
|
v
Dicolytics validates & stores
|
v
DatabaseQueue Behavior
| Parameter | Value | Configurable |
|---|---|---|
| Flush trigger (event count) | 50 events | No |
| Flush trigger (timer) | 5 seconds | Yes (flushIntervalMs) |
| Max queued events | 5,000 | No |
| Max events per batch | 500 | No |
| Max batch body size | 1 MiB | No |
Note
When the queue exceeds 5,000 events, the oldest events are dropped first. This protects memory but means data loss under extreme load. If drops occur, the SDK logs a warning and a console.warn is emitted once.
Retry Policy
Failed requests are retried with full-jitter exponential backoff:
| Scenario | Behavior |
|---|---|
| 2xx | Accepted. Batch complete. |
| 400 | Dropped. Bad request, no retry. |
| 401 | Transport permanently disabled. API key rejected. |
| 403 | Retryable. May be transient (CDN/WAF). |
| 429 | Quiet period from Retry-After header (default 300s). Only heartbeat and guild_snapshot keep flowing. |
| 5xx / network error | Jittered exponential backoff, max 5 attempts. |
See Transport & Retries for the full specification.
Python SDK
The Python SDK (dicolytics) sends "name": "dicolytics-discord.py" in the sdk envelope field, with version 0.1.0. The envelope format is otherwise identical to the discord.js SDK.
Additional Data Types
Beyond the three main categories, the SDK also emits:
| Type | Description | Delivery | Stored In |
|---|---|---|---|
heartbeat | Per-shard health snapshot (guild count, ping, memory, CPU, etc.) | Every 60s | bot_snapshots |
guild_snapshot | Per-guild state (member count, online count, name, locale) | Every 60s | guild_snapshots |
command_error | Error during interaction reply lifecycle | Per-event | events |
error | Explicit error report via captureError() or unhandledRejection | Per-event | events |
custom | Developer-defined events via track() | Per-event | events |
api_routes_snapshot | Top 10 REST API routes by call count | Every 5 min | events |
Snapshots and quota
heartbeat and guild_snapshot events are stored in dedicated tables (bot_snapshots and guild_snapshots) and do not count against event quota. They also bypass the 429 quiet period to ensure uptime tracking remains accurate.
Intent Auto-detection
The SDK checks your bot's configured intents at attach time. Gateway event listeners are only registered for events whose required intent is present. For example:
event_member_joinrequiresGuildMembersintentevent_message_createrequiresGuildMessagesintentevent_presence_updaterequiresGuildPresencesintent (privileged)
If an intent is missing, the corresponding listeners are simply not registered -- no error is thrown. Enable debug: true to see which listeners were registered and the detected intent bitfield.
Learn More
- Interactions -- 6 interaction types and their collected fields
- Actions -- 22 REST action types by category
- Events -- 24 gateway event types and required intents
- Metrics & Dimensions -- how data becomes queryable metrics