Skip to content

Webhooks

Receive signed HTTP callbacks when your services are provisioned, change state, or come under DDoS attack.

Webhooks let your systems react to changes on your GameServerKings account in real time —
provisioning progress, service state changes, and DDoS attacks on your IPs — by receiving a signed
HTTP request at a URL you control.

  • Configure: Client Area → Profile → Notifications → Webhooks → Manage webhooks
    (/client-area/webhooks).
  • One endpoint per account. Choose which event types it receives, view a delivery log, resend a
    delivery, rotate your signing secret, and send a test event.

Delivery mechanics

  • Every event is delivered as an HTTP POST with a JSON body to your endpoint URL.
  • Your URL must be HTTPS and must resolve to a public address. Redirects are not followed.
  • Respond with any 2xx status to acknowledge. Respond within 10 seconds — slower responses
    are treated as failures.
  • Anything other than 2xx (or a timeout / connection error) is retried with exponential
    backoff: up to 8 attempts starting at 30 seconds and roughly doubling each time (about two
    hours of total coverage).
  • Delivery is at-least-once: a delivery may arrive more than once (e.g. your server accepted it
    but the acknowledgement was lost). De-duplicate on the event id.
  • Ordering is not guaranteed. Retries can reorder events. Use the envelope createdAt to order
    events yourself.
  • If your endpoint fails every delivery across the full retry window for 5 consecutive events,
    it is automatically disabled and we email you. Re-enable it from the Webhooks page once it is
    reachable again. A single successful delivery resets the counter.

Request headers

Header Description
Content-Type Always application/json.
User-Agent GameServerKings-Webhooks/1.
X-GSK-Event-Id The event's unique id (same as the body id). Use for idempotency.
X-GSK-Event-Type The event type, e.g. service.active.
X-GSK-Signature Signature used to verify authenticity — see below.

Verifying signatures

Every request is signed with HMAC-SHA256 using your endpoint's signing secret (shown on the
Webhooks page, prefixed whsec_). Verify each request before trusting it:

  1. Read the X-GSK-Signature header. It is a comma-separated list of fields, for example
    t=1720031400,v1=5f2b…. The t field is the Unix timestamp (seconds) at signing. Each v1
    field is a candidate signature in lowercase hex.
  2. Build the signed string by joining the timestamp, a literal ., and the exact raw request
    body
    (do not re-serialize the JSON): "{t}.{raw_body}".
  3. Compute HMAC-SHA256(signed_string) keyed with your signing secret, as lowercase hex.
  4. Accept the request if your computed value equals any v1 field (use a constant-time
    comparison). Multiple v1 values appear only during a secret rotation — see below.
  5. Reject requests whose t is outside your tolerance window (5 minutes is recommended) to protect
    against replay.

Rotating the secret

Rotating generates a new secret and keeps the previous one valid for 24 hours. During that
window requests carry two v1 signatures — one for each secret — so a deployment that has not
yet picked up the new secret keeps validating. Update your stored secret and the old signature
simply stops appearing after the window ends.


Envelope

Every payload shares the same top-level envelope. The event-specific content lives under data.

Field Type Description
id string Unique event id. Stable across redeliveries — de-duplicate on this.
type string Event type (see the catalog below).
createdAt string ISO-8601 timestamp of when the event occurred.
data object Event-specific payload. Shape depends on type.
{
  "id": "clzq1a2b3c4d5e6f7g8h9i0j",
  "type": "service.active",
  "createdAt": "2026-07-03T18:42:11.000Z",
  "data": { }
}

Service lifecycle events

These describe the lifecycle of a service you purchased. A service is identified by its own id
and is independent of whether it runs on shared or dedicated infrastructure — the concrete backing
resource is reported separately as detail.

Event types

Type When it fires
service.provisioning Provisioning has started for the service.
service.active The service is live and ready (also fires after an update or unsuspend completes).
service.updating A configuration or build change is being applied.
service.suspended The service has been suspended.
service.cancelled The service has been cancelled or removed.
service.failed Provisioning or a lifecycle action failed.

data fields

