Ir al contenido

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.

  1. Coloca en tu sala el complemento Web API de variables. Solo el dueño de la sala puede ver y guardar sus claves.
  2. Ábrelo y pulsa Generar en la clave de lectura, en la de escritura o en las dos.
  3. Pulsa Listo. Hasta ese momento las claves no valen.
  4. 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.

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.

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): cabecera X-Wired-Read-Key con tu clave de lectura.
  • Escrituras (PUT, PATCH, DELETE y el borrado masivo): cabecera X-Wired-Write-Key con 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 llevan ETag.
GET /api/public/rooms/12345/variables/user/puntos/users/678
X-Wired-Read-Key: tu_clave_de_lectura

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.

Á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.

{
"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ó.

PATCH /api/public/rooms/12345/variables/user/puntos/users/678
X-Wired-Write-Key: tu_clave_de_escritura
Content-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 superan 9007199254740992 pasan por coma flotante y pierden dígitos: 9007199254740993 se guarda como 9007199254740992.
  • No valen los decimales (1.5), los booleanos, el texto con espacios (" 1") ni las cifras fuera de rango: dan 400 request-failed-non-200.
  • Si falta el campo value, está vacío o es null: 400 wired.variables.invalid_value.
  • Un JSON mal formado da 400 con el texto «Bad JSON».
GET /api/public/rooms/12345/variables/user/puntos/users?order_by=value&order_dir=desc&size=20
X-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/batch
X-Wired-Read-Key: tu_clave_de_lectura
X-Wired-Write-Key: tu_clave_de_escritura
Content-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, PATCH o DELETE), path ({tipo}/{id}, con o sin barra delante) y, en PUT y PATCH, un body con el value. El op_id es 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; un value mal formado en cualquier operación, 400 request-failed-non-200 para el lote entero.
  • No hay lotes para las variables globales.

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/678
X-Wired-Write-Key: tu_clave_de_escritura
Content-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.

POST /api/public/rooms/12345/variables/bulk-delete
X-Wired-Write-Key: tu_clave_de_escritura
Content-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.

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.

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.

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 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.