Private beta: this contract may change before launch. Join the waitlist
Hijinks
Hijinks Webhook API

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
Hijinks-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>

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.

Webhooks
message.create

Post a message to a channel

POST
message.update

Replace a message Hijinks created

POST
message.ephemeral

Reply that only one member should see

POST
dm.create

Send a member a private message

POST
ping

Test event

POST