{"openapi":"3.1.0","info":{"title":"nyx API","version":"1.0.0","description":"Read-only access to what nyx already knows about servers you own: daily statistics, progression leaderboards, ticket analytics, and honeypot counts, over plain JSON.\n\nRate limited to 60 requests a minute and 10,000 a day per key.","contact":{"name":"nyx","url":"https://nyx.cool"},"license":{"name":"CC0-1.0","identifier":"CC0-1.0"}},"servers":[{"url":"https://api.nyx.cool"}],"tags":[{"name":"Servers","description":"The servers a key can reach, and what each one has switched on."},{"name":"Statistics","description":"Daily member, message, and moderation counts."},{"name":"Progression","description":"Leaderboard standings and individual level and XP."},{"name":"Tickets","description":"Support volume, response times, ratings, and the live open queue."},{"name":"Honeypot","description":"Spam-bot trap counts, in total and per trap channel."},{"name":"Diagnostics","description":"What a server has configured incorrectly, as nyx sees it."}],"security":[{"bearerAuth":[]}],"paths":{"/v1/guilds":{"get":{"operationId":"listServers","summary":"List your servers","description":"Servers you own where nyx+ is active. Plugin lists are empty here; fetch a single server to see its plugins.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `guilds:read` scope.","tags":["Servers"],"x-required-scope":"guilds:read","parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guilds":[{"id":"1467281625954914369","name":"Zeta Studio","iconUrl":"https://cdn.discordapp.com/...","memberCount":1284,"premiumActive":true,"enabledPlugins":[]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}":{"get":{"operationId":"getServer","summary":"One server","description":"Summary plus the plugins switched on right now, which decides what else this key can read.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `guilds:read` scope.","tags":["Servers"],"x-required-scope":"guilds:read","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guild":{"id":"1467281625954914369","name":"Zeta Studio","iconUrl":"https://cdn.discordapp.com/...","memberCount":1284,"premiumActive":true,"enabledPlugins":["tickets","progression"]}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/stats":{"get":{"operationId":"dailyStatistics","summary":"Daily statistics","description":"Daily counts: joins, leaves, kicks, bans, timeouts, boosts, messages created, deleted and edited, voice joins.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `stats:read` scope.","tags":["Statistics"],"x-required-scope":"stats:read","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}},{"name":"metric","in":"query","required":false,"description":"optional; one metric key instead of all of them","schema":{"type":"string"}},{"name":"from","in":"query","required":false,"description":"ISO date, default 30 days ago","schema":{"type":"string"}},{"name":"to","in":"query","required":false,"description":"ISO date, default today, range capped at 365 days","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","from":"2026-07-19","to":"2026-08-19","series":[{"metric":"member_joins","total":312,"daily":[{"day":"2026-08-18","count":14}]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/progression/leaderboard":{"get":{"operationId":"leaderboard","summary":"Progression leaderboard","description":"Ranked members with level and XP. This is the endpoint for \"most active members\" on your own site.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `progression:read` scope. The progression plugin must be enabled on the server.","tags":["Progression"],"x-required-scope":"progression:read","x-required-plugin":"progression","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}},{"name":"limit","in":"query","required":false,"description":"page size, capped at 100","schema":{"type":"integer","minimum":0}},{"name":"offset","in":"query","required":false,"description":"ranked position to start from","schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","total":412,"limit":10,"offset":0,"members":[{"userId":"263304948291207170","rank":1,"level":42,"xp":180,"totalXp":96400}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/PluginDisabled"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/progression/members/{userId}":{"get":{"operationId":"memberProgression","summary":"One member's progression","description":"Level, XP and rank for one member of your server. 404 if they hold no progression there.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `progression:read` scope. The progression plugin must be enabled on the server.","tags":["Progression"],"x-required-scope":"progression:read","x-required-plugin":"progression","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}},{"name":"userId","in":"path","required":true,"description":"Discord user id.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","member":{"userId":"263304948291207170","rank":1,"level":42,"xp":180,"totalXp":96400}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/PluginDisabled"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/tickets/analytics":{"get":{"operationId":"ticketAnalytics","summary":"Ticket analytics","description":"The same analytics payload the dashboard renders. Volumes, close times, first-response times, and close-time ratings, over the last 30 days. `totalClosedTickets` is all time.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `tickets:read` scope. The tickets plugin must be enabled on the server.","tags":["Tickets"],"x-required-scope":"tickets:read","x-required-plugin":"tickets","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","premiumActive":true,"windowDays":30,"summary":{"totalClosedTickets":412,"windowOpenedTickets":96,"windowClosedTickets":91,"ticketsWithFirstResponse":88,"averageFirstResponseSeconds":364,"averageMessagesPerTicket":14.2,"ratingCount":63,"averageRating":4.6},"ratingDistribution":{"1":1,"2":2,"3":6,"4":18,"5":36},"topCategories":[{"categoryId":"billing","categoryName":"Billing","ticketCount":34,"share":0.37}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/PluginDisabled"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/tickets/queue":{"get":{"operationId":"ticketQueue","summary":"Open ticket queue","description":"Every open ticket right now: who opened it, who claimed it, how old it is, and which ones are overdue. The live view for an external support dashboard.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `tickets:read` scope. The tickets plugin must be enabled on the server.","tags":["Tickets"],"x-required-scope":"tickets:read","x-required-plugin":"tickets","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","summary":{"totalOpen":4,"unclaimed":1,"responseOverdue":0,"inactivityWarningDue":1,"autoCloseDue":0},"queue":[{"channelId":"1500847305706836070","channelName":"ticket-0042","categoryId":"general_support","categoryName":"General support","openerId":"263304948291207170","claimerId":null,"status":"open","createdAt":1787160000,"lastActivityAt":1787163000,"ageSeconds":4448}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/PluginDisabled"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/honeypot/stats":{"get":{"operationId":"honeypotStats","summary":"Honeypot catches","description":"How many spam bots the honeypot has removed, in total and per trap channel. A satisfying number to put on a wall.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `honeypot:read` scope. The honeypot plugin must be enabled on the server.","tags":["Honeypot"],"x-required-scope":"honeypot:read","x-required-plugin":"honeypot","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","totalModerated":212,"perChannel":{"1500847305706836070":148,"1486015573702869174":64}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/PluginDisabled"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/guilds/{guildId}/diagnostics":{"get":{"operationId":"diagnostics","summary":"Setup diagnostics","description":"Per-plugin configuration health: missing channels, broken permissions, incomplete setup. Poll it to catch a misconfigured server before your members do.\n\nThe key must belong to the server owner, and nyx+ must be active on the server. Requires the `diagnostics:read` scope.","tags":["Diagnostics"],"x-required-scope":"diagnostics:read","parameters":[{"name":"guildId","in":"path","required":true,"description":"Discord server id. Must be a server you own with nyx+ active.","schema":{"type":"string","pattern":"^\\d{17,20}$"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"example":{"guildId":"1467281625954914369","summary":{"totalIssues":1,"warningCount":1,"errorCount":0,"affectedPluginCount":1},"plugins":[{"plugin":"logging","status":"warning","issues":[{"code":"logging.channel_missing","severity":"warning","message":"Members module has no log channel configured."}]}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/SubscriptionInactive"},"403":{"$ref":"#/components/responses/ForbiddenScope"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An API key created from your nyx profile page, sent as `Authorization: Bearer nyx_live_...`. The `x-api-key` header is accepted too.\n\nEach key carries the scopes chosen when it was created:\n- `guilds:read`: List your servers and read one server, including its plugin list.\n- `stats:read`: Daily member, message, and moderation counts.\n- `progression:read`: Leaderboard standings and a single member's level and XP.\n- `tickets:read`: Ticket analytics and the live open ticket queue.\n- `honeypot:read`: Honeypot catch counts, in total and per trap channel.\n- `diagnostics:read`: The setup diagnostics report for a server."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}},"responses":{"Unauthorized":{"description":"The key is missing, malformed, or revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"UNAUTHORIZED","message":"Invalid or revoked API key"}}}}},"ForbiddenScope":{"description":"The key is valid but lacks the scope, or was not granted this server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"FORBIDDEN_SCOPE","message":"This key was not granted the stats:read scope"}}}}},"SubscriptionInactive":{"description":"nyx+ is not active on the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"SUBSCRIPTION_INACTIVE","message":"nyx+ is not active on this server"}}}}},"NotFound":{"description":"No such server, or it is not one the key owner owns. Both answer the same way so a caller cannot probe for servers that are not theirs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"NOT_FOUND","message":"Guild not found"}}}}},"PluginDisabled":{"description":"The plugin behind this endpoint is switched off on the server.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"PLUGIN_DISABLED","message":"The tickets plugin is not enabled on this server"}}}}},"RateLimited":{"description":"Rate limit exceeded. `retry-after` gives the seconds to wait.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"RATE_LIMITED","message":"Rate limit exceeded"}}}}},"UpstreamUnavailable":{"description":"nyx could not be reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"UPSTREAM_UNAVAILABLE","message":"Unable to reach nyx right now"}}}}}}}}