X/Twitter API is Now Pay-to-Play - Why I Disabled Cross-Posting
It's 2026 and I wanted a simple thing: when I publish a blog post, automatically cross-post it to X/Twitter alongside Bluesky. I had the code written, the credentials configured, tweepy installed. It should have been a 10-minute integration. Instead, it became an archaeology expedition through X's increasingly hostile developer ecosystem.
The Setup
The implementation was straightforward. I already had automated Bluesky cross-posting working via the AT Protocol. For Twitter, I used tweepy (v4.16.0, the latest) with OAuth 1.0a credentials from my existing developer app (App ID 15831, which I've had for years).
client = tweepy.Client(
consumer_key=api_key,
consumer_secret=api_secret,
access_token=access_token,
access_token_secret=access_token_secret,
)
response = client.create_tweet(text=tweet_text)
Simple. Clean. Should just work.
Error 1: 503 Service Unavailable
The first deploy to production returned 503 Service Unavailable. Not a great start, but transient errors happen. I assumed Twitter was having a bad day and moved on to debugging locally.
Error 2: 403 Forbidden — "App Not Attached to a Project"
Local testing revealed the real problem:
403 Forbidden
When authenticating requests to the Twitter API v2 endpoints,
you must use keys and tokens from a Twitter developer App
that is attached to a Project.
My app predates Twitter's "Project" requirement. When they restructured the developer portal under Elon's ownership, they added a requirement that all apps must be inside a "Project" to access v2 endpoints. My legacy standalone app wasn't.
The fix should have been simple: Go to the Developer Portal, create a Project, attach the app. But there was no "Create Project" button.
This isn't just me — it's a widely reported bug on the X Developer Community forums. Developers across all tiers — Free, Basic, Pro, and even the new Pay-Per-Use tier — report that the Projects section is missing entirely from the console. Some accounts have "ghost project" states where apps are internally associated with invisible/deleted projects that can't be managed.
The Fix: "Move to Package"
After digging through the portal, I found an obscure "Move to package" option buried in the app settings. This finally attached the app to a project. Authentication started working:
>>> client.get_me()
nerdymark
Victory? Not quite.
Error 3: 402 Payment Required
With auth working, I tried posting an actual tweet:
402 Payment Required
Your enrolled account [1146115155501039616] does not
have any credits to fulfill this request.
Credits. X now requires you to purchase credits to use the tweet endpoint. The "Free" tier is write-only with a credit system. Even posting a single tweet costs credits. The Basic tier is $200/month (doubled from previous pricing). There's a new Pay-Per-Use tier where you buy credits upfront and get charged per API call.
To be clear: the API that was free for over a decade, that enabled an entire ecosystem of bots, tools, and integrations — now has a literal paywall on the most basic operation (posting a tweet).
The Contrast: Bluesky
Meanwhile, my Bluesky cross-posting has been running flawlessly since I implemented it. The AT Protocol is open, well-documented, and free to use. No projects, no tiers, no credits. You authenticate with your handle and an app password, and you're done.
# Bluesky: just works
from atproto import Client
client = Client()
client.login(handle, password)
client.send_post(text="Hello from my blog!")
No 403s. No ghost projects. No credit system. Just an API that does what APIs are supposed to do.
What I Disabled
I've commented out the Twitter cross-posting code in both the immediate post-creation flow and the background scheduler. The tweepy dependency stays in requirements.txt in case X ever becomes developer-friendly again (not holding my breath). The credentials remain configured on our AWS environment.
If X introduces a reasonable free tier for posting — even 50 tweets/month would be fine for a personal blog — I'll re-enable it. Until then, my posts go to Bluesky automatically and X gets nothing.
Timeline of X API Hostility
For context, this is my fourth blog post about Twitter/X breaking things for developers:
- 2023: Twitter API Restrictions Kill Developer Projects — API pricing introduced
- 2023: Twitter Art Bot Suspended — my art bot killed
- 2024: API v1 Access Killed — legacy endpoints shut down
- 2026: This post — even v2 posting now requires payment
Each time, the platform gets worse for developers. Each time, the alternatives get better. Bluesky isn't just an alternative anymore — for developers, it's the default.