Subscribing to public events

X Activity API

This walkthrough assumes you have completed the X Activity API introduction and read Event types and authentication. It uses a public event type (profile.update.bio) with OAuth 2.0 application-only credentials (xurl --auth app). If you have not installed xurl yet, follow the xURL chapter first.

For private event types (DMs, chat, likes, and so on) you must use user OAuth instead—see Subscribing to private events.

Verify access

Confirm your app can call the subscriptions API:

xurl --auth app /2/activity/subscriptions
{
  "data": [],
  "meta": {
    "result_count": 0
  }
}

If you see a JSON body like the above (possibly with existing subscriptions), your bearer token and project access are working. For GET /2/activity/subscriptions, meta.result_count is the number of subscription objects returned in data.

Getting your user ID

Most public XAA filters use user_id (numeric user ID, not username). The exception is news.new, which uses a keyword filter—see News by Keyword.

xurl --auth app /2/users/by/username/YOUR_USERNAME

Example response

{
  "data": {
    "id": "1234567890",
    "name": "Your Name",
    "username": "your_username"
  }
}

Copy the id value for the subscription below.

Creating a subscription

Subscribe to your own profile bio updates so you can trigger a test event.

Subscription payload

When creating a subscription, you typically send:

  • event_type — the event to subscribe to (required)
  • filter — match criteria (required)—often { "user_id": "…" }
  • webhook_id — where to deliver events (optional, but required for webhook delivery)
  • tag — optional label for your own bookkeeping (recommended)
xurl --auth app /2/activity/subscriptions -X POST -d '{
  "event_type": "profile.update.bio",
  "filter": {
    "user_id": "YOUR_USER_ID"
  },
  "webhook_id": "YOUR_WEBHOOK_ID",
  "tag": "my bio updates"
}'

Success response

{
  "data": {
    "subscription": {
      "created_at": "2025-10-07T05:31:56Z",
      "event_type": "profile.update.bio",
      "filter": {
        "user_id": "YOUR_USER_ID"
      },
      "subscription_id": "1146654567674912769",
      "tag": "my bio updates",
      "updated_at": "2025-10-07T05:31:56Z",
      "webhook_id": "YOUR_WEBHOOK_ID"
    }
  },
  "meta": {
    "total_subscriptions": 1
  }
}

Testing your subscription

After the subscription is created, change your profile bio on X. Your webhook server should log a delivery.

Sample webhook payload
{
  "data": {
    "filter": {
      "user_id": "YOUR_USER_ID"
    },
    "event_type": "profile.update.bio",
    "tag": "my bio updates",
    "payload": {
      "before": "vox populi",
      "after": "vox dei"
    }
  }
}

Fields:

  • filter — the subscription filter that matched
  • event_type — which event fired
  • tag — the tag you set when creating the subscription
  • payload — change-specific data (here, before/after bio text)

Other public events

The same --auth app flow works for other public event types—just swap the event_type. For example, to track an account's posts:

xurl --auth app /2/activity/subscriptions -X POST -d '{
  "event_type": "post.create",
  "filter": {
    "user_id": "YOUR_USER_ID"
  },
  "webhook_id": "YOUR_WEBHOOK_ID",
  "tag": "their posts"
}'

Use post.delete to learn when those posts are removed. Likes (like.create) are a private event and use user OAuth instead—see Subscribing to private events.

Next steps

  1. Handle multiple event types as needed for your product
  2. Handle delivery failures and retries responsibly
  3. Monitor subscription health and rotate credentials on schedule
  4. Delete unused subscriptions and stay under your tier cap
Previous Event types and authentication