Hijinks Webhook API
Play every Hijinks game on any chat tool through a bridge you write.
Hijinks talks to a bridge: a small HTTP service you run next to your
chat tool. Hijinks POSTs signed events telling the bridge what to post
(outbound, see webhooks); the bridge POSTs signed events back when a
member runs a command, presses a button or types an answer (inbound,
POST /hooks/{workspaceId}).
A bridge that cannot take requests from the internet — a chat server on
an intranet with outbound access only — polls instead: connect
without a target URL and fetch the same events from
GET /hooks/{workspaceId}/events. See that path.
Staleness
Every outbound event carries expiresAt: past it, the event is no
longer worth showing — a question whose round is over, a reply to a
press a member made minutes ago — and a bridge drops it unapplied.
null means it never goes stale (a self-paced round's question, a
digest). A pushed event is never late enough to matter; the rule is for
a polling bridge catching up after downtime, and for any bridge that
queues events internally.
Private beta. Hijinks is not public yet; custom-platform workspaces open with the rest of the product at launch. This contract may change before then.
Signing
Both directions carry the same header, signed with the workspace's one secret (shown once in the dashboard when you connect):
Code
A poll (GET /hooks/{workspaceId}/events) has no body: the bridge signs
the query string exactly as sent (everything after ?, or the empty
string), and Hijinks signs the response body the same way it signs a push.
Sign and verify the exact raw bytes of the body — never a
re-serialised parse of it. Compare digests in constant time, and refuse a
timestamp more than 5 minutes from your clock. During a secret rotation
Hijinks accepts both the old and the new secret for 24 hours and signs
each outbound event with both — one v1= entry per secret, the new one
first — so a bridge still holding the old secret keeps verifying until you
redeploy it. Any one v1= entry matching is enough.
Text
message.text is chat-flavoured Markdown, ready to print: *italic*,
**bold**, `code`, [label](https://…), > quotes, fenced code
blocks and backslash escapes. A bare \n is a line break and a blank
line separates paragraphs, as in Slack, Discord, Mattermost and most chat
tools. A strict CommonMark renderer must be told to treat newlines as
hard breaks (for example markdown-it breaks: true), or lines will run
together. Member names and question text are escaped, GFM's | and ~
included.
Compatibility
Schemas list every field Hijinks sends today. Ignore fields you do not
recognise: new fields and new kind values may be added without notice
during the beta. Removing or renaming a field is a breaking change.
POST to the one bridge URL you set in the dashboard; the type field in the body says which event it is. Answer any 2xx within 5 seconds.Post a message to a channel
Replace a message Hijinks created
Reply that only one member should see
Send a member a private message
Test event