API e integraciones
Cada sala tiene una API HTTP. Inicia y detén temporizadores, muestra mensajes, añade tiempo y lee la escaleta desde un script, un sistema de control de show o cualquier cosa capaz de hacer una petición web. Un webhook avisa a tu sistema cuando un temporizador empieza o termina.


Primeros pasos
Crea una clave de API
Abre Claves de API y haz clic en Crear clave. Cópiala ahora: solo se muestra una vez. Consulta Team y claves de API.
Encuentra el id de la sala
Es la parte que va después de /timer/r/ en la dirección de la sala de control, por ejemplo https://cliqer.io/timer/r/<room>/control.
Haz una llamada
Envía la clave con cada petición. ping comprueba que la sala existe.
La API controla la misma sala que la sala de control: una llamada desde tu herramienta se ve en todas las pantallas a la vez.
Peticiones
Todas las llamadas son https://cliqer.io/api/timer/v1/<room>/<action>. Funcionan GET, POST, PUT y PATCH. Los parámetros van en la query string, o en un cuerpo JSON con POST, PUT y PATCH; si ambos traen uno, prevalece el cuerpo. Los guiones en el nombre de la acción también funcionan, así que add-time equivale a add_time. /api/timer/v0/ acepta las mismas llamadas.
Envía la clave de una de estas formas, que se comprueban en este orden:
| Dónde | Ejemplo |
|---|---|
Cabecera Authorization | Authorization: Bearer <key> |
Cabecera x-api-key | x-api-key: <key> |
Parámetro de consulta api_key | ?api_key=<key>. Evítalo siempre que puedas: las direcciones acaban en los registros. |
curl -X POST https://cliqer.io/api/timer/v1/<room>/add_time \
-H "Authorization: Bearer $CLIQER_KEY" \
-H "content-type: application/json" \
-d '{"timer_id": "<timer>", "amount": "2m"}'
const res = await fetch('https://cliqer.io/api/timer/v1/<room>/add_time', {
method: 'POST',
headers: { 'authorization': `Bearer ${process.env.CLIQER_KEY}`, 'content-type': 'application/json' },
body: JSON.stringify({ timer_id: '<timer>', amount: '2m' }),
})
const { ok, message, data } = await res.json()
import os, requests
r = requests.post(
"https://cliqer.io/api/timer/v1/<room>/add_time",
headers={"Authorization": f"Bearer {os.environ['CLIQER_KEY']}"},
json={"timer_id": "<timer>", "amount": "2m"},
)
print(r.json())
Claves y permisos
La clave de API de tu cuenta puede hacerlo todo en las salas de las que eres propietario. Una sala también puede tener sus propias claves, cada una con algunos de estos tres permisos:
| Permiso | Permite |
|---|---|
| Lectura | Las acciones get_ y export. |
| Dirección del show | Transporte, tiempo, blackout, En el aire y mensajes. |
| Edición | Eliminar, importar, intents en bruto y el webhook. |
Una llamada que necesita un permiso que la clave no tiene recibe 401. El secreto de una clave de sala se muestra una sola vez, al crearla. Para usar la API necesitas que tu plan la incluya, consulta Planes y límites.
Acciones
timer_id elige un temporizador por su id; index lo elige por posición, contando desde 1. Si se envían ambos, prevalece timer_id. Omite los dos para actuar sobre el temporizador actual.
| Acción | Devuelve |
|---|---|
get_room | Título, fecha, zona horaria y ajustes. |
get_status | Lo que se está ejecutando ahora. |
get_timers | La escaleta. |
get_messages | Los mensajes. |
get_questions | Las preguntas del público. |
get_connections | Los dispositivos conectados. |
get_logs | El registro de la sala. limit, offset. |
export | La sala completa como descarga cliqer-timer-<room>.json. |
| Acción | Parámetros | Qué hace |
|---|---|---|
start, start_or_stop | timer_id o index | Lo inicia, o lo alterna. |
stop | Detiene el temporizador en marcha. | |
start_fresh | timer_id o index | Lo inicia desde la duración completa. |
select | timer_id o index (se necesita uno) | Lo convierte en el actual sin iniciarlo. |
reset | timer_id o index, autostart, from_memory | Lo devuelve a la duración completa. |
next, previous | autostart, from_memory | Avanza o retrocede por la escaleta. |
add_time, subtract_time | timer_id, amount | Cambia la duración de un temporizador. |
jump | amount | Hace saltar el temporizador en marcha esa cantidad. |
set_remaining | amount | Fija el tiempo restante. |
flash | count, message | Hace parpadear las pantallas. |
stop_flash | Detiene el parpadeo. | |
blackout | on | Activa o desactiva el blackout. |
blackout_on, blackout_off, toggle_blackout | Lo mismo, sin parámetro. | |
focus | on | Destaca el mensaje. |
on_air | on | El letrero En el aire. |
show_message | message_id, focus | Muestra un mensaje. |
toggle_message | message_id | Lo muestra, o lo oculta si ya se ve. |
hide_message | Oculta el mensaje. |
| Acción | Parámetros | Qué hace |
|---|---|---|
delete_timer | timer_id | Elimina un temporizador. |
delete_message | message_id | Elimina un mensaje. |
delete_question | question_id | Elimina una pregunta. |
import_csv | csv, replace, date_line, columns, header_row, rows | Importa filas, como en Importar desde Stagetimer. |
intent | {"intent": {...}} | Cualquier cambio que pueda hacer la sala de control, en JSON. |
webhook | url | Configura o borra el webhook. Más abajo tienes los detalles. |
| Acción | Parámetros | Qué hace |
|---|---|---|
ping | Responde pong si la sala existe. | |
submit_question | text (hasta 1000 caracteres), name (hasta 100) | Envía una pregunta del público. |
vote_question | question_id | Vota una pregunta. |
Las cantidades son 30s, 5m, 1h, 250ms o un número de segundos sin unidad. seconds sirve en lugar de amount, y un signo menos va hacia atrás. Los interruptores como on, autostart y replace interpretan 0, false, off y no como desactivado y cualquier otro valor como activado. Omite on en blackout para alternarlo.
Respuestas
Todas las respuestas son JSON: {"ok": true, "message": "<action>", "data": ...} si todo va bien, {"ok": false, "message": "...", "code": "..."} si falla.
| Estado | Mensaje | Motivo |
|---|---|---|
| 400 | Either timer_id OR index are required | select sin temporizador. |
| 400 | amount is required, like 30s, 5m or 1h | Cantidad ausente o ilegible. |
| 400 | Refused: invalid | La sala no ha podido aplicarlo. |
| 401 | Access Denied: Valid API key required | Sin clave, una clave incorrecta o falta un permiso. |
| 403 | The API is not in this plan | El plan de la sala no incluye API. |
| 403 | Refused: forbidden, Refused: readOnly, Refused: limitReached | No permitido, una sala de solo lectura o un límite del plan. |
| 404 | Room not found, Unknown action <name>, Timer not found | Comprueba el id de la sala, la acción o el id del temporizador. |
| 409 | Refused: staleEpoch | La sala cambió mientras se procesaba la llamada. Vuelve a enviarla. |
| 429 | Too many requests. Please try again later. | Límite de frecuencia. |
| 503 | Refused: authorityOffline | La sala está en la papelera. Restáurala primero. |
Límite de frecuencia: 100 llamadas por minuto por clave; las llamadas sin clave se cuentan por dirección. Cada respuesta incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset (segundos hasta que vuelve a empezar el minuto).
Webhooks
Configura la dirección
Llama a webhook con una url https. La respuesta contiene un secret que empieza por whsec_. Guárdalo: solo se muestra una vez.
Recibe eventos
Cliqer Timer envía un POST a esa dirección cuando ocurre algo en la sala.
Comprueba la firma
Verifica cada petición antes de confiar en ella.
Bórralo
Llama a webhook sin url. Se eliminan tanto la dirección como su secreto.
| Evento | Cuándo |
|---|---|
timerStarted | Un temporizador se inicia. |
timerEnded | Un temporizador llega a cero. |
wrapUpYellow | Un temporizador llega a su punto de aviso amarillo. |
wrapUpRed | Un temporizador llega a su punto de aviso rojo. |
messageShown | Se muestra un mensaje. |
El cuerpo es {"event", "roomId", "timestamp", "payload"}. La cabecera x-cliqer-timestamp contiene la hora Unix en segundos, y x-cliqer-signature contiene sha256= seguido del HMAC-SHA256 en hexadecimal de <timestamp>.<body> con tu secreto como clave.
# Recompute the signature of a saved body.
printf '%s.%s' "$TIMESTAMP" "$(cat body.json)" \
| openssl dgst -sha256 -hmac "$WHSEC" -hex
import { createHmac, timingSafeEqual } from 'node:crypto'
export function verify(rawBody: string, timestamp: string, signature: string, secret: string) {
const want = `sha256=${createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')}`
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) < 300
return fresh && want.length === signature.length && timingSafeEqual(Buffer.from(want), Buffer.from(signature))
}
import hashlib, hmac, time
def verify(raw_body: bytes, timestamp: str, signature: str, secret: str) -> bool:
mac = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256)
fresh = abs(time.time() - int(timestamp)) < 300
return fresh and hmac.compare_digest("sha256=" + mac.hexdigest(), signature)
Firma el cuerpo en bruto exactamente como llegó, antes de analizar el JSON. La ventana de cinco minutos la decides tú; evita que se reenvíe una petición antigua.
La entrega es un único intento con un tiempo de espera de 5 segundos. No se siguen redirecciones, y se descarta cualquier dirección que resuelva a una red privada. Si un evento perdido te importa, consulta get_status para ponerte al día.
Enlaces cortos
GET https://cliqer.io/api/timer/link/<code> convierte el código de un enlace corto en su sala: {"ok": true, "data": {"roomId", "link"}}, o 404 Link not found si el código es desconocido, se ha revocado o ha caducado, o si la contraseña es incorrecta. Para un enlace con contraseña, envíala en la cabecera x-link-password, nunca en la dirección.
Companion y Stream Deck
No existe un módulo de Companion ni un plugin de Stream Deck para las salas de Cliqer Timer. El módulo Generic HTTP de Bitfocus Companion puede llamar a las acciones anteriores. El temporizador propio de la app de escritorio de Cliqer tiene su API REST y compatibilidad con Stream Deck, consulta Timer (escritorio) y Timer en el host.
Preguntas frecuentes
Falta la clave, está mal escrita o no es tuya: una clave de cuenta solo funciona en las salas de las que eres propietario. Comprueba que la cabecera sea Authorization: Bearer <key> sin espacios de más.
El plan del propietario de la sala no incluye la API de Timer. Consulta Planes y límites.
No. La API necesita una clave de una sala que sea tuya, y la sala de demostración no pertenece a nadie.
Comprueba que la dirección sea https, que sea accesible desde Internet y que responda en menos de 5 segundos sin redirección. Si has perdido el secreto, vuelve a configurarla; el anterior deja de funcionar.
Siguiente
Importar desde Stagetimer
Trae una escaleta desde un CSV de Stagetimer, una hoja de cálculo o una exportación de Cliqer Timer, y vuelve a sacarla cuando quieras.
Descripción general de los casos de uso
Descubre la amplia variedad de software y escenarios en los que Cliqer mejora el control de tus presentaciones y tu flujo de trabajo.