Skip to main content
All webhook events share the same envelope format:
{
  "id": "evt_accounts.created:usr_abc123",
  "type": "accounts.created",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": { ... }
}
FieldTypeDescription
idstringUnique event ID (use for deduplication)
typestringEvent type (dot notation)
createdAtstringISO 8601 timestamp
dataobjectEvent-specific payload

accounts.created

Fired when a new user is created in your app (first authentication).
{
  "id": "evt_accounts.created:usr_abc123",
  "type": "accounts.created",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "userId": "usr_abc123",
    "appId": "app_xyz",
    "createdAt": "2026-04-09T18:15:03.000Z"
  }
}
FieldTypeDescription
userIdstringThe new user’s ID
appIdstringYour app’s ID
createdAtstringWhen the user was created

accounts.linked

Fired when a user is linked to a partner external ID via the identity assertion flow.
{
  "id": "evt_accounts.linked:usr_abc123:partner_42",
  "type": "accounts.linked",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "userId": "usr_abc123",
    "externalId": "partner_42",
    "linkedAt": "2026-04-09T18:15:03.000Z"
  }
}
FieldTypeDescription
userIdstringThe user’s AGG ID
externalIdstringYour internal user ID
linkedAtstringWhen the link was created

wallets.ready

Fired when a server-managed wallet is provisioned for a user (both EVM and Solana addresses are available).
{
  "id": "evt_wallets.ready:usr_abc123",
  "type": "wallets.ready",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "userId": "usr_abc123",
    "evmAddress": "0x1234...abcd",
    "svmAddress": "ABC123...xyz",
    "createdAt": "2026-04-09T18:15:03.000Z"
  }
}
FieldTypeDescription
userIdstringThe user’s ID
evmAddressstringEVM (Ethereum/Polygon) wallet address
svmAddressstringSolana wallet address
createdAtstringWhen the wallet was provisioned

trades.placed

Fired when a user submits a trade order. The payload contains the order ID — query the API for the full breakdown (venue splits, amounts, prices).
{
  "id": "evt_trades.placed:quote_abc123",
  "type": "trades.placed",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "orderId": "quote_abc123",
    "userId": "usr_abc123",
    "side": "yes",
    "timestamp": "2026-04-09T18:15:03.000Z"
  }
}
FieldTypeDescription
orderIdstringThe order/quote ID (query API for details)
userIdstringThe user who placed the trade
sidestringOutcome side: "yes" or "no"
timestampstringWhen the order was placed

trades.filled

Fired when a trade order reaches a terminal fill state. One event per venue-level order fill.
{
  "id": "evt_trades.filled:ord_abc123",
  "type": "trades.filled",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "orderId": "ord_abc123",
    "userId": "usr_abc123",
    "status": "filled",
    "timestamp": "2026-04-09T18:15:03.000Z"
  }
}
FieldTypeDescription
orderIdstringThe individual order ID (query API for fill details)
userIdstringThe user who placed the trade
statusstring"filled" or "partial_fill"
timestampstringWhen the fill was recorded

markets.resolved

Fired once per app when a prediction market resolves. Contains a summary — use the pull endpoint for the full list of affected users.
{
  "id": "evt_markets.resolved:vm_123:app_xyz",
  "type": "markets.resolved",
  "createdAt": "2026-04-09T18:15:03.000Z",
  "data": {
    "venueMarketId": "vm_123",
    "externalIdentifier": "KXBTC-26APR09",
    "status": "resolved",
    "outcomes": [
      { "label": "Yes", "winner": true },
      { "label": "No", "winner": false }
    ],
    "affectedUsersCount": 1842,
    "detailsPath": "/apps/app_xyz/market-resolutions/vm_123/users"
  }
}
FieldTypeDescription
venueMarketIdstringThe resolved market ID
externalIdentifierstringVenue-specific market identifier
statusstring"resolved" or "closed"
outcomesarrayResolution outcome for each option
affectedUsersCountnumberUsers in your app with open positions
detailsPathstringAPI path to paginate affected user IDs

Querying affected users

Use the SDK to paginate through affected users. Pass includeEmails: true to get email addresses where available.
import { AggAdminClient } from "@agg-market/sdk/server";

const admin = new AggAdminClient({
  baseUrl: "https://api.agg.market",
  apiKey: process.env.AGG_API_KEY!,
});

// Paginate through all affected users
let cursor: string | undefined;
do {
  const page = await admin.listMarketResolutionUsers(
    appId,
    event.data.venueMarketId,
    { limit: 100, cursor, includeEmails: true },
  );
  for (const user of page.data) {
    console.log(user.userId, user.email);
  }
  cursor = page.nextCursor ?? undefined;
} while (cursor);
See the List users affected by market resolution API reference for full details.
This endpoint returns the current set of users with non-zero positions, not an immutable snapshot at resolution time. If positions are modified after resolution, the results may differ from the affectedUsersCount in the webhook.