DAPI
Dashboard & Developer API
Programmatic access to your NitsuBot server configuration, member data, and analytics. Build integrations, automate workflows, and extend your Discord server.
Authentication
All DAPI requests require an API key passed as a Bearer token in the Authorization header.
Keys have to be requested from the NitsuBot Dashboard under Studio → Request a Custom Module. Fill out the form saying you are requesting a DAPI key.
🔐 Read Keys
Can only access all GET endpoints. Useful for read-only integrations, dashboards, or monitoring tools.
✏️ Write Keys
Can get full access to all endpoints including POST mutations. Handle with care — store securely, never expose client-side.
403.GET https://bot.nitsu.xyz/dapi/guild/123456789/info Authorization: Bearer nitsu_your_api_key_here Content-Type: application/json
Rate Limits
Rate limits are enforced per IP address. Limits are returned as standard headers on every response.
Global Limit
Applies to all GET requests.
Write Limit
Applies to all POST requests.
Rate limit headers returned on every response:
RateLimit-Limit: 50 RateLimit-Remaining: 48 RateLimit-Reset: 40
429 Too Many Requests with body {"error":"Trop de requêtes. Merci de ralentir un peu."}Error Handling
All errors return a consistent JSON envelope with an error string field.
| Status | Meaning | When it occurs |
|---|---|---|
| 400 | Bad Request | Missing or invalid field in the request body (payload schema violation) |
| 401 | Unauthorized | No valid session and no valid API key |
| 403 | Forbidden | Invalid key, inactive key, wrong guild scope, or insufficient permissions |
| 404 | Not Found | Guild not found, member not found, or bot absent from the server |
| 429 | Rate Limited | Too many requests in the current window |
| 500 | Server Error | Internal database or Discord API error |
{
"error": "Human-readable error message"
}
Endpoints
https://bot.nitsu.xyz. Guild-scoped endpoints require the bot to be present in the target server. Click any endpoint to expand its full specification.User & Guilds
Returns the guild's channel tree, role list, member count, and whether the user has Administrator permission (this will always be false for API keys regardless of your roles).
{
"guilds": { "eco": [{ "id": "111", "name": "My Server", "icon": "hash" }] },
"channels": {
"textChannels": [{ "id": "...", "name": "general", "parentID": "..." }],
"voiceChannels": [{ "id": "...", "name": "Voice 1", "parentID": "..." }],
"categories": [{ "id": "...", "name": "TEXT CHANNELS" }]
},
"roles": [{ "id": "...", "name": "Member", "color": "#8b5cf6" }],
"memberCount": 1234,
"isAdmin": false
}
Fetch complete cross-module data for a guild member. {query} accepts either a Discord User ID (17–20 digit snowflake) or a username string.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| guildId | string | required | Discord Guild snowflake ID |
| query | string | required | Discord User ID (17–20 digits) or username string |
{
"userId": "123456789012345678",
"userName": "nitsu",
"userAvatar": "https://cdn.discordapp.com/avatars/...",
"eco": { // null if no economy data
"cash": 5000, "bank": 20000, "empruntAmount": 0, ...
},
"ecoItems": [], // array of owned shop items
"moderation": { // null if no moderation record
"warnings": 2, "mutedUntil": null, ...
},
"level": { // null if levels disabled
"level": 12, "points": 3400
},
"enterprises": [], // owned enterprise slots
"enterpriseItems": [], // produced items
"enterpriseMaterials": [] // held materials
}
Configuration
Fetch configuration for utility features: temp channels, staff logs, and ticket system.
{
"tempChannelCategoryId": "...", // category for temp voice channels
"tempChannelRoleId": "...", // role that can create temp channels
"tempChannelCreatedId": "...", // the "create" trigger voice channel
"staffLogsChannelId": "...", // channel for staff action logs
"ticketCategoryId": "...", // category for ticket channels
"maxTickets": 5 // max open tickets per user (1-50)
}
Partially update utility module settings. All fields are optional — only included fields are updated.
Request Body
| Field | Type | Required | Constraints |
|---|---|---|---|
| tempChannelCategoryId | string | optional | Discord channel snowflake |
| tempChannelRoleId | string | optional | Discord role snowflake |
| tempChannelCreatedId | string | optional | Discord channel snowflake |
| staffLogsChannelId | string | optional | Discord channel snowflake |
| ticketCategoryId | string | optional | Discord channel snowflake |
| maxTickets | number | optional | Integer, min: 1, max: 50 |
{ "success": true }Returns consolidated Auto-Mod thresholds, toggles, and allowed ad channels.
{
"swearThreshold": 3,
"adThreshold": 2,
"superMuteAtWarns": 5,
"kickAtWarns": 7,
"banAtWarns": 10,
"ultraSafe": false,
"automodAntiSpam": true,
"automodAntiMentions":true,
"automodAntiJurons": false,
"automodAntiPubs": true,
"automodMuteDuration":10, // minutes
"allowedAdsChannels": [{ "channelId": "..." }]
}
Update Auto-Mod configuration. Passing allowedAdsChannels fully replaces the list (up to 50 entries).
| Field | Type | Required | Constraints |
|---|---|---|---|
| swearThreshold | number | optional | min: 1 |
| adThreshold | number | optional | min: 1 |
| superMuteAtWarns | number | optional | min: 1 |
| kickAtWarns | number | optional | min: 1 |
| banAtWarns | number | optional | min: 1 |
| ultraSafe | boolean | optional | — |
| automodAntiSpam | boolean | optional | — |
| automodAntiMentions | boolean | optional | — |
| automodAntiJurons | boolean | optional | — |
| automodAntiPubs | boolean | optional | — |
| automodMuteDuration | number | optional | min: 0 (minutes) |
| allowedAdsChannels | array | optional | max: 50 items, each with channelId |
{ "success": true }Returns welcome/goodbye messages, join role, and anti-double-account level.
{
"welcomeChannelId": "...",
"welcomeMessage": "Welcome {membre}!", // {membre} = @mention
"goodbyeMessage": "Goodbye {membre}.",
"onJoinRoleId": "...", // role given on join
"antiDoubleAccount": 1, // 0=off, 1=log, 2=kick same IP, 3=strict
"verifLogsChannelId": "..."
}
| Field | Type | Required | Constraints |
|---|---|---|---|
| welcomeChannelId | string | optional | Discord channel snowflake |
| welcomeMessage | string | optional | max: 2000 chars. Use {membre} for mention |
| goodbyeMessage | string | optional | max: 2000 chars |
| onJoinRoleId | string | optional | Discord role snowflake |
| antiDoubleAccount | number | optional | 0 = disabled · 1 = log only · 2 = kick same IP · 3 = strict (kick proxy OR same IP) |
| verifLogsChannelId | string | optional | Discord channel snowflake |
{ "success": true }{
"featureEnabled": true,
"levelUpChannelId": "...",
"levelUpMessage": "GG {membre}, level {level}!",
"xpCooldownSeconds": 60,
"requiredRoleId": "...", // role required to earn XP
"roleRewards": [
{ "id": 1, "level": 10, "roleId": "..." }
],
"ignoredChannels": [
{ "id": 1, "channelId": "..." }
]
}
Passing roleRewards or ignoredChannels will fully replace those collections. Max 500 items per array.
| Field | Type | Required | Constraints |
|---|---|---|---|
| featureEnabled | boolean | optional | — |
| levelUpChannelId | string | optional | Discord channel snowflake |
| levelUpMessage | string | optional | max: 2000 chars |
| xpCooldownSeconds | number | optional | min: 0 |
| requiredRoleId | string | optional | Discord role snowflake |
| roleRewards | array | optional | max: 500 — each: {level, roleId} |
| ignoredChannels | array | optional | max: 500 — each: {channelId} |
{ "success": true }Economy
Returns full economy configuration including feature flags, earning params, and all items/role salaries.
{
"featureEconomy": true,
"featureWork": true,
"featureCrime": false,
"featureRob": false,
"featureNitsuCrypt":true,
"featureCoinFlip": true,
"featureBitcoin": false,
"workMinEarning": 50,
"workMaxEarning": 200,
"workCooldownHours": 4,
"crimeMinEarning": 100,
"crimeMaxEarning": 500,
"crimeCooldownHours": 6,
"robCooldownHours": 8,
"chatMinEarning": 5,
"chatMaxEarning": 15,
"chatCooldownMinutes": 2,
"cooldownCasinoMinutes":30,
"casinoLimit": 1000,
"startingMoney": 500,
"maxBank": 100000,
"maxEmpruntable": 5000,
"roleSalaries": [
{ "id": 1, "roleId": "...", "amount": 100 }
],
"items": [
{ "id": 1, "name": "Café", "price": 50, "description": "Un bon café" }
]
}
Partially update economy settings. roleSalaries and items support upsert/delete — include an id to update an existing record, omit it to create a new one. Records not present in the array are deleted.
| Field | Type | Required | Constraints |
|---|---|---|---|
| featureEconomy … featureBitcoin | boolean | optional | 7 feature flag toggles |
| workMinEarning / workMaxEarning | number | optional | — |
| workCooldownHours | number | optional | min: 0 |
| crimeMinEarning / crimeMaxEarning | number | optional | — |
| crimeCooldownHours | number | optional | min: 0 |
| robCooldownHours | number | optional | min: 0 |
| chatMinEarning / chatMaxEarning | number | optional | — |
| chatCooldownMinutes | number | optional | min: 0 |
| cooldownCasinoMinutes | number | optional | min: 0 |
| casinoLimit | number | optional | min: 0 |
| startingMoney | number | optional | min: 0 |
| maxBank | number | optional | — |
| maxEmpruntable | number | optional | min: 0 |
| roleSalaries | array | optional | max: 500 — each: {id?, roleId, amount} |
| items | array | optional | max: 500 — each: {id?, name, price, description} |
{ "success": true }Returns enterprise module settings including types, material types, and item types (with their material requirements).
{
"featureEnabled": true,
"maxEnterprises": 3,
"enterpriseTypes": [
{ "id": 1, "name": "Bakery", "price": 5000 }
],
"materialTypes": [
{ "id": 1, "name": "Flour", "price": 100 }
],
"enterpriseItemTypes": [
{
"id": 1, "name": "Baguette", "sellPrice": 200,
"materials": [{ "materialTypeId": 1, "quantity": 2 }]
}
]
}
Update enterprise system settings. Array fields support upsert via id. Item types include a nested materials array that is fully replaced on each save.
| Field | Type | Required | Constraints |
|---|---|---|---|
| featureEnabled | boolean | optional | — |
| maxEnterprises | number | optional | min: 1 |
| enterpriseTypes | array | optional | max: 500 — each: {id?, name, price} |
| materialTypes | array | optional | max: 500 — each: {id?, name, price} |
| enterpriseItemTypes | array | optional | max: 500 — each: {id?, name, sellPrice, materials: [{materialTypeId, quantity}]} |
{ "success": true }Analytics
Aggregated analytics across all modules: economy leaderboard, enterprise averages, alliance count, and top XP rankings.
{
"membersTotal": 1234,
"totalCash": 4500000,
"totalBank": 12000000,
"avgMoney": 8200,
"activeLoans": 7,
"top3Richest": [
{ "name": "nitsu", "avatar": "https://...", "total": 500000 }
],
"mostOwnedItemName": "Café",
"enterprise": {
"averages": { "ents": "1.2", "mats": "5.4", "prods": "3.1" },
"moEnt": "Bakery", "moMat": "Flour", "moProd": "Baguette"
},
"allianceCount": 3,
"top10Levels": [
{ "name": "nitsu", "avatar": "https://...", "level": 42, "points": 18200 }
]
}
Returns the latest NitsuBot news posts (up to 10), active dashboard sponsors, current bot status from Instatus, and the 10 most recent guild audit log entries.
{
"newsList": [
{ "id": 1, "title": "v3.2.0 Released", "content": "...", "publishedAt": "2026-04-01T..." }
],
"botStatus": "En ligne", // "En ligne" | "Performance dégradée" | "Maintenance en cours"
"sponsors": [
{ "id": 1, "name": "Sponsor" }
],
"serverLogs": [
{
"id": "...",
"actionType": 24, // Discord AuditLogEvent integer
"executor": { "id": "...", "username": "nitsu" },
"target": { "id": "..." },
"reason": "Spam",
"createdAt": "2026-04-22T12:00:00.000Z"
}
]
}
Quickstart
Get your first DAPI response in under a minute.
# Get guild insights curl -X GET \ "https://bot.nitsu.xyz/dapi/guild/YOUR_GUILD_ID/insights" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json"
const BASE = 'https://bot.nitsu.xyz'; const KEY = 'nitsu_your_api_key'; const GUILD = 'YOUR_GUILD_ID'; async function getInsights() { const res = await fetch(`${BASE}/dapi/guild/${GUILD}/insights`, { headers: { 'Authorization': `Bearer ${KEY}` } }); if (!res.ok) throw new Error(await res.text()); return res.json(); } getInsights().then(data => console.log(data));
import requests BASE = "https://bot.nitsu.xyz" KEY = "nitsu_your_api_key" GUILD = "YOUR_GUILD_ID" headers = {"Authorization": f"Bearer {KEY}"} r = requests.get(f"{BASE}/dapi/guild/{GUILD}/insights", headers=headers) r.raise_for_status() print(r.json())