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

Events a bridge sends to Hijinks.


Report a command, button press or typed message

POST
https://api.hijinks.team
/hooks/{workspaceId}

Hijinks checks a request in a fixed order and answers the first failure:

CheckStatus
Body is JSON and at most 64 KB400 / 413
At most 500 requests per second from the sending IP address, signed or not429
Workspace exists, is a custom-platform workspace and is connected404
Hijinks-Signature matches the raw body401
Signed timestamp within 5 minutes of Hijinks' clock409
At most 250 requests per second for this workspace429
Body matches InboundEvent (the field at fault is named)400

Anything that passes is answered 202 {"ok": true} before it is acted on. What the event causes — a question, an updated message, a DM — arrives as outbound events, never in this response. A message that answers nothing in play is accepted and dropped, so a bridge may forward every message in a channel without filtering.

Rate limits. Every button press and typed answer is one request, so the workspace's 250 a second covers a whole game answering at once — 200 players, the largest per-game cap of any plan that has one — with room for polls. Only signed requests count against the workspace's limit; every request counts against its IP address's 500, which is checked before anything else so unsigned traffic is refused cheaply. Bridges for several workspaces sharing one egress address share that address's limit. A 429 carries Retry-After (seconds): wait that long and send the request again.

Retries and idempotency. Hijinks acts on a request once. Give each request your own id (any string up to 128 characters, unique per request — a UUID will do): a request repeating an id seen in the last 24 hours is answered 202 and ignored, however it is signed. A request without an id is ignored only when it is the very same signed request again (same timestamp, same bytes). So:

  • Retry a timeout, a dropped connection, a 5xx or a 429 with the same body and id, re-signed with the current time.
  • Do not retry any other 4xx: the request itself is wrong.

Without an id, a retry re-signed with a new timestamp is a new request — and a repeated typed guess in a word game costs a turn.

Send Content-Type: application/json; the signature is checked over the body bytes as received.

Report a command, button press or typed message › path Parameters

workspaceId
​WorkspaceId · uuid · required

The workspace id shown in the dashboard next to the inbound URL.

The Hijinks workspace, as shown in the dashboard.

Report a command, button press or typed message › Headers

Hijinks-Signature
​string · pattern: ^t=\d+(,v1=[0-9a-fA-… · required

t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>. Several v1= entries are allowed; any one matching is enough.

Report a command, button press or typed message › Request Body

oneOf
Exactly one variant must match.

Decision Table

VariantMatching Criteria
type = object · type="command" · requires: channel, user, text
type = object · type="action" · requires: channel, user, messageId +1 more
type = object · type="message" · requires: channel, user, text
Properties for Variant 1:
A member ran `/hijinks <text>` (or however your chat spells the command).
type
​const · required
Const value: command
​Channel · required

Where the event happened — a bare id, or an id with a display name.

​User · required

The member who acted. id is your chat's id for them, opaque to Hijinks and stable — scores and DMs follow it. name is shown in results and leaderboards; send it whenever you have it.

text
​string · maxLength: 2000 · required

What followed the command, e.g. start, start science, leaderboard. Empty is help.

id
​RequestId · minLength: 1 · maxLength: 128

Optional. Your id for this request, unique per request; send the same one when you retry it. A request repeating an id seen in the last 24 hours is answered 202 and ignored.

Report a command, button press or typed message › Responses

Accepted. Effects arrive as outbound events.

ok
​const · required
Const value: