You want your product to react the moment something happens on X — a DM lands, someone follows, a post goes out. So you look for a realtime endpoint, and you discover that this is not part of standard API access at all. It is a separate, gated webhook product with its own application, its own validation handshake, its own subscription ceiling, and its own bill.
And in 2026 there is a second complication that most tutorials have not caught up with: the product you will find first is the one X is moving away from.
X’s own documentation now carries a deprecation notice on the Account Activity API, pointing developers to the newer X Activity API for realtime user-activity delivery going forward. DM events were moved into the newer pipeline in March 2026, and the Account Activity replay endpoint was deprecated in the same month.
No end-of-life date has been published. That is exactly the problem: the old product still works, still has live documentation, and is still what every third-party tutorial describes — so teams keep building on it without realising which side of the migration they are standing on.
This page explains what the realtime webhook product actually is, the four systems that have to line up before a single event reaches your server, and where projects stall. It is written for teams building DM automation, social inboxes, and customer-support tooling on X.
What the realtime webhook product actually delivers
Instead of polling endpoints on a timer, you register one HTTPS endpoint and subscribe individual user accounts to it. X then pushes activity for those accounts to your server as it happens, over a single connection.
The supported activity list is broad: posts and post deletes, mentions, replies, reposts and quote posts, likes, follows and unfollows, blocks and unblocks, mutes and unmutes, direct messages sent and received, typing indicators, read receipts, and subscription revokes.
It is all-or-nothing
You cannot subscribe to a narrower slice of event types. The documentation is explicit that the full product is the only option and delivers every supported event type.
Home timeline is excluded
Timeline data is not delivered through this product. If your plan assumed a realtime feed of what a user sees, that assumption does not hold.
Posts count against your cap
Posts delivered through webhooks still count towards your monthly post cap. Realtime delivery is not a way around volume limits.
DMs need elevated app permissions
Your app must be set to Read, Write, and Access direct messages before DM events flow at all. This is a permissions-tab setting, not something you request per event.
The access tier question — and a myth worth correcting
A claim you will see repeated constantly is that realtime webhooks on X are enterprise-only. That is not accurate. The current documentation lists the product on two tiers, and the difference between them is not features — it is capacity.
| Tier | Unique subscriptions | Webhook endpoints |
|---|---|---|
| Pay Per Use | 3 | 1 |
| Enterprise | 5,000+ | 5+ |
Three subscriptions is enough to prove a concept and nothing more. Any product that onboards customers — a social inbox, a support desk, an agency tool — crosses that ceiling on day one and needs an enterprise application. That application is submitted through the developer portal, and the practical prerequisites are that the app is created under a corporate account, that you have its numeric app ID to hand, and that you already have a webhook endpoint capable of passing validation.
A note on what is not published. X does not publish approval criteria, a review timeline, a required-documents list, or enterprise pricing for this product. Anyone quoting you a fixed approval checklist or turnaround time is inventing it. The honest answer is that the application is reviewed and the outcome is not something anyone can promise in advance.
Older pages still list an enterprise ceiling of roughly 500 subscriptions across 3 webhooks, and retired tier documentation mentions a 250-subscription cap. Both are stale. Plan against the current figures, and check the live docs at build time — this area has changed repeatedly through 2026.
The validation handshake that decides whether you receive anything
Registering a URL is not enough. X challenges your endpoint and will only mark it valid if it answers correctly — and it keeps challenging it for as long as the webhook exists.
- X sends a challenge to your endpointA GET request arrives carrying a single-use challenge token as a query parameter. Your server has to recognise it and respond, not just return a page.
- You sign the token — with the right secretThe response is a keyed hash of that token, base64 encoded and prefixed. The single most common mistake here is signing with the wrong credential: it must be the app’s consumer secret, not a bearer token and not an access token.
- You answer inside the response windowThe published requirement is a 200 response within 10 seconds. Cold-start serverless functions and endpoints sitting behind a slow authentication layer routinely miss this.
- The endpoint must be plainly reachableHTTPS with valid TLS, publicly accessible, and no port number in the URL — a URL with an explicit port is rejected outright. Self-signed certificates and tunnels that expire will fail validation.
- Then it happens again, on a schedule, foreverValidation is re-run on a recurring basis. A webhook that stops answering correctly is marked invalid and stops receiving events — and the failure is silent from your side. Registration failures also surface as distinct errors for a failed check, an unreachable URL, a duplicate URL, or an exceeded webhook limit.
Current documentation is internally inconsistent about how often revalidation runs — one page says hourly, another says every 30 minutes when the webhook has not validated recently. The widely-quoted "every 24 hours" and "you have 3 seconds to respond" figures come from retired pages and should not be designed against. What matters operationally is simpler: your endpoint must answer the challenge correctly at any time, indefinitely, or delivery stops.
Two authorisations, not one
This is where a large share of integrations dead-end. Managing the webhook and subscribing a user are different operations with different credentials, and getting one working tells you nothing about the other.
Webhook management
Creating, listing, validating and deleting the webhook itself — along with app-level subscription operations such as listing and counting — uses app-level authentication. No user is involved.
Subscribing a user
Adding a user to the webhook is a user-context operation and requires that specific user’s own authorisation. Your own tokens will not subscribe someone else’s account.
A further detail that trips up teams working from older material: the authentication model changed in January 2026 to support the newer OAuth flow with fine-grained scopes alongside the legacy flow. Existing integrations continue to work, and legacy permissions override the newer scopes when both are present. So "you must use the old flow" is no longer correct — but neither is assuming the new one behaves identically.
Verifying that a payload really came from X
Every inbound event carries a signature header. Validating it is a keyed hash of the raw request body — not the parsed JSON, not a re-serialised object — compared against the header value using a timing-safe comparison. Frameworks that consume and discard the raw body before your handler runs are a recurring cause of signatures that never match, and skipping the check entirely leaves an endpoint that anyone who learns the URL can post to.
Where these builds actually stall
- The endpoint answers the browser but not the challenge. A URL that returns 200 in a browser can still fail validation because it does not compute the response, signs with the wrong secret, or is too slow.
- Everything works, then quietly stops. Revalidation fails after a deploy, a certificate renewal, or a URL change, and events stop arriving with no error on your side.
- The proof of concept passes, the product cannot ship. Three subscriptions is fine in testing and impossible in production, and the enterprise application was not started early enough.
- Duplicate events treated as bugs. When two subscribed users are in the same conversation, your webhook receives the event once per user; multiple apps sharing an endpoint multiply it again. Deduplication by event identifier is expected design, not a workaround.
- DM events never appear. The app permission level was never raised to include direct-message access, so the subscription succeeds and delivers nothing.
- Costs land differently than modelled. On the current per-event billing model, inbound activity such as a received DM is billed while your own outbound sends are not. Teams that estimated cost from total message volume model it wrong in both directions.
- The build targets the deprecated product. The most expensive failure of all: months of work against the pipeline X is migrating away from, discovered late.
What a properly scoped realtime integration looks like
Getting this right the first time
None of the individual pieces here are conceptually hard. What makes realtime access on X expensive is that four independent systems — app permissions, tier and capacity, the validation handshake, and per-user authorisation — all have to be correct simultaneously, and when one is wrong the symptom is almost always the same: nothing arrives, with no error explaining why. Add a deprecation in progress and stale documentation on both the official and third-party side, and it becomes very easy to spend weeks debugging a design decision made in the first hour.
I provide setup and approval support for social platform API integrations, including reviewing which pipeline and tier your use case belongs on, preparing the access application, and getting webhook delivery working end to end. If you have hit a comparable wall on Meta’s side, the same class of problem is covered in Facebook Webhooks setup, and current engagement options are listed on the pricing page.
Platform requirements, tiers, limits and pricing on X change frequently and should be confirmed against the official documentation at the time you build. This page is technical setup and approval support — no specific outcome or timeline can be guaranteed.