Developer Portal
Experimental The bot & app platform is in active development. Self-hosted server support shipped on 2026-08-13 with a smaller feature surface than cloud. See what's supported.
← Docs

App webhooks

An app webhook is a per-channel URL your CI runner, monitoring tool, or external service can POST to in order to drop a message into a GameVox channel. No gateway session required. Messages post as your bot user, with the bot's avatar and username.

Limits

  • 50 webhooks per application.
  • Name: 1–80 characters.
  • Content: 1–4000 characters per message.
  • One webhook = one channel. Creating a webhook requires the manage_server permission in the channel's server.

Token format

WH.{8-char prefix}.{base64 random}

example: WH.aB7xZ2k1.q9F7v1NkN3J2Wm8L6PpV5cU0Yr1zQbXa

The full token is shown exactly once, at create time. We store only the bcrypt hash plus the prefix and last 4 characters for display. If you lose a token, delete the webhook and create a new one.

Creating a webhook (portal)

Open your application → Webhooks tab → New Webhook. Pick a server you can manage, pick a channel, give it a name. The reveal modal shows the full token and the ready-to-paste execute URL. Copy it before dismissing; the portal will never show it again.

Endpoints

Two auth modes: bot token for management, URL token for execute.

Bot-token auth (management)

GET    /channels/{channel.id}/webhooks
POST   /channels/{channel.id}/webhooks
GET    /guilds/{guild.id}/webhooks
GET    /webhooks/{webhook.id}
PATCH  /webhooks/{webhook.id}
DELETE /webhooks/{webhook.id}

URL-token auth (execute + edit)

POST   /webhooks/{webhook.id}/{token}
GET    /webhooks/{webhook.id}/{token}
PATCH  /webhooks/{webhook.id}/{token}
DELETE /webhooks/{webhook.id}/{token}
PATCH  /webhooks/{webhook.id}/{token}/messages/{message.id}
DELETE /webhooks/{webhook.id}/{token}/messages/{message.id}

For URL-token routes there is no Authorization header. The token in the URL path is the auth. Treat the URL like a secret.

Execute request

JSON body:

POST https://api.gamevox.com/webhooks/{webhook.id}/{token}
Content-Type: application/json

{
  "content": "Build #4811 passed on production.",
  "embeds": [
    {
      "title": "CI green",
      "url": "https://ci.example.com/builds/4811",
      "description": "42 tests, 0 failures.",
      "color": 3066993
    }
  ]
}

multipart/form-data body (for attachments):

Content-Type: multipart/form-data; boundary=xyz

--xyz
Content-Disposition: form-data; name="payload_json"

{ "content": "See screenshot", "embeds": [ ... ] }
--xyz
Content-Disposition: form-data; name="files[0]"; filename="crash.png"
Content-Type: image/png

...binary...
--xyz--

Response (both content types):

{
  "id": "1199283740192847400",
  "channel_id": "1199283740192847000",
  "content": "Build #4811 passed on production.",
  "embeds": [ ... ],
  "attachments": [ ... ],
  "timestamp": "2026-05-21T15:42:09Z"
}

What's supported

  • Content: plain text, 1–4000 characters.
  • Embeds: full Discord embed shape (title, description, url, color, timestamp, footer, image, thumbnail, author, fields). Multiple embeds per message allowed.
  • Attachments: upload files via multipart/form-data with a payload_json part; the response includes CDN URLs.
  • Reply targeting: pass message_reference in payload_json.
  • ?wait=true: implicit; the response is always the resolved message.
  • Edit / delete: PATCH / DELETE on /webhooks/{id}/{token}/messages/{message.id} mirror Discord.
  • Username / avatar overrides: not supported. Messages always post as the application's bot user.

Errors

  • 401: token missing, malformed, or doesn't match.
  • 404: webhook deleted, or id doesn't exist.
  • 400: empty content and no embeds/attachments, or content longer than 4000 characters.
  • 405: verb not supported on this route.
  • 413: attachment exceeds the per-file size limit.

Rotating

There is no rotate-in-place endpoint in v1. Delete the webhook and create a new one. The old token stops working immediately on delete (the execute path excludes soft-deleted rows).

Differences from Discord

  • Webhooks are owned by the application, not by a server admin. Deleting the channel does not delete the webhook row; the next execute returns 404 from the channel join in the lookup.
  • No username / avatar_url overrides per request. Identity is fixed to the bot user.
  • Per-channel webhook cap is not enforced; the cap is per-application (50).
  • Auth is verified with bcrypt, so token compare is intentionally slow. Don't hammer the endpoint in tight loops.
  • Self-hosted servers: webhooks aren't routed to self-hosted boxes. All webhook endpoints return 404 for self-hosted guild targets. See Self-hosted docs.

← Back to docs