API pública de BRES
Documentación oficial de la API REST pública de BRES, el repositorio de plugins, mapas, addons, cores y resource packs para Minecraft Bedrock.
La API permite consultar el catálogo, buscar recursos, leer perfiles de usuarios y organizaciones, y descargar versiones. Todos los endpoints de esta página son públicos; los endpoints de escritura y los datos privados están fuera de este documento.
| Base URL | https://api.bettersrv.host/services/bres |
| Versión | 2.0.0 |
| Formato | JSON (UTF-8); las descargas devuelven el archivo binario |
| Autenticación | No requerida, salvo la descarga de proyectos de pago |
| CORS | Abierto para /services/*: el origen de la petición se refleja en Access-Control-Allow-Origin |
| Última actualización | 28 de octubre de 2026 |
Esta referencia cubre únicamente los endpoints públicos. Las rutas autenticadas viven bajo
/services/bres/clienty requieren una sesión de Clerk.
Primeros pasos
La forma más rápida de comprobar que la API responde es pedir la lista de categorías de plugins:
curl "https://api.bettersrv.host/services/bres/categories?type=plugin"
Y una búsqueda desde JavaScript:
const response = await fetch(
"https://api.bettersrv.host/services/bres/projects/search?q=economy&limit=5",
);
if (!response.ok) {
throw new Error(`BRES API respondió ${response.status}`);
}
const { data, pagination } = await response.json();
console.log(data[0]?.name, pagination.total);
Todas las rutas de esta documentación se escriben relativas a la Base URL. Por ejemplo, /projects/search corresponde a https://api.bettersrv.host/services/bres/projects/search.
Autenticación
Los endpoints públicos no necesitan credenciales. No hay API keys ni tokens obligatorios para leer el catálogo.
Algunos endpoints aceptan autenticación opcional para ampliar la respuesta:
| Endpoint | Efecto de autenticarse |
|---|---|
GET /projects/:slug | Permite ver un proyecto en estado under_review si eres su dueño o moderador. |
GET /projects/:slug/comments | Rellena likedByUser según los likes del usuario autenticado. |
GET /projects/:slug/versions | Incluye versiones no listadas (pending_review, rejected) si eres dueño, colaborador o moderador. |
GET /projects/:slug/versions/:versionId | Permite consultar una versión no listada con esos mismos permisos. |
La descarga de un proyecto de pago sí exige autenticación. Envíala como token de Clerk:
Authorization: Bearer <clerk_token>
También se acepta la cookie de sesión del frontend de BRES. Nunca compartas tu token: da acceso a tu cuenta.
Límites de uso
Los límites se aplican por IP y devuelven 429 Too Many Requests cuando se superan. Las respuestas incluyen cabeceras RateLimit con el estado de la ventana.
| Ámbito | Límite | Ventana |
|---|---|---|
| General (todos los endpoints) | 50 peticiones | 10 segundos |
Búsqueda (/projects/search) | 60 peticiones | 1 minuto |
Descarga (/versions/:versionId/download) | 30 peticiones | 1 minuto |
Los límites se acumulan: una búsqueda consume tanto la cuota general como la específica de búsqueda.
Convenciones
Paginación
Los endpoints paginados devuelven un objeto pagination:
{
"page": 1,
"limit": 20,
"total": 137,
"pages": 7
}
page empieza en 1 y limit por defecto es 20. Usa page para avanzar y limit para ajustar el tamaño de página.
Fechas e identificadores
- Las fechas son cadenas ISO 8601 en UTC, por ejemplo
2026-10-23T12:00:00.000Z. - Los identificadores de proyectos y versiones son ObjectId de MongoDB de 24 caracteres hexadecimales.
- En los resultados de búsqueda el campo
idequivale al_iddel proyecto.
Errores
Los errores de la aplicación usan un cuerpo JSON con una sola propiedad error:
{ "error": "Project not found" }
La excepción son los 429 del limitador de peticiones, que pueden devolver una respuesta de texto en lugar de JSON.
| Código | Significado |
|---|---|
400 | Parámetro inválido o ausente. |
401 | La descarga requiere autenticación y no se envió una sesión válida. |
403 | Autenticado, pero sin licencia para descargar el recurso. |
404 | El recurso no existe o no es visible públicamente. |
429 | Se superó un límite de peticiones. |
500 | Error interno del servidor. |
502 | El archivo no pudo obtenerse del almacenamiento durante una descarga. |
URLs absolutas
Las URLs de imágenes y descargas que devuelve la API son absolutas. No necesitas anteponer la Base URL a thumbnail, banner, files[].downloadUrl ni downloadUrl.
Endpoints
| Método | Ruta | Descripción |
|---|---|---|
GET | / | Metadatos de la API. |
GET | /categories | Categorías disponibles por tipo de recurso. |
GET | /projects/search | Búsqueda de proyectos con filtros y ordenación. |
GET | /projects/rating-reasons | Motivos predefinidos para valorar un proyecto. |
GET | /projects/:slug | Detalle completo de un proyecto. |
GET | /projects/:slug/comments | Comentarios y respuestas de un proyecto. |
GET | /projects/:slug/versions | Versiones publicadas de un proyecto. |
GET | /projects/:slug/versions/:versionId | Detalle de una versión. |
GET | /projects/:slug/versions/:versionId/download | Descarga del archivo de una versión. |
GET | /users/:username | Perfil público de un usuario. |
GET | /organizations/:slug | Perfil público de una organización. |
GET | /organizations/:slug/projects | Proyectos de una organización. |
GET | /organization/:slug | Perfil extendido de una organización. |
GET/
Devuelve los metadatos de la API y un catálogo informativo de rutas.
GET https://api.bettersrv.host/services/bres
Respuesta 200
{
"name": "BRES API",
"version": "2.0.0",
"description": "Bedrock Resource Marketplace — plugins, addons, worlds y resource packs para Minecraft Bedrock",
"endpoints": {
"public": ["GET /categories", "GET /projects/search", "..."],
"authenticated": ["POST /projects/:slug/rate", "GET /client/my-projects", "..."]
}
}
El catálogo endpoints es informativo y puede incluir rutas heredadas. Esta página es la referencia vigente de los endpoints públicos.
GET/categories
Lista las categorías disponibles. Sin filtro devuelve todas, agrupadas por tipo.
Parámetros de consulta
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
type | string | No | Filtra por tipo: plugin, world, addon, resourcepack o core. |
Respuesta 200 sin filtro
[
{ "value": "economy", "label": "Economía", "type": "plugin" },
{ "value": "gamemode", "label": "Modos de juego", "type": "plugin" },
{ "value": "survival", "label": "Supervivencia", "type": "world" },
{ "value": "realistic", "label": "Realista", "type": "resourcepack" }
]
Respuesta 200 con ?type=plugin
[
{ "value": "economy", "label": "Economía" },
{ "value": "gamemode", "label": "Modos de juego" },
{ "value": "mechanics", "label": "Mecánicas" }
]
Ejemplos
# Todas las categorías
curl "https://api.bettersrv.host/services/bres/categories"
# Solo categorías de plugins
curl "https://api.bettersrv.host/services/bres/categories?type=plugin"
# Solo categorías de cores
curl "https://api.bettersrv.host/services/bres/categories?type=core"
La lista completa de valores está en Categorías.
Errores
| Código | Cuerpo |
|---|---|
500 | { "error": "Internal server error" } |
GET/projects/search
Búsqueda full-text sobre el catálogo, con filtros y ordenación. Solo devuelve proyectos con estado active.
Rate limit: 60 peticiones por minuto.
Parámetros de consulta
| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
q | string | — | Texto a buscar. Busca en nombre, descripción corta, categorías, loaders y tipo. |
category | string | — | Categoría exacta, por ejemplo economy o survival. |
type | string | — | Tipo de recurso: plugin, world, addon, resourcepack o core. |
subtype | string | — | Para plugins: plugin o virion. |
loader | string | — | Loader compatible: pocketmine, nukkit, waterdogpe o vanilla. |
tag | string | — | Etiqueta gestionada por el sistema: incompatible o broken (ver Etiquetas del sistema). |
verified | string | — | "true" devuelve solo autores verificados; "false" los excluye. |
featured | string | — | "true" devuelve solo proyectos destacados. |
sort | string | relevancia | Campo de ordenación. Antepón - para orden descendente, por ejemplo -downloads. |
limit | number | 20 | Resultados por página. |
page | number | 1 | Número de página. |
Campos ordenables: downloads, likes, averageRating, createdAt y updatedAt. Cualquier otro campo puede provocar un error del motor de búsqueda.
Respuesta 200
{
"data": [
{
"id": "68f2c1a4e9b7d3a12c4f5e60",
"name": "EconomyPlus",
"slug": "economyplus",
"type": "plugin",
"subtype": "plugin",
"loaders": ["pocketmine"],
"shortDescription": "Economía completa para tu servidor",
"categories": ["economy"],
"author": {
"type": "user",
"slug": "dev123"
},
"verified": true,
"featured": false,
"downloads": 15420,
"likes": 312,
"averageRating": 4.6,
"thumbnail": "https://cdn.bettersrv.host/bres/economyplus.webp",
"banner": "https://cdn.bettersrv.host/bres/economyplus-banner.webp",
"status": "active",
"gameVersions": ["1.20.80", "1.21.0", "1.21.50"],
"versionType": ["release"],
"tags": [],
"pluginApi": ["5.0.0"],
"createdAt": "2025-06-12T09:30:00.000Z",
"updatedAt": "2026-10-01T18:12:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 43,
"pages": 3
},
"totalResources": 1284,
"query": "economy",
"processingTimeMs": 4
}
| Campo | Descripción |
|---|---|
data | Proyectos que coinciden con la búsqueda. |
pagination | Página actual, tamaño, total de coincidencias y total de páginas. |
totalResources | Total de proyectos activos en el catálogo (se cachea unos minutos). |
query | Texto buscado, tal como se envió. |
processingTimeMs | Tiempo que tardó el motor de búsqueda en milisegundos. |
Cada resultado incluye además tags (etiquetas gestionadas por el sistema, normalmente vacío) y pluginApi (unión de las APIs declaradas por todas las versiones del proyecto, por ejemplo ["5.0.0"]).
Ejemplos
# Plugins de economía ordenados por descargas
curl "https://api.bettersrv.host/services/bres/projects/search?q=economy&type=plugin&sort=-downloads"
# Virions para PocketMine
curl "https://api.bettersrv.host/services/bres/projects/search?subtype=virion&loader=pocketmine"
# Segunda página de proyectos destacados
curl "https://api.bettersrv.host/services/bres/projects/search?featured=true&page=2&limit=10"
# Solo plugins marcados como incompatibles con PocketMine-MP 5
curl "https://api.bettersrv.host/services/bres/projects/search?tag=incompatible&type=plugin"
Errores
| Código | Cuerpo |
|---|---|
429 | Demasiadas peticiones. |
500 | { "error": "Internal server error" } |
GET/projects/rating-reasons
Devuelve los motivos predefinidos que puede elegir un usuario al valorar un proyecto, agrupados por número de estrellas (de 1 a 5).
Respuesta 200
{
"1": [
{ "value": "broken", "label": "No funciona correctamente" },
{ "value": "malware", "label": "Contiene malware o código malicioso" }
],
"2": [
{ "value": "buggy", "label": "Tiene muchos bugs y errores" }
],
"3": [
{ "value": "average", "label": "Cumple su función pero nada especial" }
],
"4": [
{ "value": "good", "label": "Buen recurso, funciona bien" }
],
"5": [
{ "value": "excellent", "label": "Excelente en todos los aspectos" }
]
}
La tabla completa está en Motivos de valoración.
Errores
| Código | Cuerpo |
|---|---|
500 | { "error": "Internal server error" } |
GET/projects/:slug
Devuelve el detalle completo de un proyecto. Solo los proyectos activos son visibles públicamente; un proyecto en revisión responde 404 salvo para su dueño o un moderador autenticado.
Cada petición puede incrementar el contador de vistas. Se cuenta como máximo una vista por IP cada 24 horas para el mismo proyecto, y se ignoran los user-agents de bots.
Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
slug | string | Slug único del proyecto. |
Respuesta 200
{
"_id": "68f2c1a4e9b7d3a12c4f5e60",
"name": "EconomyPlus",
"slug": "economyplus",
"type": "plugin",
"subtype": "plugin",
"loaders": ["pocketmine"],
"categories": ["economy"],
"description": "# EconomyPlus\n\nSistema de economía con soporte para...",
"shortDescription": "Economía completa para tu servidor",
"thumbnail": "https://cdn.bettersrv.host/bres/economyplus.webp",
"banner": "https://cdn.bettersrv.host/bres/economyplus-banner.webp",
"screenshots": ["https://cdn.bettersrv.host/bres/economyplus-1.webp"],
"author": {
"type": "user",
"slug": "dev123"
},
"collaborators": ["helper1"],
"dependencies": [
{
"_id": "68e1b2c3d4e5f60718293a4b",
"name": "VaultAPI",
"slug": "vaultapi",
"thumbnail": "https://cdn.bettersrv.host/bres/vaultapi.webp",
"type": "plugin"
}
],
"downloads": 15420,
"views": 2890,
"likes": 312,
"averageRating": 4.6,
"totalRatings": 87,
"featured": false,
"verified": true,
"status": "active",
"tags": ["incompatible"],
"pluginTest": {
"result": "incompatible",
"reason": "Incompatible API version (plugin requires one of: 4.0.0)",
"pmVersion": "5.50.0",
"phpVersion": "8.4.27",
"at": "2026-10-27T02:25:16.363Z"
},
"sourceUrl": "https://github.com/dev123/economyplus",
"websiteUrl": null,
"discordUrl": null,
"license": "MIT",
"pricing": {
"type": "free",
"price": {
"amount": 0,
"currency": "USD"
},
"paymentMode": "owner"
},
"latestVersion": "2.4.1",
"latestChangelog": "Corrige el guardado de balances y añade soporte para 1.21.80.",
"createdAt": "2025-06-12T09:30:00.000Z",
"updatedAt": "2026-10-01T18:12:00.000Z"
}
latestVersion y latestChangelog son cadenas o null si el proyecto todavía no tiene versiones. pricing siempre está presente.
tags y pluginTest los genera la prueba automática que arranca cada versión en un servidor PocketMine-MP real (ver Etiquetas del sistema). En proyectos que nunca se probaron, tags es [] y pluginTest.result es null.
Ejemplo
curl "https://api.bettersrv.host/services/bres/projects/economyplus"
# Solo los proyectos incompatibles con PocketMine-MP 5
curl "https://api.bettersrv.host/services/bres/projects/search?tag=incompatible"
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "Project not found" } |
500 | { "error": "Internal server error" } |
GET/projects/:slug/comments
Lista los comentarios principales de un proyecto, con sus respuestas anidadas. Solo funciona para proyectos activos.
La autenticación es opcional: si envías una sesión válida, cada comentario incluye likedByUser según tus likes.
Parámetros de ruta y consulta
| Parámetro | Ubicación | Tipo | Por defecto | Descripción |
|---|---|---|---|---|
slug | ruta | string | — | Slug del proyecto. |
page | query | number | 1 | Página de comentarios. |
limit | query | number | 20 | Comentarios principales por página. |
Respuesta 200
{
"comments": [
{
"_id": "6701a2b3c4d5e6f708192a3b",
"content": "Funciona perfecto en PocketMine 5.20.",
"author": {
"userId": "user_2abc123def456",
"username": "server_owner",
"avatar": "https://img.clerk.com/..."
},
"likes": 7,
"likedByUser": false,
"createdAt": "2026-09-18T14:32:00.000Z",
"updatedAt": "2026-09-18T14:32:00.000Z",
"replies": [
{
"_id": "6701a2b3c4d5e6f708192a3c",
"content": "Gracias por el reporte.",
"author": {
"userId": "user_2dev123",
"username": "dev123",
"avatar": "https://img.clerk.com/..."
},
"likes": 2,
"likedByUser": false,
"createdAt": "2026-09-18T16:05:00.000Z",
"updatedAt": "2026-09-18T16:05:00.000Z"
}
]
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 34,
"pages": 2
}
}
Las respuestas se ordenan de más antigua a más reciente y solo hay un nivel de anidación.
Ejemplo
curl "https://api.bettersrv.host/services/bres/projects/economyplus/comments?page=1&limit=10"
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "Project not found" } |
500 | { "error": "Internal server error" } |
GET/projects/:slug/versions
Lista las versiones publicadas de un proyecto, de la más reciente a la más antigua. Cada versión incluye una downloadUrl lista para usar.
Públicamente solo se muestran versiones con estado listed. Si te autenticas como dueño, colaborador o moderador, también verás las versiones pendientes o rechazadas.
Parámetros de ruta y consulta
| Parámetro | Ubicación | Tipo | Por defecto | Descripción |
|---|---|---|---|---|
slug | ruta | string | — | Slug del proyecto. |
page | query | number | 1 | Página de versiones. |
limit | query | number | 20 | Versiones por página. |
version_type | query | string | — | Filtra por release, beta o alpha. |
game_version | query | string | — | Filtra por versión de Minecraft Bedrock, por ejemplo 1.21.50. |
Respuesta 200
{
"project": {
"name": "EconomyPlus",
"slug": "economyplus",
"author": {
"type": "user",
"slug": "dev123"
},
"type": "plugin",
"status": "active"
},
"versions": [
{
"_id": "68fa11b2c3d4e5f607182930",
"projectId": "68f2c1a4e9b7d3a12c4f5e60",
"version": "2.4.1",
"versionType": "release",
"loaders": ["pocketmine"],
"gameVersions": ["1.21.50", "1.21.80"],
"changelog": "Corrige el guardado de balances.",
"files": [
{
"_id": "68fa11b2c3d4e5f607182931",
"filename": "EconomyPlus-2.4.1.phar",
"fileSize": 184320,
"fileExtension": "phar",
"fileType": "direct",
"primary": true,
"sha1": "f1c2...",
"sha512": "9a8b..."
}
],
"dependencies": [],
"fileSize": 184320,
"fileExtension": "phar",
"fileType": "direct",
"pluginApi": ["5.0.0"],
"pluginTest": {
"result": "ok",
"reason": null,
"at": "2026-10-27T02:25:16.363Z"
},
"releaseDate": "2026-09-30T00:00:00.000Z",
"downloads": 842,
"status": "listed",
"downloadUrl": "https://api.bettersrv.host/services/bres/projects/economyplus/versions/68fa11b2c3d4e5f607182930/download",
"createdAt": "2026-09-30T11:20:00.000Z",
"updatedAt": "2026-10-01T09:00:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 6,
"pages": 1
}
}
Por seguridad, el listado omite files[].downloadUrl; usa el downloadUrl de la versión, que pasa por el endpoint de descarga y actualiza los contadores.
pluginApi recoge las APIs que declara el manifiesto (plugin.yml) de ese archivo, por ejemplo ["5.0.0"] para PocketMine-MP 5 o ["3.0.0", "4.0.0"] para plugins antiguos. pluginTest es el veredicto de haber arrancado esa versión en un servidor real; el detalle de la versión incluye además pmVersion y phpVersion.
Ejemplos
# Todas las versiones
curl "https://api.bettersrv.host/services/bres/projects/economyplus/versions"
# Solo releases compatibles con 1.21.80
curl "https://api.bettersrv.host/services/bres/projects/economyplus/versions?version_type=release&game_version=1.21.80"
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "Project not found" } |
500 | { "error": "Internal server error" } |
GET/projects/:slug/versions/:versionId
Devuelve el detalle de una versión concreta, incluidas las URLs directas de sus archivos.
Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
slug | string | Slug del proyecto. |
versionId | string | ObjectId de la versión. |
Respuesta 200
{
"project": {
"name": "EconomyPlus",
"slug": "economyplus",
"author": {
"type": "user",
"slug": "dev123"
},
"type": "plugin",
"status": "active"
},
"version": {
"_id": "68fa11b2c3d4e5f607182930",
"projectId": "68f2c1a4e9b7d3a12c4f5e60",
"version": "2.4.1",
"versionType": "release",
"loaders": ["pocketmine"],
"gameVersions": ["1.21.50", "1.21.80"],
"changelog": "Corrige el guardado de balances.",
"files": [
{
"_id": "68fa11b2c3d4e5f607182931",
"filename": "EconomyPlus-2.4.1.phar",
"downloadUrl": "https://pb.bettersrv.host/api/files/...",
"fileSize": 184320,
"fileExtension": "phar",
"fileType": "direct",
"primary": true,
"sha1": "f1c2...",
"sha512": "9a8b..."
}
],
"dependencies": [],
"fileSize": 184320,
"fileExtension": "phar",
"fileType": "direct",
"pluginApi": ["5.0.0"],
"pluginTest": {
"result": "ok",
"reason": null,
"pmVersion": "5.50.0",
"phpVersion": "8.4.27",
"at": "2026-10-27T02:25:16.363Z"
},
"releaseDate": "2026-09-30T00:00:00.000Z",
"downloads": 842,
"status": "listed",
"createdAt": "2026-09-30T11:20:00.000Z",
"updatedAt": "2026-10-01T09:00:00.000Z"
}
}
files[].downloadUrl apunta al almacenamiento y no suma descargas. Para contabilizar la descarga y aplicar la comprobación de licencia, usa el endpoint /download.
Ejemplo
curl "https://api.bettersrv.host/services/bres/projects/economyplus/versions/68fa11b2c3d4e5f607182930"
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "Project not found" } |
404 | { "error": "Version not found" } |
500 | { "error": "Internal server error" } |
GET/projects/:slug/versions/:versionId/download
Descarga el archivo de una versión. La respuesta es el archivo binario, no JSON.
Rate limit: 30 peticiones por minuto.
Autenticación condicional:
- Proyectos gratuitos: no requiere autenticación.
- Proyectos de pago: requiere sesión de Clerk y una licencia comprada. El dueño del proyecto y sus colaboradores pueden descargar sin licencia.
Parámetros
| Parámetro | Ubicación | Tipo | Requerido | Descripción |
|---|---|---|---|---|
slug | ruta | string | Sí | Slug del proyecto. |
versionId | ruta | string | Sí | ObjectId de la versión. |
file | query | string | No | ObjectId del archivo o su extensión (phar, zip…). Sin este parámetro se sirve el archivo principal. Si el valor no coincide con ningún archivo, también se sirve el principal. |
Respuesta 200
Devuelve el archivo con estos encabezados:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="EconomyPlus-2.4.1.phar"; filename*=UTF-8''EconomyPlus-2.4.1.phar
Content-Length: 184320
El Content-Type es el que reporta el almacenamiento para el archivo (normalmente application/octet-stream).
Cada descarga correcta incrementa el contador de la versión, el del proyecto y el registro diario de descargas.
Ejemplo
# Descargar el archivo principal
curl -OJ "https://api.bettersrv.host/services/bres/projects/economyplus/versions/68fa11b2c3d4e5f607182930/download"
# Elegir un archivo concreto de la versión
curl -OJ "https://api.bettersrv.host/services/bres/projects/economyplus/versions/68fa11b2c3d4e5f607182930/download?file=zip"
# Proyecto de pago (requiere licencia)
curl -OJ \
-H "Authorization: Bearer <clerk_token>" \
"https://api.bettersrv.host/services/bres/projects/premium-plugin/versions/68fb22c3d4e5f60718293041/download"
Errores
| Código | Cuerpo | Causa |
|---|---|---|
401 | { "error": "Authentication required" } | Proyecto de pago sin sesión. |
403 | { "error": "Purchase required" } | Sesión válida, pero sin licencia. |
404 | { "error": "Project not found" } | El slug no existe o no es visible. |
404 | { "error": "Version not found" } | La versión no existe o no está listada. |
404 | { "error": "Download URL not found" } | La versión no tiene archivo asociado. |
429 | — | Se superó el límite de descargas. |
502 | { "error": "Failed to fetch file from storage" } | El almacenamiento no devolvió el archivo. |
GET/users/:username
Devuelve el perfil público de un usuario, sus estadísticas y sus proyectos activos más descargados.
Los datos se combinan con Clerk para el avatar y el rol. El usuario debe existir en la base de datos de BRES.
Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
username | string | Nombre de usuario exacto. |
Respuesta 200
{
"username": "dev123",
"avatarUrl": "https://img.clerk.com/...",
"role": "Developer",
"stats": {
"plugins": 5,
"worlds": 2,
"addons": 0,
"resourcepacks": 1,
"totalDownloads": 28450,
"totalLikes": 640,
"averageRating": 4.42
},
"projects": [
{
"_id": "68f2c1a4e9b7d3a12c4f5e60",
"name": "EconomyPlus",
"slug": "economyplus",
"type": "plugin",
"loaders": ["pocketmine"],
"thumbnail": "https://cdn.bettersrv.host/bres/economyplus.webp",
"banner": "https://cdn.bettersrv.host/bres/economyplus-banner.webp",
"shortDescription": "Economía completa para tu servidor",
"categories": ["economy"],
"downloads": 15420,
"likes": 312,
"averageRating": 4.6,
"featured": false,
"verified": true,
"createdAt": "2025-06-12T09:30:00.000Z"
}
],
"createdAt": "2024-01-08T17:45:00.000Z"
}
Notas:
projectsincluye como máximo 10 proyectos activos, ordenados por descargas.- Las estadísticas se calculan sobre esos proyectos.
averageRatingpuede tener decimales; no se redondea.rolees el nombre del rol; si el usuario no tiene rol asignado, esUser.
Ejemplo
curl "https://api.bettersrv.host/services/bres/users/dev123"
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "User not found" } |
500 | { "error": "Internal server error" } |
GET/organizations/:slug
Devuelve el perfil público de una organización con sus estadísticas agregadas.
El slug se busca en los metadatos públicos de la organización en Clerk; no es el ID de Clerk.
Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
slug | string | Slug público de la organización. |
Respuesta 200
{
"id": "org_2abc123def456",
"name": "PixelForge Studio",
"slug": "pixelforge",
"description": "Estudios de plugins y mapas para Bedrock.",
"avatarUrl": "https://img.clerk.com/...",
"bannerUrl": "https://cdn.bettersrv.host/bres/pixelforge-banner.webp",
"websiteUrl": "https://pixelforge.dev",
"discordUrl": "https://discord.gg/pixelforge",
"createdBy": "user_2founder",
"stats": {
"projectCount": 12,
"totalDownloads": 52840,
"totalLikes": 1260,
"memberCount": 5
}
}
projectCount, totalDownloads y totalLikes solo tienen en cuenta proyectos activos.
Errores
| Código | Cuerpo |
|---|---|
500 | { "error": "Internal server error" } |
Una organización inexistente también responde
500en este endpoint. La variante/organization/:slugsí devuelve404.
GET/organizations/:slug/projects
Lista los proyectos activos de una organización, ordenados por descargas.
Parámetros de ruta y consulta
| Parámetro | Ubicación | Tipo | Por defecto | Descripción |
|---|---|---|---|---|
slug | ruta | string | — | Slug de la organización. |
page | query | number | 1 | Página de proyectos. |
limit | query | number | 20 | Proyectos por página. |
Respuesta 200
{
"projects": [
{
"_id": "68f2c1a4e9b7d3a12c4f5e60",
"name": "EconomyPlus",
"slug": "economyplus",
"type": "plugin",
"thumbnail": "https://cdn.bettersrv.host/bres/economyplus.webp",
"shortDescription": "Economía completa para tu servidor",
"downloads": 15420,
"likes": 312,
"averageRating": 4.6,
"categories": ["economy"],
"loaders": ["pocketmine"],
"pricing": {
"type": "free",
"price": { "amount": 0, "currency": "USD" },
"paymentMode": "owner"
}
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 12,
"pages": 1
}
}
Si la organización no existe, el endpoint devuelve una lista vacía; no devuelve 404.
Errores
| Código | Cuerpo |
|---|---|
500 | { "error": "Internal server error" } |
GET/organization/:slug
Perfil extendido de una organización con miembros, proyectos y estadísticas detalladas. Es la variante en singular y complementa a /organizations/:slug; incluye información que ese endpoint no expone.
Parámetros de ruta
| Parámetro | Tipo | Descripción |
|---|---|---|
slug | string | Slug público de la organización. |
Respuesta 200
{
"name": "PixelForge Studio",
"slug": "pixelforge",
"description": "Estudios de plugins y mapas para Bedrock.",
"avatarUrl": "https://img.clerk.com/...",
"bannerUrl": "https://cdn.bettersrv.host/bres/pixelforge-banner.webp",
"websiteUrl": "https://pixelforge.dev",
"discordUrl": "https://discord.gg/pixelforge",
"verified": true,
"featured": false,
"stats": {
"plugins": 7,
"worlds": 3,
"addons": 1,
"resourcepacks": 1,
"cores": 0,
"totalDownloads": 52840,
"totalLikes": 1260,
"averageRating": 4.38,
"memberCount": 5
},
"members": [
{
"role": "admin",
"joinedAt": "2025-02-01T10:00:00.000Z"
},
{
"role": "member",
"joinedAt": "2025-05-14T18:20:00.000Z"
}
],
"projects": [
{
"_id": "68f2c1a4e9b7d3a12c4f5e60",
"name": "EconomyPlus",
"slug": "economyplus",
"type": "plugin",
"thumbnail": "https://cdn.bettersrv.host/bres/economyplus.webp",
"downloads": 15420,
"likes": 312,
"averageRating": 4.6
}
],
"createdAt": "2025-01-20T08:00:00.000Z"
}
Notas:
projectsse limita a 20 proyectos ordenados por descargas.- Las estadísticas por tipo y los totales se calculan sobre esos proyectos, por lo que una organización con más de 20 recursos puede mostrar totales parciales.
- Los miembros no incluyen nombre ni avatar en esta respuesta.
Errores
| Código | Cuerpo |
|---|---|
404 | { "error": "Organization not found" } |
500 | { "error": "Internal server error" } |
Modelos de datos
Proyecto
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | ObjectId del proyecto. |
name | string | Nombre visible. |
slug | string | Identificador único usado en las URLs. |
type | string | plugin, world, addon, resourcepack o core. |
subtype | string | Solo para plugins: plugin o virion. |
loaders | string[] | Loaders compatibles. |
categories | string[] | Categorías del recurso. |
description | string | Descripción en Markdown. |
shortDescription | string | Resumen corto. |
thumbnail | string | URL de la imagen principal. |
banner | string | URL del banner. |
screenshots | string[] | URLs de capturas adicionales. |
author | object | { type, slug }; type es user u organization. |
collaborators | string[] | Usernames de colaboradores. |
dependencies | object[] | Proyectos de los que depende. |
downloads | number | Descargas acumuladas. |
views | number | Vistas acumuladas. |
likes | number | Favoritos acumulados. |
averageRating | number | Media de valoraciones. |
totalRatings | number | Número de valoraciones. |
featured | boolean | Si está destacado en el catálogo. |
verified | boolean | Si el autor está verificado. |
status | string | active, deleted o under_review. |
tags | string[] | Etiquetas gestionadas por el sistema (ver Etiquetas del sistema). |
pluginTest | object | Último resultado de la prueba automática del proyecto. |
sourceUrl | string | Repositorio del código. |
license | string | Licencia declarada. |
pricing | object | Precio del recurso (ver abajo). |
createdAt | string | Fecha de creación (ISO 8601). |
updatedAt | string | Última actualización (ISO 8601). |
Versión
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | ObjectId de la versión. |
projectId | string | ObjectId del proyecto. |
version | string | Número de versión, por ejemplo 2.4.1. |
versionType | string | release, beta o alpha. |
loaders | string[] | Loaders compatibles con esta versión. |
gameVersions | string[] | Versiones de Minecraft Bedrock compatibles. |
changelog | string | Notas del cambio. |
files | object[] | Archivos de la versión. |
dependencies | object[] | Dependencias declaradas. |
fileSize | number | Tamaño del archivo principal en bytes (campo heredado). |
fileExtension | string | Extensión del archivo principal (campo heredado). |
pluginApi | string[] | APIs de PocketMine declaradas en el manifiesto de la versión. |
pluginTest | object | Resultado de la prueba de esta versión en un servidor real. |
downloads | number | Descargas de esta versión. |
status | string | pending_review, listed o rejected. |
releaseDate | string | Fecha de publicación. |
createdAt | string | Fecha de creación. |
updatedAt | string | Última actualización. |
Archivo de versión
| Campo | Tipo | Descripción |
|---|---|---|
_id | string | ObjectId del archivo. |
filename | string | Nombre del archivo. |
downloadUrl | string | URL directa al almacenamiento (solo en el detalle de versión). |
fileSize | number | Tamaño en bytes. |
fileExtension | string | Extensión sin punto. |
fileType | string | direct o archive. |
primary | boolean | Si es el archivo principal. |
sha1 | string | Hash SHA-1. |
sha512 | string | Hash SHA-512. |
Objeto de prueba del plugin
pluginTest resume qué pasó la última vez que el archivo se arrancó en un servidor PocketMine-MP real.
| Campo | Tipo | Descripción |
|---|---|---|
result | string | ok, incompatible, broken, no_manifest o null si no se ha probado. |
reason | string | Motivo legible del fallo; null si el resultado es ok. Sin rutas locales ni datos internos. |
pmVersion | string | Versión de PocketMine-MP usada en la prueba. Solo en el proyecto y en el detalle de versión. |
phpVersion | string | Versión de PHP usada en la prueba. Solo en el proyecto y en el detalle de versión. |
at | string | Fecha de la prueba (ISO 8601). |
{
"result": "incompatible",
"reason": "Incompatible API version (plugin requires one of: 4.0.0)",
"pmVersion": "5.50.0",
"phpVersion": "8.4.27",
"at": "2026-10-27T02:25:16.363Z"
}
Objeto de paginación
| Campo | Tipo | Descripción |
|---|---|---|
page | number | Página actual, desde 1. |
limit | number | Elementos por página. |
total | number | Total de elementos. |
pages | number | Total de páginas. |
Precios
{
"type": "free",
"price": {
"amount": 0,
"currency": "USD"
},
"paymentMode": "owner",
"paymentNotes": "Instrucciones opcionales del autor"
}
| Campo | Valores | Descripción |
|---|---|---|
type | free, paid | Si el recurso es gratuito o de pago. |
price.amount | number | Importe. |
price.currency | string | Moneda ISO 4217. |
paymentMode | bres, owner | Si el pago lo gestiona BRES o el autor. |
paymentNotes | string | Notas opcionales para el comprador. |
Etiquetas del sistema
BRES prueba automáticamente cada versión de plugin en un servidor PocketMine-MP 5.50 real y publica el veredicto. Sirve para avisar antes de descargar: un plugin marcado no va a funcionar tal cual en un servidor actual.
Las etiquetas viven en tags (proyecto) y el detalle en pluginTest. Solo hay dos etiquetas públicas:
| Etiqueta | Significado |
|---|---|
incompatible | El plugin declara una API de PocketMine que PM5 no acepta (3.x o 4.x), así que se niega a cargar. |
broken | Con API válida, el plugin falla al cargar o activar: manifiesto inválido, excepción, main class inexistente o cierre del servidor. |
Cómo interpretarlas
tags: []— o el plugin funciona (pluginTest.result=ok), o no se ha probado todavía. ConsultapluginTest.resultpara distinguirlo.pluginTest.result=no_manifest— el archivo no tieneplugin.yml(típicamente un virión). No lleva etiqueta porque no es un plugin instalable.- Sin etiqueta y sin resultado
ok— fallos que no se pueden atribuir al plugin: dependencia no instalada en el servidor de pruebas, configuración obligatoria o licencia. Quedan pendientes de revisión manual a propósito.
Filtrar por etiqueta:
# Plugins incompatibles con PocketMine-MP 5
curl "https://api.bettersrv.host/services/bres/projects/search?tag=incompatible&type=plugin"
# Plugins que fallan al cargar
curl "https://api.bettersrv.host/services/bres/projects/search?tag=broken&type=plugin"
El motivo (pluginTest.reason) ya viene saneado: no incluye rutas del servidor de pruebas ni prefijos de log, así que se puede mostrar tal cual en una interfaz.
Enumeraciones
Tipos de recurso
| Valor | Etiqueta |
|---|---|
plugin | Plugin |
world | Mundo |
addon | Addon |
resourcepack | Resource Pack |
core | Core |
Loaders
| Tipo | Loaders válidos |
|---|---|
plugin | pocketmine, nukkit, waterdogpe |
world | vanilla, pocketmine, nukkit |
addon | vanilla |
resourcepack | vanilla |
core | pocketmine, nukkit, waterdogpe, vanilla |
Categorías
| Tipo | Valores |
|---|---|
plugin y addon | economy, gamemode, mechanics, utilities, admin, protection, chat, world, misc, tools, security, spawns, statistics |
world | survival, aventura, minijuegos, terror, mapas, parkour, desafios |
resourcepack | realistic, cartoon, medieval, modern, sci-fi, fantasy, low-res, high-res, pvp-friendly, anime |
core | hcf, survival, factions, skyblock, prison, kitpvp, bedwars, lobby, full-server, practice, semi-vanilla |
Tipos de versión
| Valor | Descripción |
|---|---|
release | Versión estable. |
beta | Versión de prueba. |
alpha | Versión temprana. |
Estados de versión
| Valor | Visible públicamente |
|---|---|
listed | Sí |
pending_review | No, salvo dueño, colaborador o moderador. |
rejected | No, salvo dueño, colaborador o moderador. |
Extensiones de archivo
| Tipo | Extensiones |
|---|---|
plugin | phar, zip |
world | mcworld, schem, schematic, zip |
addon | mcaddon, mcpack, zip |
resourcepack | mcpack, zip |
core | phar, zip |
Cada versión admite hasta 5 archivos.
Resultado de la prueba automática
| Valor | Etiqueta asociada | Significado |
|---|---|---|
ok | — | Cargó y activó sin errores. |
incompatible | incompatible | La API declarada no es compatible con PocketMine-MP 5. |
broken | broken | Falla al cargar o activar por un error propio del plugin. |
no_manifest | — | El archivo no declara plugin.yml (virión). |
null | — | Sin probar. |
Motivos de valoración
1 estrella
broken— No funciona correctamentemalware— Contiene malware o código maliciosomisleading— La descripción no coincide con el recursopoor_quality— Calidad muy bajano_support— No tiene soporte ni actualizacionesstolen— Contenido robado o plagiado
2 estrellas
buggy— Tiene muchos bugs y errorespoor_docs— Documentación insuficiente o inexistentemissing_features— Le faltan funciones prometidaspoor_performance— Consume muchos recursos o causa laghard_config— Muy difícil de configurar
3 estrellas
average— Cumple su función pero nada especialneeds_improvement— Necesita mejoras importantesdecent— Decente pero tiene margen de mejoraincomplete— Parece incompleto o en desarrollooutdated— Funciona pero está desactualizado
4 estrellas
good— Buen recurso, funciona bienuseful— Muy útil para mi servidorwell_made— Bien hecho y bien estructuradogood_docs— Buena documentación y configuracióngood_support— Buen soporte por parte del autoractive_dev— Desarrollo activo con actualizaciones
5 estrellas
excellent— Excelente en todos los aspectosmust_have— Imprescindible para cualquier servidorbest_in_class— El mejor en su categoríagreat_support— Soporte excepcional del autorinnovative— Innovador y único en su tipo
Recursos
Si encuentras un comportamiento que no coincide con esta documentación, repórtalo al equipo de BRES indicando la ruta, la petición exacta y la respuesta recibida.