Webhooks reference
Compact reference for outbound webhooks. For setup walkthroughs, full payload examples and verification code, see Webhooks.
Base URL: https://api.coolgptgames.com. Auth: Authorization: Bearer <key> with the webhooks scope, or a signed-in dashboard session. See API keys & scopes.
Management endpoints
Method & path | Body | Success response | Notes |
|---|---|---|---|
|
|
|
|
| — |
| Newest first. |
|
|
| Switch on/off or edit. Re-enabling clears the failure streak and resumes queued deliveries. Empty body or unknown keys → |
| — |
| Stops deliveries immediately and removes the delivery log |
| — |
| The 25 most recent deliveries, newest first. |
| — |
| Sends again now, same delivery id and body. |
| — |
| Sends |
There's no endpoint to rotate a secret — see the rotation recipe under Caveats.
Errors
Status |
| When |
|---|---|---|
|
| Bad |
|
| You already have 10 webhooks |
|
| Missing or invalid credentials |
|
| The key lacks the |
|
| No webhook with that ID, or no such delivery |
|
| The webhook is switched off — test/redeliver after re-enabling it |
|
| The delivery predates retry support, so its body wasn't stored |
Errors use the standard envelope { "error": { "code", "message", "details"? } }. See Errors & limits.
Limits
Limit | Value |
|---|---|
Webhooks per account | 10 |
URL |
|
Delivery timeout | 10 seconds per attempt |
Attempts per delivery | 7 (1 + 6 retries) over about 34 hours |
Auto-disable | Every attempt failing for 3 days and ≥ 5 consecutive failed deliveries |
Delivery log shown | 25 most recent deliveries, each with its attempt log |
Delivery retention | Finished deliveries 30 days; pending ones kept |
Event catalogue
Deliveries only cover your own games and the tournaments you created.
Event | Sent when |
|
|---|---|---|
| A version of your game is approved, by the automated pipeline or a human moderator |
|
| A version of your game is rejected, by the automated pipeline or a human moderator |
|
| A player files an abuse report on your game |
|
| A player submits or edits a rating with written text |
|
| A tournament you created settles (a background job checks every 30 seconds; viewing it after its end time also settles it) |
|
| A creator payout is transferred to you |
|
| You trigger a test for one webhook (not subscribable by name; sent only to that webhook) |
|
automated is true for a pipeline decision and false for a human one. A version held for human review sends nothing until a moderator decides. A rejected update to a live game only rejects that version; the game stays published on its previous version. Canceled tournaments don't send tournament.ended. In winners, entrants who never scored are left out, and players tied on the same result share a rank and split the prizes for the places they occupy.
reasonCode / reasonCodes values: nsfw_sexual, nsfw_nudity, graphic_violence, gore, hate_symbols, harassment, ip_infringement, trademark, broken_not_playable, blank_screen, not_a_game, low_effort_duplicate, exact_duplicate, malicious_code, cryptominer, data_exfiltration, phishing_ui, misleading_metadata, spam, contact_info_spam, gambling, age_inappropriate, economy_abuse, other.
prizeCoins are virtual coins, not real money.
Request
POST <your url>
content-type: application/json
user-agent: CoolGPTGames-Webhooks/1.0
x-arcadey-event: <event>
x-arcadey-signature: sha256=<64 lowercase hex chars>
x-arcadey-delivery: <delivery id, stable across retries>
x-arcadey-attempt: <1-based attempt number>Body (compact JSON, keys in this order):
{ "id": "<delivery id>", "event": "<event>", "data": { }, "sentAt": "<ISO 8601 UTC>" }sentAt is when the event was queued and does not change between retries.
Signature algorithm
Item | Value |
|---|---|
Header |
|
Format |
|
Algorithm | HMAC-SHA256 |
Key | The full secret string as UTF-8, including the |
Message | The raw request body bytes, exactly as received |
Timestamp in signature | None. Use the signed |
Comparison | Constant-time ( |
// Node.js
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");# Python
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()Secrets look like whsec_ + 48 hex characters, and each webhook has its own.
Delivery and retry schedule
Item | Value |
|---|---|
Queueing | The event is stored when it happens; a worker sends it within ~5 seconds |
Success | Any |
Failure | Non- |
Attempts | 7 |
Backoff after each failure | +1 min, +5 min, +30 min, +2 h, +8 h, +24 h |
Redirects | Not followed — a |
Manual redelivery |
|
Ordering | Not guaranteed. Subscribed webhooks receive the event in parallel. |
Delivery ID |
|
Logged per attempt |
|
Caveats
Dashboard with no events ticked: creates an all-events webhook, the same as leaving out
eventsin the API.Auto-disabled webhook: you get a dashboard notification (and an email if enabled). Re-enable with the toggle or
PATCH /v1/dev/webhooks/:idonce your endpoint is healthy.Secret rotation: create a second webhook for the same URL, accept either secret, then delete the old one. Each event arrives twice during the overlap.