Field Type Description
service.id number Stable service identifier.
service.type string SHARED (game hosting) or DEDICATED (dedicated hardware).
service.deliveredAt string | null When the service first became active.
service.suspendedAt string | null When the service was suspended, if applicable.
service.canceledAt string | null When the service was cancelled, if applicable.
billable object | null The recurring contract behind the service (null if none).
billable.id number Billable (subscription) id.
billable.status string PENDING, ACTIVE, FAILED, SUSPENDED, or CANCELLED.
billable.currency string ISO currency code, e.g. USD.
billable.price number Recurring price in the currency's minor units (e.g. cents).
billable.periodStart string Start of the current billing period.
billable.periodEnd string End of the current billing period.
billable.autoRenew boolean Whether the subscription auto-renews.
resource.type string Same as service.type (SHARED / DEDICATED).
resource.id number Id of the concrete backing server/machine.
resource.status string | null The backing resource's internal status (more granular than the event).

Example (service.active)

{
  "id": "clzq1a2b3c4d5e6f7g8h9i0j",
  "type": "service.active",
  "createdAt": "2026-07-03T18:42:11.000Z",
  "data": {
    "service": {
      "id": 4821,
      "type": "SHARED",
      "deliveredAt": "2026-07-03T18:42:11.000Z",
      "suspendedAt": null,
      "canceledAt": null
    },
    "billable": {
      "id": 9155,
      "status": "ACTIVE",
      "currency": "USD",
      "price": 1200,
      "periodStart": "2026-07-03T18:42:11.000Z",
      "periodEnd": "2026-08-03T18:42:11.000Z",
      "autoRenew": true
    },
    "resource": {
      "type": "SHARED",
      "id": 4821,
      "status": "ACTIVE"
    }
  }
}

DDoS attack events

Attack events relay the same information as the Discord/email attack alerts, for DDoS attacks on IP
addresses attached to your account. They are not filtered by your Discord/email alert thresholds
— subscribing your endpoint to the event type is the only filter. Each attack produces at most one
attack.started and one attack.ended.

Event types

Type When it fires
attack.started A DDoS attack on one of your IPs is first detected.
attack.ended A previously reported attack has ended.

data fields

Field Type Description
attack.eventId string Upstream attack identifier — the same value on the start and end events.
attack.ipAddress string The IP under attack.
attack.status string Raw upstream marker (start / end); prefer the event type.
attack.pps number Peak packets per second observed.
attack.mbps number Peak megabits per second observed.
attack.startedAt string | null When the attack started.
attack.endedAt string | null When the attack ended (present on attack.ended).
attack.machineId number | null Your machine the IP belongs to, if it maps to one.
attack.serverName string | null That machine's name, if available.

Example (attack.ended)

{
  "id": "clzq7p8q9r0s1t2u3v4w5x6y",
  "type": "attack.ended",
  "createdAt": "2026-07-03T19:05:44.000Z",
  "data": {
    "attack": {
      "eventId": "atk_8f21c0",
      "ipAddress": "203.0.113.24",
      "status": "end",
      "pps": 1450000,
      "mbps": 8800,
      "startedAt": "2026-07-03T18:58:02.000Z",
      "endedAt": "2026-07-03T19:05:40.000Z",
      "machineId": 312,
      "serverName": "fra-dedi-07"
    }
  }
}

Test event

The Send test event button on the Webhooks page delivers a ping to verify your endpoint and
signature wiring end-to-end. It is not a subscribable type — it is only ever sent on demand.

{
  "id": "clzq0t1e2s3t4p5i6n7g8ev9",
  "type": "ping",
  "createdAt": "2026-07-03T20:00:00.000Z",
  "data": {
    "message": "This is a test event from GameServerKings."
  }
}

Event type reference

Type Category Subscribable
service.provisioning Service lifecycle Yes
service.active Service lifecycle Yes
service.updating Service lifecycle Yes
service.suspended Service lifecycle Yes
service.cancelled Service lifecycle Yes
service.failed Service lifecycle Yes
attack.started DDoS attack Yes
attack.ended DDoS attack Yes
ping Test No (sent on demand)