API pública de variables
Tu sala puede ofrecer una API pública para leer y cambiar sus variables desde fuera del juego: una página web con la clasificación, un bot que reparte puntos, un panel para ti. Sigue el mismo contrato que la API de variables wired del hotel oficial: mismas rutas, mismas cabeceras y mismos códigos de error.
Se activa con un complemento y se protege con claves. Si no quieres escribir las peticiones a mano, el Explorador de variables las hace por ti.
Cómo se activa
Sección titulada «Cómo se activa»- Coloca en tu sala el complemento Web API de variables. Solo el dueño de la sala puede ver y guardar sus claves.
- Ábrelo y pulsa Generar en la clave de lectura, en la de escritura o en las dos.
- Pulsa Listo. Hasta ese momento las claves no valen.
- Manda las claves en las cabeceras de tus peticiones.
La API funciona aunque la sala esté vacía y descargada. Con la sala descargada lee y escribe lo guardado y no corre ningún wired; con la sala cargada trabaja en vivo, y las escrituras hacen saltar el causante Cambio de variable con origen Externa.
Qué variables se ven
Sección titulada «Qué variables se ven»La API trabaja con las variables de las cajas de tu sala que sean de usuario, de furni o globales y tengan una de estas dos disponibilidades:
- Permanente.
- Permanente, compartida entre salas.
No entran las variables temporales, las de contexto, las heredadas, las internas ni las que brotan de un complemento. Se piden por su nombre, sin distinguir mayúsculas.
Con la sala cargada, las permanentes son las que había al cargarla: una variable nueva, o una a la que le cambias el nombre, no se ve en la API hasta que la sala se vacía y se vuelve a cargar. Recoger una caja se nota al momento, y las compartidas entre salas se ven siempre al instante.
El dato vive en un portador: la persona, la mascota, el bot o el furni que tiene la variable. Las variables globales no tienen portador: son de la sala.
Cómo se hace una petición
Sección titulada «Cómo se hace una petición»Todas las rutas cuelgan de /api/public/rooms/{sala}, donde {sala} es el número de tu sala. La dirección
del servidor de la API es la que te dé el hotel, y siempre por HTTPS. Los ejemplos de esta página se escriben
como líneas de petición HTTP, sin la dirección.
- Lecturas (
GET): cabeceraX-Wired-Read-Keycon tu clave de lectura. - Escrituras (
PUT,PATCH,DELETEy el borrado masivo): cabeceraX-Wired-Write-Keycon tu clave de escritura. La clave de escritura no sirve para leer. - Los cuerpos van en JSON, con
Content-Type: application/json. El valor de una escritura suelta también se acepta como formulario (application/x-www-form-urlencoded,value=150). - Las respuestas son JSON con
Content-Type: application/json; charset=utf-8, y los errores son{"error":"<código>"}. Los nombres de la ruta no distinguen mayúsculas, pero los tipos de portador (users,furni…) sí. - La API acepta peticiones desde páginas web (CORS), responde a
HEAD, y las respuestas llevanETag.
GET /api/public/rooms/12345/variables/user/puntos/users/678X-Wired-Read-Key: tu_clave_de_lecturaLas rutas
Sección titulada «Las rutas»Todas las rutas de la tabla van detrás de /api/public/rooms/{sala}. {ámbito} es user o furni,
{variable} el nombre de la variable, {tipo} el tipo de portador (ver más abajo) e {id} el número del
portador.
| Método y ruta | Clave | Qué hace |
|---|---|---|
GET /variables |
lectura | Los nombres de las variables: {"users":[…],"furni":[…],"global":[…]} |
GET /variables/{ámbito}/{variable}/{tipo}/{id} |
lectura | El valor de esa variable en ese portador |
PUT /variables/{ámbito}/{variable}/{tipo}/{id} |
escritura | Da la variable: la crea o la reemplaza |
PATCH /variables/{ámbito}/{variable}/{tipo}/{id} |
escritura | Cambia el valor, solo si ya existe |
DELETE /variables/{ámbito}/{variable}/{tipo}/{id} |
escritura | Quita la variable al portador |
GET /variables/{ámbito}/{variable}/{tipo} |
lectura | Lista paginada de quién tiene la variable |
GET /variables/{ámbito}/{variable}/{tipo}/count |
lectura | Cuántos la tienen: {"count":n} |
POST /variables/{ámbito}/{variable}/batch |
según las operaciones | Hasta 50 operaciones de una vez |
POST /variables/bulk-delete |
escritura | Borrado masivo |
GET /variables/global/{variable} |
lectura | El valor de una variable global |
PATCH /variables/global/{variable} |
escritura | Cambia una variable global |
GET /variables_profile/user/users?name=… |
lectura | El perfil de un usuario, buscado por nombre |
GET /variables_profile/user/users?unique_id=… |
lectura | El perfil de un usuario, buscado por su unique_id |
GET /variables_profile/user/{tipo}/{id} |
lectura | El perfil de un usuario, mascota o bot |
PATCH /variables_profile/user/{tipo}/{id} |
escritura | Cambia o quita varias variables de un portador |
DELETE /variables_profile/user/{tipo}/{id} |
escritura | Le quita todas sus variables de la sala |
GET /variables_profile/furni/{tipo}/{id} |
lectura | El perfil de un furni |
PATCH /variables_profile/furni/{tipo}/{id} |
escritura | Cambia o quita varias variables de un furni |
GET /variables_profile/global |
lectura | Todas las variables globales |
PATCH /variables_profile/global |
escritura | Cambia varias variables globales |
Las rutas o los métodos que no existen —por ejemplo PUT o DELETE sobre una variable global, o DELETE de
un perfil de furni— responden 404 con una página HTML, no con JSON. Una barra final no cuenta.
Tipos de portador
Sección titulada «Tipos de portador»| Ámbito | Tipo | Portador | Su {id} |
|---|---|---|---|
user |
users |
Usuarios | El id del usuario |
user |
pets |
Mascotas | El id de la mascota |
user |
bots |
Bots | El id del bot |
furni |
furni |
Furni de suelo | El id del furni |
furni |
furni-bc |
Furni de suelo de Builders Club (BC) | El id del furni |
furni |
wall-items |
Furni de pared | El id del furni |
furni |
wall-items-bc |
Furni de pared de Builders Club (BC) | El id del furni |
El tipo tiene que coincidir con el del portador: un furni normal pedido como furni-bc no existe para la
API. Un ámbito con un tipo que no es suyo (user con furni) da wired.variables.invalid_target.
Cómo es una variable en la respuesta
Sección titulada «Cómo es una variable en la respuesta»{ "value": "120", "creation_time": "2026-10-15T02:14:43.281Z", "update_time": "2026-10-15T02:20:05.497Z"}El value va como texto, porque es un entero de 64 bits. Las fechas van en hora universal (UTC) con
milisegundos: creation_time es cuando se le dio la variable al portador y update_time, la última vez que
cambió.
Escribir un valor
Sección titulada «Escribir un valor»PATCH /api/public/rooms/12345/variables/user/puntos/users/678X-Wired-Write-Key: tu_clave_de_escrituraContent-Type: application/json
{ "value": "150" }| Método | Qué hace |
|---|---|
PUT |
Da la variable. Si el portador ya la tenía, la reemplaza y su fecha de creación pasa a ser la del momento de la escritura. A un usuario, mascota o bot solo se le puede dar si ya tiene alguna variable en la sala (si no, wired.variables.user_not_participating); un furni tiene que estar en la sala (si no, wired.variables.entity_not_found) |
PATCH |
Cambia el valor y conserva la fecha de creación. Si el portador no la tiene, wired.variables.not_found |
DELETE |
Quita la variable. Responde 204 sin cuerpo; si no la tenía, wired.variables.not_found |
El valor de una variable que no guarda valor se acepta y se guarda igual. Las variables globales no se dan ni
se quitan —existen siempre—: solo se leen y se cambian con PATCH, y si nunca se les dio valor valen "0".
Qué valores valen. Un entero de 64 bits con signo: de -9223372036854775808 a 9223372036854775807.
- Mándalo como texto:
"150","-3","+3". Un número JSON también sirve, pero los que superan9007199254740992pasan por coma flotante y pierden dígitos:9007199254740993se guarda como9007199254740992. - No valen los decimales (
1.5), los booleanos, el texto con espacios (" 1") ni las cifras fuera de rango: dan 400request-failed-non-200. - Si falta el campo
value, está vacío o esnull: 400wired.variables.invalid_value. - Un JSON mal formado da 400 con el texto «Bad JSON».
Listados y recuentos
Sección titulada «Listados y recuentos»GET /api/public/rooms/12345/variables/user/puntos/users?order_by=value&order_dir=desc&size=20X-Wired-Read-Key: tu_clave_de_lectura| Parámetro | Valores | De fábrica |
|---|---|---|
page |
Un entero desde 1 | 1 |
size |
De 1 a 100 (si pides más, son 100) | 50 |
order_by |
value, creation_time o update_time |
creation_time |
order_dir |
asc o desc |
asc |
{ "items": [ { "variable": { "value": "120", "creation_time": "2026-10-15T02:14:43.281Z", "update_time": "2026-10-15T02:20:05.497Z" }, "user": { "unique_id": "hhht-…", "name": "Jugador", "id": 678 } } ], "page": 1, "size": 50}Cada elemento trae la variable y, según el tipo, su portador en la clave user, pet, bot, furni,
furni_bc, wall_item o wall_item_bc: los usuarios con unique_id, name e id; las mascotas y los bots
con id y name; los furnis solo con id. Una página que no existe devuelve items vacío. El unique_id es
un identificador de cada usuario que empieza por hhht-.
/count devuelve cuántos portadores tiene la variable, y el número puede ir con retraso: se guarda entre
20 segundos y 10 minutos, más tiempo cuantos más portadores haya.
Un lote reúne hasta 50 operaciones sobre una misma variable en una sola petición.
POST /api/public/rooms/12345/variables/user/puntos/batchX-Wired-Read-Key: tu_clave_de_lecturaX-Wired-Write-Key: tu_clave_de_escrituraContent-Type: application/json
{ "requests": [ { "op_id": "a", "method": "GET", "path": "users/678" }, { "method": "PATCH", "path": "users/999", "body": { "value": "10" } } ]}{ "results": [ { "status": 200, "body": { "value": "120", "creation_time": "…", "update_time": "…" }, "error": null, "op_id": "a" }, { "status": 404, "body": null, "error": { "code": "wired.variables.not_found", "message": "wired.variables.not_found" }, "op_id": null } ]}- Cada operación lleva
method(GET,PUT,PATCHoDELETE),path({tipo}/{id}, con o sin barra delante) y, enPUTyPATCH, unbodycon elvalue. Elop_ides opcional y vuelve como texto. - Los resultados vienen en el mismo orden, cada uno con su propio
status. La respuesta es 200 aunque alguna operación falle: el fallo va dentro de su resultado. - La clave de lectura hace falta solo si hay alguna lectura, y la de escritura solo si hay alguna
operación que no lo sea. Si falta la cabecera de una clave necesaria, la respuesta es
wired.variables.key_missing; si está pero no coincide,wired.variables.key_invalid. - Un lote vacío es
wired.variables.batch_empty; más de 50,wired.variables.batch_limit_exceeded; unvaluemal formado en cualquier operación, 400request-failed-non-200para el lote entero. - No hay lotes para las variables globales.
Perfiles
Sección titulada «Perfiles»El perfil de un portador reúne todas sus variables de la sala. Un usuario, una mascota o un bot tiene perfil si tiene al menos una variable; un furni, si está en la sala; la sala (las globales) siempre.
{ "user": { "id": 678, "name": "Jugador", "unique_id": "hhht-…" }, "variables": { "puntos": { "value": "120", "creation_time": "…", "update_time": "…" } }}Solo trae las variables que el portador tiene. El perfil de una mascota o un bot lleva pet o bot en vez de
user, y el de un furni, furni, furni_bc, wall_item o wall_item_bc; el global, solo variables.
Para cambiar varias variables a la vez, PATCH con un objeto variables; un valor la da o la cambia, y
null la quita:
PATCH /api/public/rooms/12345/variables_profile/user/users/678X-Wired-Write-Key: tu_clave_de_escrituraContent-Type: application/json
{ "variables": { "puntos": "20", "ganador": null } }Responde con el perfil entero ya cambiado. Un nombre de variable que no existe, o un objeto vacío, es
wired.variables.invalid_target. En el perfil global no se puede quitar nada: un null da
wired.variables.operation_not_allowed. Un DELETE de perfil quita de golpe todas las variables de ese
usuario, mascota o bot en la sala.
Borrado masivo
Sección titulada «Borrado masivo»POST /api/public/rooms/12345/variables/bulk-deleteX-Wired-Write-Key: tu_clave_de_escrituraContent-Type: application/json
{ "variables": ["puntos", "vidas"] }Vacía de golpe los valores de las variables que nombres —las de usuario y las de furni, no las globales—, para
todos los portadores. Las variables siguen en la sala; lo que se borra es lo que cada uno tenía. Solo
funciona si en el complemento está marcada la casilla Permitir eliminación masiva; si no,
wired.variables.bulk_delete_not_enabled. Una lista vacía es wired.variables.bulk_delete_empty, y un nombre
que no es una variable de usuario ni de furni de la sala, wired.variables.bulk_delete_invalid_variable. Si sale bien, responde 204 sin cuerpo.
Errores
Sección titulada «Errores»Una respuesta de error es un JSON con el código: {"error":"wired.variables.not_found"}.
| Código | HTTP | Cuándo |
|---|---|---|
wired.variables.key_missing |
403 | La sala no tiene clave de ese tipo: no hay complemento, o dejaste ese campo vacío. En un lote, también si falta la cabecera de una clave necesaria |
wired.variables.key_invalid |
403 | La sala tiene clave de ese tipo y la cabecera falta o no coincide |
wired.variables.invalid_target |
400 | La ruta o los parámetros no encajan: tipo de portador que no es del ámbito, page o size igual a 0 (un size mayor de 100 se queda en 100), order_by u order_dir con un valor que no existe, operación de lote mal formada, perfil sin variables |
wired.variables.invalid_value |
400 | Falta el valor, está vacío o es null |
request-failed-non-200 |
400 | El valor no es un entero válido, o un campo trae un tipo que no vale |
wired.variables.not_found |
404 | La variable no existe en la sala, el portador no la tiene o su id no corresponde a ese tipo |
wired.variables.entity_not_found |
404 | No hay perfil: usuario, mascota o bot sin variables en la sala, furni que no está en la sala, o un nombre que no existe |
not-found |
404 | La sala no existe, o un id, page o size no es un entero sin signo (-1 o abc también dan not-found) |
wired.variables.user_not_participating |
403 | Un PUT a un usuario, mascota o bot que no tiene ninguna variable en la sala |
wired.variables.operation_not_allowed |
403 | Quitar una variable global |
wired.variables.bulk_delete_not_enabled |
403 | Borrado masivo sin la casilla marcada |
wired.variables.bulk_delete_empty |
400 | Borrado masivo sin ningún nombre |
wired.variables.bulk_delete_invalid_variable |
400 | Un nombre que no es una variable de usuario ni de furni de la sala |
wired.variables.batch_empty |
400 | Lote sin operaciones |
wired.variables.batch_limit_exceeded |
400 | Lote de más de 50 operaciones |
wired.variables.too_many_requests |
429 | Te pasaste del límite (ver abajo) |
wired.variables.internal_error |
500 | Fallo interno |
Las comprobaciones se hacen siempre en el mismo orden: primero el JSON y la forma de la ruta, luego el valor, luego que la sala exista, luego las claves, luego la paginación y, al final, la variable. Por eso un valor mal formado da su error antes que una clave que falta.
Límites
Sección titulada «Límites»Los límites son por sala: cuentan las peticiones válidas (con clave correcta) que lleguen a tu sala, vengan de quien vengan.
| Grupo | Qué cuenta | Por minuto | En 10 segundos |
|---|---|---|---|
| Lecturas simples | Nombres de variables, un valor, una variable global | 300 | 60 |
| Listados | Listados y recuentos | 120 | 20 |
| Perfiles | Leer un perfil y buscar un usuario | 120 | 20 |
| Escrituras | PUT, PATCH y DELETE de un valor, PATCH de una global, DELETE de un perfil |
120 | 30 |
| Borrado masivo | bulk-delete |
10 | 5 |
| Lotes | Los lotes y los PATCH de perfil |
30 | sin límite propio |
Además, las escrituras que van dentro de un lote o de un PATCH de perfil gastan un presupuesto aparte de
500 por minuto.
Al pasarte, la API responde 429 con wired.variables.too_many_requests y una cabecera Retry-After con
los segundos que faltan para volver a intentarlo. Espera ese tiempo en vez de insistir.
Seguridad de las claves
Sección titulada «Seguridad de las claves»Una clave es como una contraseña de tu sala:
- Con la clave de lectura se ven todas las variables permanentes de tu sala y quién las tiene, con los nombres de usuario.
- Con la clave de escritura se puede cambiar o borrar cualquier valor. Si de esos valores salen recompensas, puntuaciones o accesos, quien tenga la clave puede dárselos.
Qué conviene hacer:
- No las compartas ni las pegues en un sitio que vea todo el mundo: una página web, un repositorio público, una captura de pantalla. Como la API admite llamadas desde páginas web, una clave escrita en una página la ve cualquiera que la abra; si la herramienta es pública, haz las peticiones desde un servidor tuyo.
- Pide solo lo que necesitas. Si la herramienta solo lee, deja vacía la clave de escritura.
- Deja apagado el borrado masivo salvo que lo necesites de verdad, y pruébalo antes en una sala de prueba con variables de prueba.
- Cambia la clave si sospechas que se ha visto: abre el complemento, pulsa Regenerar y Listo. La clave anterior deja de valer en el acto.
- Cierra lo que no uses. Con las dos claves vacías, la API de tu sala rechaza todo. Recoger el complemento o vender la sala también borra las claves.
- Protege las pilas que no deban activarse desde fuera. Una escritura por la API hace saltar Cambio de variable con origen Externa; desmarca esa casilla en las pilas de recompensa si no quieres que nadie con una clave las dispare.
El Explorador de variables
Sección titulada «El Explorador de variables»El Explorador de variables es una aplicación web aparte que habla con esta API por ti, para consultar y cambiar las variables de tu sala desde el navegador sin escribir ninguna petición.
Se entra con el ID de la sala y tu clave de lectura; la de escritura es opcional. Sin ella, el explorador funciona en modo Solo lectura; con ella, en modo Escritura. El explorador comprueba la conexión pidiendo la lista de variables, y si falla enseña el código de error.
| Pestaña | Qué hace |
|---|---|
| Global | Las variables globales de la sala, con su valor, que puedes cambiar |
| Usuarios y Furnis | Quién tiene cada variable. Eliges la variable y el subtipo (usuarios, mascotas o bots; furni de suelo, de pared o sus versiones BC), y ves una tabla ordenable por valor, creación o última actualización, con páginas de 10, 25, 50 o 100 filas |
| Buscar | Abre el perfil de un usuario por su ID, su nombre o su ID único, el de una mascota o un bot por su ID, o el de un furni por su ID del juego |
| Borrado masivo | Elige variables de usuario y de furni y vacía sus valores, con confirmación. Requiere la casilla Permitir eliminación masiva del complemento |
- Cambiar un valor: haz clic en él, escribe el número y pulsa Intro para guardar; Escape, o hacer clic fuera, lo cancela. Solo se aceptan enteros.
- Operaciones en lote: activa el interruptor y los cambios y borrados de la página se quedan en cola hasta que pulses Guardar, que los manda juntos (hasta 50). Lo que falle se queda en la cola con su error.
- Perfil: al abrir un portador ves todas sus variables. Puedes dar una variable nueva, cambiar o quitar las que tiene, y borrar el perfil entero de un usuario, una mascota o un bot.
- Red: un panel con las últimas peticiones que ha hecho el explorador, con sus cabeceras y respuestas, y un compositor para mandar tus propias peticiones.
- Recargar variables vuelve a pedir la lista; Desconectar cierra la sesión.
El explorador espera solo cuando se acerca a los límites de la API, así que no hace falta que cuentes peticiones. Los números salen con puntos de millar y las fechas, en la hora de tu navegador.