API und Integrationen
Jeder Raum hat eine HTTP-API. Starten und stoppen Sie Timer, zeigen Sie Nachrichten an, fügen Sie Zeit hinzu und lesen Sie den Ablaufplan aus, und zwar aus einem Skript, einem Showsteuerungssystem oder allem, was eine Webanfrage senden kann. Ein Webhook informiert Ihr System, wenn ein Timer startet oder endet.


Erste Schritte
API-Schlüssel erstellen
Öffnen Sie API-Schlüssel und klicken Sie auf Schlüssel erstellen. Kopieren Sie ihn sofort: Er wird nur einmal angezeigt. Siehe Team und API-Schlüssel.
Raum-ID finden
Das ist der Teil nach /timer/r/ in der Adresse des Kontrollraums, zum Beispiel https://cliqer.io/timer/r/<room>/control.
Einen Aufruf senden
Senden Sie den Schlüssel mit jeder Anfrage. ping prüft, ob der Raum existiert.
Die API steuert denselben Raum wie der Kontrollraum: Ein Aufruf aus Ihrem Tool erscheint gleichzeitig auf allen Bildschirmen.
Anfragen
Jeder Aufruf lautet https://cliqer.io/api/timer/v1/<room>/<action>. GET, POST, PUT und PATCH funktionieren alle. Parameter stehen im Query-String oder bei POST, PUT und PATCH in einem JSON-Body; enthalten beide einen Wert, gilt der Body. Bindestriche im Aktionsnamen funktionieren ebenfalls, add-time entspricht also add_time. /api/timer/v0/ akzeptiert dieselben Aufrufe.
Senden Sie den Schlüssel auf eine dieser Arten, geprüft in dieser Reihenfolge:
| Wo | Beispiel |
|---|---|
Authorization-Header | Authorization: Bearer <key> |
x-api-key-Header | x-api-key: <key> |
api_key-Query | ?api_key=<key>. Vermeiden Sie das nach Möglichkeit: Adressen landen in Logs. |
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())
Schlüssel und Berechtigungen
Mit dem API-Schlüssel Ihres Kontos können Sie in allen Räumen, die Ihnen gehören, alles tun. Ein Raum kann außerdem eigene Schlüssel haben, jeweils mit einer Auswahl aus drei Berechtigungen:
| Berechtigung | Erlaubt |
|---|---|
| Lesen | Die get_-Aktionen und export. |
| Show-Steuerung | Transportfunktionen, Zeit, Blackout, On Air und Nachrichten. |
| Bearbeiten | Löschen, Importieren, Raw-Intents und den Webhook. |
Ein Aufruf, der eine Berechtigung benötigt, die dem Schlüssel fehlt, erhält 401. Das Secret eines Raumschlüssels wird nur einmal angezeigt, bei seiner Erstellung. Damit Sie die API überhaupt nutzen können, muss sie in Ihrem Plan enthalten sein, siehe Pläne und Limits.
Aktionen
timer_id wählt einen Timer über seine ID aus; index wählt ihn über seine Position aus, gezählt ab 1. Werden beide gesendet, gilt timer_id. Lassen Sie beide weg, um den aktuellen Timer anzusprechen.
| Aktion | Rückgabe |
|---|---|
get_room | Titel, Datum, Zeitzone und Einstellungen. |
get_status | Was gerade läuft. |
get_timers | Den Ablaufplan. |
get_messages | Die Nachrichten. |
get_questions | Publikumsfragen. |
get_connections | Verbundene Geräte. |
get_logs | Das Raumprotokoll. limit, offset. |
export | Den gesamten Raum als Download cliqer-timer-<room>.json. |
| Aktion | Parameter | Funktion |
|---|---|---|
start, start_or_stop | timer_id oder index | Startet oder schaltet um. |
stop | Stoppt den laufenden Timer. | |
start_fresh | timer_id oder index | Startet mit der vollen Länge. |
select | timer_id oder index (eines davon ist erforderlich) | Macht ihn zum aktuellen Timer, ohne ihn zu starten. |
reset | timer_id oder index, autostart, from_memory | Zurück auf die volle Länge. |
next, previous | autostart, from_memory | Bewegt sich durch den Ablaufplan. |
add_time, subtract_time | timer_id, amount | Ändert die Länge eines Timers. |
jump | amount | Springt im laufenden Timer um diesen Betrag. |
set_remaining | amount | Setzt die verbleibende Zeit. |
flash | count, message | Lässt die Bildschirme blinken. |
stop_flash | Beendet das Blinken. | |
blackout | on | Blackout ein oder aus. |
blackout_on, blackout_off, toggle_blackout | Dasselbe, ohne Parameter. | |
focus | on | Hebt die Nachricht hervor. |
on_air | on | Die On-Air-Anzeige. |
show_message | message_id, focus | Zeigt eine Nachricht an. |
toggle_message | message_id | Zeigt sie an oder blendet sie aus, wenn sie bereits angezeigt wird. |
hide_message | Blendet die Nachricht aus. |
| Aktion | Parameter | Funktion |
|---|---|---|
delete_timer | timer_id | Löscht einen Timer. |
delete_message | message_id | Löscht eine Nachricht. |
delete_question | question_id | Löscht eine Frage. |
import_csv | csv, replace, date_line, columns, header_row, rows | Importiert Zeilen wie unter Import aus Stagetimer. |
intent | {"intent": {...}} | Jede Änderung, die der Kontrollraum vornehmen kann, als JSON. |
webhook | url | Setzt oder entfernt den Webhook. Siehe unten. |
| Aktion | Parameter | Funktion |
|---|---|---|
ping | Antwortet mit pong, wenn der Raum existiert. | |
submit_question | text (bis zu 1000 Zeichen), name (bis zu 100) | Sendet eine Publikumsfrage. |
vote_question | question_id | Stimmt für eine Frage ab. |
Beträge sind 30s, 5m, 1h, 250ms oder eine einfache Zahl in Sekunden. seconds funktioniert anstelle von amount, und ein Minuszeichen geht rückwärts. Schalter wie on, autostart und replace werten 0, false, off und no als aus und alles andere als ein. Lassen Sie on bei blackout weg, um den Blackout umzuschalten.
Antworten
Jede Antwort ist JSON: {"ok": true, "message": "<action>", "data": ...} bei Erfolg, {"ok": false, "message": "...", "code": "..."} bei einem Fehler.
| Status | Meldung | Grund |
|---|---|---|
| 400 | Either timer_id OR index are required | select ohne Timer. |
| 400 | amount is required, like 30s, 5m or 1h | Fehlender oder nicht lesbarer Betrag. |
| 400 | Refused: invalid | Der Raum konnte die Änderung nicht anwenden. |
| 401 | Access Denied: Valid API key required | Kein Schlüssel, ein falscher Schlüssel oder eine fehlende Berechtigung. |
| 403 | The API is not in this plan | Der Plan des Raums enthält keine API. |
| 403 | Refused: forbidden, Refused: readOnly, Refused: limitReached | Nicht erlaubt, ein schreibgeschützter Raum oder ein Planlimit. |
| 404 | Room not found, Unknown action <name>, Timer not found | Prüfen Sie die Raum-ID, die Aktion oder die Timer-ID. |
| 409 | Refused: staleEpoch | Der Raum hat sich während des Aufrufs weiterbewegt. Senden Sie den Aufruf erneut. |
| 429 | Too many requests. Please try again later. | Ratenlimit. |
| 503 | Refused: authorityOffline | Der Raum liegt im Papierkorb. Stellen Sie ihn zuerst wieder her. |
Ratenlimit: 100 Aufrufe pro Minute und Schlüssel; Aufrufe ohne Schlüssel werden pro Adresse gezählt. Jede Antwort enthält RateLimit-Limit, RateLimit-Remaining und RateLimit-Reset (Sekunden, bis die Minute neu beginnt).
Webhooks
Adresse festlegen
Rufen Sie webhook mit einer https-Adresse als url auf. Die Antwort enthält ein secret, das mit whsec_ beginnt. Speichern Sie es: Es wird nur einmal angezeigt.
Ereignisse empfangen
Cliqer Timer sendet einen POST an diese Adresse, wenn im Raum etwas passiert.
Signatur prüfen
Verifizieren Sie jede Anfrage, bevor Sie ihr vertrauen.
Webhook entfernen
Rufen Sie webhook ohne url auf. Die Adresse und ihr Secret werden beide gelöscht.
| Ereignis | Wann |
|---|---|
timerStarted | Ein Timer startet. |
timerEnded | Ein Timer erreicht null. |
wrapUpYellow | Ein Timer erreicht seine gelbe Wrap-up-Marke. |
wrapUpRed | Ein Timer erreicht seine rote Wrap-up-Marke. |
messageShown | Eine Nachricht wird angezeigt. |
Der Body ist {"event", "roomId", "timestamp", "payload"}. Der Header x-cliqer-timestamp enthält die Unix-Zeit in Sekunden, und x-cliqer-signature enthält sha256= gefolgt vom hexadezimalen HMAC-SHA256 von <timestamp>.<body>, mit Ihrem Secret als Schlüssel.
# 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)
Signieren Sie den Rohbody genau so, wie er angekommen ist, vor jedem JSON-Parsing. Das Fünf-Minuten-Fenster legen Sie selbst fest; es verhindert, dass eine alte Anfrage erneut eingespielt wird.
Die Zustellung erfolgt mit einem einzigen Versuch und 5 Sekunden Timeout. Weiterleitungen werden nicht verfolgt, und eine Adresse, die in ein privates Netzwerk auflöst, wird verworfen. Wenn ein verpasstes Ereignis wichtig ist, lesen Sie get_status, um den aktuellen Stand abzurufen.
Kurzlinks
GET https://cliqer.io/api/timer/link/<code> löst einen Kurzlink-Code in seinen Raum auf: {"ok": true, "data": {"roomId", "link"}}, oder 404 Link not found bei einem unbekannten, widerrufenen oder abgelaufenen Code oder einem falschen Passwort. Bei einem Link mit Passwort senden Sie dieses im Header x-link-password, niemals in der Adresse.
Companion und Stream Deck
Es gibt kein Companion-Modul und kein Stream Deck Plugin für Räume in Cliqer Timer. Das Generic HTTP Modul von Bitfocus Companion kann die oben genannten Aktionen aufrufen. Der eigene Timer der Cliqer Desktop-App hat eine eigene REST-API und Unterstützung für Stream Deck, siehe Timer (Desktop) und Host-Timer.
Häufige Fragen
Der Schlüssel fehlt, ist falsch eingegeben oder gehört nicht Ihnen: Ein Kontoschlüssel funktioniert nur in Räumen, die Ihnen gehören. Prüfen Sie, ob der Header Authorization: Bearer <key> lautet, ohne zusätzliche Leerzeichen.
Der Plan des Raumbesitzers enthält keine Timer-API. Siehe Pläne und Limits.
Nein. Die API benötigt einen Schlüssel für einen Raum, der Ihnen gehört, und der Demo-Raum gehört niemandem.
Prüfen Sie, ob die Adresse https verwendet, aus dem Internet erreichbar ist und innerhalb von 5 Sekunden ohne Weiterleitung antwortet. Legen Sie sie erneut fest, wenn Sie das Secret verloren haben; das alte funktioniert dann nicht mehr.
Weiter
Import aus Stagetimer
Übernehmen Sie einen Ablaufplan aus einer Stagetimer-CSV, einer Tabelle oder einem Export aus Cliqer Timer, und exportieren Sie ihn auch wieder.
Überblick über die Anwendungsfälle
Entdecken Sie die vielfältige Software und die zahlreichen Szenarien, in denen Cliqer Ihre Präsentationssteuerung und Ihren Workflow verbessert.