API and integrations

Run a Cliqer Timer room from your own tools over HTTP, and get a signed webhook when the show moves.

Every room has an HTTP API. Start and stop timers, show messages, add time and read the rundown from a script, a show control system or anything that can make a web request. A webhook tells your system when a timer starts or ends.

The API keys page with a Create key button and a list of keys
Account API keys, under Team in your dashboard.

Get started

Create an API key

Open API keys and click Create key. Copy it now: it is shown once. See Team and API keys.

Find the room id

It is the part after /timer/r/ in the control room address, for example https://cliqer.io/timer/r/<room>/control.

Make a call

Send the key with each request. ping checks the room is there.

The API runs the same room as the control room: a call from your tool shows on every screen at once.

Requests

Every call is https://cliqer.io/api/timer/v1/<room>/<action>. GET, POST, PUT and PATCH all work. Parameters go in the query string, or in a JSON body on POST, PUT and PATCH; the body wins when both have one. Dashes in the action name work too, so add-time is add_time. /api/timer/v0/ takes the same calls.

Send the key in one of these, checked in this order:

WhereExample
Authorization headerAuthorization: Bearer <key>
x-api-key headerx-api-key: <key>
api_key query?api_key=<key>. Avoid it where you can: addresses end up 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"}'

Keys and permissions

Your account API key can do everything on rooms you own. A room can also hold its own keys, each with some of three permissions:

PermissionAllows
ReadThe get_ actions and export.
Show callTransport, time, blackout, on air and messages.
EditDeleting, importing, raw intents and the webhook.

A call that needs a permission the key lacks gets 401. A room key's secret is shown once, when it is made. Using the API at all needs the API in your plan, see Plans and limits.

Actions

timer_id picks a timer by its id; index picks it by position, counting from 1. When both are sent, timer_id wins. Leave both out to act on the current timer.

ActionReturns
get_roomTitle, date, time zone and settings.
get_statusWhat is running now.
get_timersThe rundown.
get_messagesThe messages.
get_questionsAudience questions.
get_connectionsConnected devices.
get_logsThe room log. limit, offset.
exportThe whole room as a cliqer-timer-<room>.json download.

Amounts are 30s, 5m, 1h, 250ms, or a bare number of seconds. seconds works in place of amount, and a minus sign goes backwards. Switches like on, autostart and replace read 0, false, off and no as off and anything else as on. Leave on out of blackout to toggle it.

Responses

Every answer is JSON: {"ok": true, "message": "<action>", "data": ...} on success, {"ok": false, "message": "...", "code": "..."} on failure.

StatusMessageWhy
400Either timer_id OR index are requiredselect without a timer.
400amount is required, like 30s, 5m or 1hMissing or unreadable amount.
400Refused: invalidThe room could not apply it.
401Access Denied: Valid API key requiredNo key, a wrong key or a missing permission.
403The API is not in this planThe room's plan has no API.
403Refused: forbidden, Refused: readOnly, Refused: limitReachedNot allowed, a read-only room, or a plan limit.
404Room not found, Unknown action <name>, Timer not foundCheck the room id, the action or the timer id.
409Refused: staleEpochThe room moved on under the call. Send it again.
429Too many requests. Please try again later.Rate limit.
503Refused: authorityOfflineThe room's offline desktop host is not reachable.

Rate limit: 100 calls a minute per key; calls without a key count per address. Each answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the minute starts again).

Webhooks

Set the address

Call webhook with an https url. The answer holds a secret starting whsec_. Store it: it is shown once.

Receive events

Cliqer Timer sends a POST to that address when something happens in the room.

Check the signature

Verify every request before you trust it.

Clear it

Call webhook without a url. The address and its secret are both deleted.

EventWhen
timerStartedA timer starts.
timerEndedA timer reaches zero.
wrapUpYellowA timer reaches its yellow wrap-up point.
wrapUpRedA timer reaches its red wrap-up point.
messageShownA message is shown.

The body is {"event", "roomId", "timestamp", "payload"}. The x-cliqer-timestamp header holds the Unix time in seconds, and x-cliqer-signature holds sha256= and the hex HMAC-SHA256 of <timestamp>.<body> keyed with your secret.

# Recompute the signature of a saved body.
printf '%s.%s' "$TIMESTAMP" "$(cat body.json)" \
  | openssl dgst -sha256 -hmac "$WHSEC" -hex

Sign the raw body exactly as it arrived, before any JSON parsing. The five minute window is your choice; it stops an old request being replayed.

Delivery is one try with a 5 second timeout. Redirects are not followed, and an address that resolves to a private network is dropped. If a missed event matters, read get_status to catch up.

GET https://cliqer.io/api/timer/link/<code> turns a short link code into its room: {"ok": true, "data": {"roomId", "link"}}, or 404 Link not found for an unknown, revoked or expired code or a wrong password. For a link with a password, send it in the x-link-password header, never in the address.

Companion and Stream Deck

There is no Companion module or Stream Deck plugin for Cliqer Timer rooms yet. Bitfocus Companion's Generic HTTP module can call the actions above. The Cliqer desktop app's own timer has its REST API and Stream Deck support, see Timer (desktop) and Host timer.

FAQ

Next

Offline and reliability

What happens when the network drops.

Plans and limits

Which plans include the API.