Subscribing to public events
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 matchedevent_type— which event firedtag— the tag you set when creating the subscriptionpayload— 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
- Handle multiple event types as needed for your product
- Handle delivery failures and retries responsibly
- Monitor subscription health and rotate credentials on schedule
- Delete unused subscriptions and stay under your tier cap