Integra tu servidor de Discord con scripts y aplicaciones externas. Lectura y, desde v1.1, escritura (economía) protegida por scopes. Disponible para Roody Pro y Team.
Genera una clave en Claves de API y haz tu primera petición:
curl https://dashboard.roody.es/api/v1/me \ -H "Authorization: Bearer rdy_TU_CLAVE_AQUI"
O en JavaScript:
const res = await fetch('https://dashboard.roody.es/api/v1/me', {
headers: { 'X-API-Key': 'rdy_TU_CLAVE_AQUI' }
});
const { data } = await res.json();
console.log(data.user.username, data.plan.tier);
Toda petición a /api/v1/* debe llevar la clave en uno de estos dos headers:
Authorization: Bearer rdy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X-API-Key: rdy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Las claves son personales, intransferibles y nunca se vuelven a mostrar tras crearlas — guárdalas en un gestor de secretos. Si una clave se compromete, revócala desde tu panel y crea otra.
Cada clave tiene un límite de peticiones por minuto que depende del plan del dueño. Si lo superas, devolvemos 429 con el header Retry-After.
Cada respuesta incluye headers X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset para que tu cliente sepa cuánto te queda.
Devuelve el usuario dueño de la clave, su plan, la cuota por minuto y los metadatos de la clave usada en la petición.
{
"success": true,
"data": {
"user": {
"discordId": "123456789012345678",
"username": "tu_usuario"
},
"plan": {
"tier": "pro",
"name": "Pro"
},
"rateLimit": {
"perMinute": 60,
"advanced": false
},
"apiKey": {
"prefix": "rdy_aB3xF2gH",
"label": "Mi script",
"createdAt": "2026-05-24T10:00:00.000Z",
"lastUsedAt": "2026-05-24T10:42:11.000Z"
}
}
}
Estado actual del bot (online/connecting), número de servidores y usuarios, ping al gateway y uptime en milisegundos.
{
"success": true,
"data": {
"status": "online",
"servers": 1284,
"users": 458321,
"ping": 41,
"uptimeMs": 184302000
}
}
Servidores donde la cuenta dueña de la clave es propietaria o tiene "Administrator". Incluye nombre, icono, nº de miembros y rol.
{
"success": true,
"data": {
"count": 2,
"guilds": [
{
"id": "987654321098765432",
"name": "Mi servidor",
"icon": "https://cdn.discordapp.com/...",
"memberCount": 348,
"role": "owner"
},
{
"id": "876543210987654321",
"name": "Otro servidor",
"icon": null,
"memberCount": 1240,
"role": "admin"
}
]
}
}
Datos detallados del servidor: descripción, icono, banner, miembros, canales, roles, nivel de boost, fecha de creación, locale, features.
{
"success": true,
"data": {
"id": "987654321098765432",
"name": "Mi servidor",
"memberCount": 348,
"channels": 32,
"roles": 18,
"boost": {
"level": 2,
"count": 7
},
"owner": {
"id": "123456789012345678"
},
"role": "owner"
}
}
Resumen de los módulos activos del servidor y si tienen canal asignado: bienvenidas, despedidas, boost, moderación, logs, sorteos, polls, tickets, antiraid, niveles, economía.
{
"success": true,
"data": {
"guildId": "987654321098765432",
"lang": "es",
"modules": {
"bienvenidas": {
"enabled": true,
"hasChannel": true,
"type": "embed"
},
"moderacion": {
"enabled": true,
"antiflood": true,
"antilinks": false,
"antimayus": false
},
"economia": {
"enabled": false
}
}
}
}
Cartera, banco y datos básicos de economía de un usuario en el servidor. Requiere el scope economy:read (las claves con * lo incluyen).
{
"success": true,
"data": {
"userId": "123456789012345678",
"cash": 1500,
"bank": 8000,
"total": 9500,
"level": 7,
"netWorth": 9500
}
}
Modifica el saldo de un usuario. Body JSON: { "action": "add" | "remove" | "set", "amount": número ≥ 0, "target": "cash" | "bank" (opcional, por defecto cash) }. Requiere el scope economy:write. add/remove se acotan a [0, 10.000.000.000].
{
"success": true,
"data": {
"userId": "123456789012345678",
"cash": 2500,
"bank": 8000,
"total": 10500,
"level": 7,
"netWorth": 9500,
"action": "add",
"target": "cash",
"applied": 1000
}
}
Enciende o apaga un módulo del servidor. Body JSON: { "enabled": true | false }. Módulos soportados: bienvenidas, despedidas, boost, logs, sorteos, polls, tickets, antiraid, niveles, economia. Requiere el scope config:write.
{
"success": true,
"data": {
"guildId": "987654321098765432",
"module": "economia",
"enabled": true
}
}
Registra un warning. Body JSON: { "reason": "texto" } (obligatorio). Requiere el scope moderation:write.
{
"success": true,
"data": {
"userId": "123456789012345678",
"warnId": "A1B2C3",
"reason": "Spam en general",
"totalWarns": 2
}
}
Aplica un timeout. Body JSON: { "durationSeconds": 1..2419200, "reason": "texto" (opcional) }. El bot necesita "Moderar miembros" y estar por encima del usuario. Scope moderation:write.
{
"success": true,
"data": {
"userId": "123456789012345678",
"action": "timeout",
"durationSeconds": 3600,
"reason": "Flood"
}
}
Expulsa al usuario. Body JSON: { "reason": "texto" (opcional) }. El bot necesita "Expulsar miembros" y jerarquía sobre el usuario. Scope moderation:write.
{
"success": true,
"data": {
"userId": "123456789012345678",
"action": "kick",
"reason": "Saltarse las normas"
}
}
Banea al usuario (también sirve como ban preventivo si no está en el servidor). Body JSON: { "reason": "texto" (opcional), "deleteMessageSeconds": 0..604800 (opcional) }. El bot necesita "Banear miembros". Scope moderation:write.
{
"success": true,
"data": {
"userId": "123456789012345678",
"action": "ban",
"reason": "Raid",
"deleteMessageSeconds": 86400
}
}
Ejemplos completos de cosas que puedes automatizar. Cambia de lenguaje con los botones y sustituye rdy_TU_CLAVE, GUILD_ID y USER_ID por los tuyos.
Tu web/juego da 500 monedas a un miembro cuando completa una acción. (scope economy:write)
curl -X POST https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID/balance \
-H "Authorization: Bearer rdy_TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{"action":"add","amount":500,"target":"cash"}'
const res = await fetch(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID/balance',
{
method: 'POST',
headers: {
'Authorization': 'Bearer rdy_TU_CLAVE',
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'add', amount: 500, target: 'cash' })
}
);
const { data } = await res.json();
console.log('Nuevo saldo:', data.cash);
import requests
res = requests.post(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID/balance',
headers={'Authorization': 'Bearer rdy_TU_CLAVE'},
json={'action': 'add', 'amount': 500, 'target': 'cash'},
)
print('Nuevo saldo:', res.json()['data']['cash'])
Un anti-cheat o panel externo banea a un tramposo y borra sus mensajes del último día. (scope moderation:write)
curl -X POST https://dashboard.roody.es/api/v1/guilds/GUILD_ID/members/USER_ID/ban \
-H "Authorization: Bearer rdy_TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{"reason":"Trampas detectadas","deleteMessageSeconds":86400}'
await fetch(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/members/USER_ID/ban',
{
method: 'POST',
headers: {
'Authorization': 'Bearer rdy_TU_CLAVE',
'Content-Type': 'application/json'
},
body: JSON.stringify({ reason: 'Trampas detectadas', deleteMessageSeconds: 86400 })
}
);
import requests
requests.post(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/members/USER_ID/ban',
headers={'Authorization': 'Bearer rdy_TU_CLAVE'},
json={'reason': 'Trampas detectadas', 'deleteMessageSeconds': 86400},
)
Antes de un evento, desactivas la economía desde tu script y la vuelves a activar al terminar. (scope config:write)
curl -X PATCH https://dashboard.roody.es/api/v1/guilds/GUILD_ID/config/economia \
-H "Authorization: Bearer rdy_TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{"enabled":false}'
await fetch(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/config/economia',
{
method: 'PATCH',
headers: {
'Authorization': 'Bearer rdy_TU_CLAVE',
'Content-Type': 'application/json'
},
body: JSON.stringify({ enabled: false })
}
);
import requests
requests.patch(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/config/economia',
headers={'Authorization': 'Bearer rdy_TU_CLAVE'},
json={'enabled': False},
)
Muestra en tu web cuánto dinero tiene un miembro. (scope economy:read)
curl https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID \ -H "Authorization: Bearer rdy_TU_CLAVE"
const res = await fetch(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID',
{ headers: { 'Authorization': 'Bearer rdy_TU_CLAVE' } }
);
const { data } = await res.json();
console.log(`${data.cash} en cartera, ${data.bank} en banco`);
import requests
res = requests.get(
'https://dashboard.roody.es/api/v1/guilds/GUILD_ID/economy/users/USER_ID',
headers={'Authorization': 'Bearer rdy_TU_CLAVE'},
)
data = res.json()['data']
print(data['cash'], 'en cartera,', data['bank'], 'en banco')
Si haces muchas llamadas seguidas, ante un 429 espera los segundos de Retry-After y reintenta.
# --retry reintenta y respeta el header Retry-After curl --retry 3 --retry-delay 0 \ https://dashboard.roody.es/api/v1/me \ -H "Authorization: Bearer rdy_TU_CLAVE"
async function call(url, opts) {
for (let i = 0; i < 4; i++) {
const res = await fetch(url, opts);
if (res.status !== 429) return res;
const wait = Number(res.headers.get('Retry-After') || 1);
await new Promise(r => setTimeout(r, wait * 1000));
}
throw new Error('Rate limit: reintentos agotados');
}
import time, requests
def call(method, url, **kw):
for _ in range(4):
res = requests.request(method, url, **kw)
if res.status_code != 429:
return res
time.sleep(int(res.headers.get('Retry-After', 1)))
raise RuntimeError('Rate limit: reintentos agotados')
Todos los errores siguen el mismo formato: success: false + error.code + error.message.
{
"success": false,
"error": {
"code": "tier_insufficient",
"message": "Esta clave pertenece a un usuario sin acceso a la API.",
"currentTier": "free",
"requiredTier": "pro"
}
}
Códigos de error más comunes:
| HTTP | code | Cuándo ocurre |
|---|---|---|
| 401 | missing_api_key | Falta el header de autenticación. |
| 401 | invalid_api_key | Clave no encontrada o revocada. |
| 401 | expired_api_key | La clave ha caducado. |
| 403 | tier_insufficient | El dueño de la clave no tiene Pro/Team. |
| 403 | guild_access_denied | El dueño de la clave no administra ese servidor. |
| 403 | insufficient_scope | La clave no incluye el scope necesario (p. ej. economy:write). |
| 400 | invalid_action / invalid_amount / invalid_user_id | Parámetros de escritura inválidos (economía). |
| 400 | invalid_module / invalid_body | Módulo no soportado o body inválido (config). |
| 404 | config_not_found | El servidor no tiene configuración. |
| 400 | invalid_reason / invalid_duration | Faltan o son inválidos los parámetros de moderación. |
| 403 | target_is_owner / target_is_bot / hierarchy_error / bot_missing_permission | No se puede moderar a ese usuario (dueño, el propio bot, jerarquía o falta de permiso del bot). |
| 404 | member_not_found | El usuario no está en el servidor (para timeout/kick). |
| 502 | action_failed | Discord rechazó la acción de moderación. |
| 404 | guild_not_found | El bot no está en el servidor pedido. |
| 404 | economy_user_not_found | El usuario no tiene economía en ese servidor. |
| 404 | endpoint_not_found | Endpoint no existe en v1. |
| 429 | rate_limited | Has superado tu cuota por minuto. |
| 503 | bot_unavailable | El bot está desconectado. |