Webhooks

Event delivery

Create subscriptions in Settings → Developer API. Each subscription gets its own signing secret and a delivery log.

Payload
POST https://your-bot.example.com/eaw
x-eaw-event: war.declared
x-eaw-event-id: 9f1c...        # unique — deduplicate on this
x-eaw-timestamp: 1756051200
x-eaw-signature: sha256=<hmac>

{
  "event_id": "9f1c...",
  "event": "war.declared",
  "created_at": "2026-08-24T17:00:00Z",
  "data": { "war_id": "...", "attacker_nation_id": "...", "defender_nation_id": "...", "objective": "raid" }
}
Verifying the signature
import crypto from "node:crypto";

const expected = crypto
  .createHmac("sha256", process.env.EAW_WEBHOOK_SECRET)
  .update(`${timestampHeader}.${rawBody}`)
  .digest("hex");

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature.slice(7)))) {
  return res.status(401).end();
}

Reject deliveries whose timestamp is more than five minutes old to defeat replay attacks.

Retries and deduplication
  • Any 2xx marks the delivery complete. Anything else is retried with exponential backoff, up to 6 attempts.
  • The same event_id may arrive more than once — store it and ignore duplicates.
  • Every attempt is recorded with status, HTTP code and error text in your delivery log.
  • A failing endpoint never affects gameplay: the war still happens if your bot is down.
Events
war.declaredwar.endedbattle.completedalliance.member_joinedalliance.member_lefttreaty.signedtreaty.endedglobal_conflict.startedglobal_conflict.endedstrategic_weapon.launchedstrategic_weapon.impactstrategic_weapon.interceptedera.startedera.endedmarket.major_movementcontract.completedpeace.accepted

Events for systems that have not shipped yet (eras, global conflicts, market, strategic weapons, contracts) are reserved now so bots can subscribe before launch day.