X's 2026 API Pricing Overhaul: What Pay-Per-Use Means for Teams Receiving DMs and Mentions — UnifyPort
If you registered for the X API for the first time this year, you hit a wall that didn’t exist in 2025: there is no free tier. X moved its developer API to a pay-per-use model in February 2026, replacing the old fixed monthly plans (the ones that ran anywhere from $0 to $5,000/month depending on the tier). New developers now need to fund a credit balance before they can make a single call — there’s no longer a way to “try it for free” with a handful of reads a month.
For teams that just want to receive direct messages and mentions on an X account — the inbound side, not posting or analytics — this changes the shape of the decision entirely. It’s no longer “which fixed tier covers our volume,” it’s “how much does every single message we receive cost us, forever, as a recurring line item.”
What actually changed, and twice
The February 2026 overhaul set the baseline: requests are billed per-call, with reads and writes priced separately, and no usage caps — you simply get charged for whatever you call. Then on April 20, 2026, X published an unscheduled revision to those rates. Reads of your own data — your own account’s tweets, followers, and DMs — dropped sharply to $0.001 per resource, a 5x cut from the original pay-per-use rate. At the same time, standard write requests rose from $0.010 to $0.015 per request.
For an inbound DM/mention pipeline, that means two different meters are running at once:
- Reading inbound DMs and mentions — now relatively cheap at $0.001 per owned-resource read, after the April correction
- Sending replies — a write request, now $0.015 per call
The $0.001 read rate sounds small until you do the arithmetic a support team actually lives with. A small team handling a few hundred inbound DMs and mentions a day, each needing a reply, is paying for reads and writes on every single message — and that’s before accounting for polling overhead, since “receiving” on X’s API still typically means querying for new activity rather than a push-based webhook for DMs. Polling intervals multiply the read cost independently of how many real messages actually arrive.
None of this is catastrophic at low volume — a few dollars a month for light usage, as several pricing breakdowns from earlier this year noted. But it’s a fundamentally different cost model than “we pay $X/month and stop thinking about it.” Every spike in customer messages — a product launch, a viral mention, a support backlog — now shows up directly on the bill, denominated per message, per reply, per poll.
The reframe: you don’t need to call the API to receive a message
Here’s the part that’s easy to miss when you’re staring at a per-request price sheet: the cost structure above is a property of X’s official API, not a property of “receiving a message on X.” If your actual requirement is “when someone DMs our account or mentions us, our backend should find out about it and be able to reply” — that requirement doesn’t inherently require paying X per read and per write.
That’s the gap UnifyPort’s unofficial inbound interface for X fills. Instead of your backend polling X’s API (and paying per read for the privilege), UnifyPort connects to the X account directly and pushes inbound activity to your webhook as it happens — no metered reads, no polling loop, no per-message charge from the platform you’re integrating against.
How it looks in practice
Connecting an X account to UnifyPort uses the same session-based flow documented for the UnifyPort Exporter extension: you create an account record with provider: "twitter" and auth_mode: "session", export the session for an account you’re already logged into, and bring the runtime online.
POST /v1/accounts
Content-Type: application/json
{
"provider": "twitter",
"auth_mode": "session"
}
From there, every DM and mention that lands on that account arrives at your webhook as a message.received event — the same normalized shape UnifyPort uses for WhatsApp, Telegram, LINE, TikTok, and Zalo:
{
"event": "message.received",
"account_id": "acct_8Q2vK",
"provider": "twitter",
"from": "user_3f9c1a",
"text": "Hey, do you ship to the EU?",
"timestamp": 1749427200,
"message_id": "x_msg_7c1f9d"
}
Replying is the same POST /v1/messages call you’d use for any other channel, addressed by account_id and from. There’s no separate read step to “fetch” the DM before you can act on it — the event already contains everything you need — and no per-call billing tied to how many messages arrive or how often you check.
X (Twitter) ──► UnifyPort ──► message.received ──► your webhook
▲ │
│ ▼
POST /v1/messages ◄──────────── your reply logic
Every delivery is signed with HMAC-SHA256 using the signing_secret you configure on the webhook, so verification is a single code path — the same one you’d already be running for your other connected channels.
What this means in practice
If your X usage is genuinely light — a handful of DMs a week, no other automation — the new $0.001 owned-read rate is cheap enough that the official API is fine, and standing up a separate connection isn’t worth the effort.
But if X is one of several channels your team monitors for inbound messages, and especially if volume is unpredictable — a viral post, a support spike, a launch — a per-call meter on reads and writes turns “we get more attention” into “our bill goes up,” which is the wrong direction for that incentive to point. Connecting X through UnifyPort’s unified webhook puts it on the same flat, normalized footing as the rest of your channels — one message.received event, one reply endpoint, no metering on top.