X API Playground: the free local mock, and its limits
X ships a free local server that emulates the X API v2 so tests never spend credits. What it gets right, what it fakes badly, and why its cost meter is the real draw.
The short version
- ▸X API Playground is a free Go binary from X's own xdevplatform GitHub org. It runs an HTTP server on localhost:8080 that emulates X API v2, so test traffic never reaches api.x.com and never spends a credit.
- ▸X barely advertises it. There is one card on the Tools and Libraries page in the docs and a single forum announcement from 23 December 2025. Everything else lives in the repo's README and DOCUMENTATION.md.
- ▸Route coverage does not freeze with the code. The server downloads https://api.x.com/2/openapi.json and refreshes it when the cache passes 24 hours, so endpoints added to the spec show up without a new release.
- ▸The cost meter is the real reason to run it. It pulls X's live rate card from console.x.com/api/credits/pricing and applies the same 24-hour deduplication window X bills on, so you can price a pagination loop before it runs against production.
- ▸Response behaviour is hand-written and the last commit landed 9 January 2026. Multipart media upload, some expansions, and several error bodies do not match the real API, so treat it as a wiring and budgeting tool, not a conformance suite.
Quick answer
X API Playground is a free local server, published by X itself, that pretends to be the X API v2. You install a Go binary, run playground start, point your code at http://localhost:8080, and every request your integration makes during development is answered locally instead of billed. It is the cheapest fix for the single biggest change to this platform in 2026: there is no free tier any more, so every careless loop in a test suite costs money.
Last updated: October 2026
Almost nobody uses it, and that is mostly X's fault. The tool got one forum post on 23 December 2025 and one card on the Tools and Libraries page. It has no page in the developer documentation, no entry in llms.txt, and no mention in the pay-per-use announcements where it would have been most useful.
What it actually is
A single Go binary that serves an HTTP API shaped like api.x.com, with in-memory state, seeded data, and a browser UI.
go install github.com/xdevplatform/playground/cmd/playground@latest
playground start
curl -H "Authorization: Bearer test" http://localhost:8080/2/users/me
Setup ends there. Go 1.21 or later is the only prerequisite. The web UI opens at http://localhost:8080/playground, and alongside the emulated X routes the server exposes its own management endpoints: GET /health, GET /endpoints, POST /state/reset, GET /state/export, POST /state/import and GET /rate-limits.
State is real in the sense that matters. Create a Post against the playground and a later read returns it. Enable persistence in ~/.playground/config.json and that state survives a restart, which is what makes it usable in a CI pipeline where a fixture has to exist before the test that reads it.
Two simulations are switched off by default and worth turning on deliberately. Rate limiting (rate_limit.enabled) returns a real 429 with x-rate-limit-limit, x-rate-limit-remaining and x-rate-limit-reset headers once the window fills. Error injection (errors.enabled, with an error_rate between 0 and 1) makes a configurable share of requests fail, which is the only cheap way to find out whether your retry logic actually retries.
Why the frozen repo still tracks the live API
Commit history on the repo looks abandoned. Four releases between 23 December 2025 and 9 January 2026, ending at v1.2.1, and nothing since. Five open issues, the newest from June 2026, none answered.
That matters less than it looks, because the playground does not hardcode its routes. On first start it downloads https://api.x.com/2/openapi.json, caches it at ~/.playground/.playground-openapi-cache.json, and re-downloads it whenever the cache is older than 24 hours. playground refresh forces it. The DOCUMENTATION.md description is blunt about the consequence: the server "automatically supports new endpoints as they're added to the spec."
So the routing layer and the request validation layer are current. What froze in January is the hand-written part: the seeded data model, the response construction, and the error bodies. The result is a tool that will happily accept a request to an endpoint that shipped last month and answer it with something generic.
If you want the genuinely current picture of which endpoints exist and what they do, the spec itself and X API search are better references than anything the playground returns.
The cost meter is the actual reason to run it
Version 1.2.0 added usage and cost tracking, and this is the feature that justifies the install.
Every successful request is metered against X's own rate card, and the result is exposed at three endpoints:
curl http://localhost:8080/api/credits/pricing | jq
curl "http://localhost:8080/api/accounts/0/usage?interval=30days&groupBy=eventType" | jq
curl http://localhost:8080/api/accounts/0/cost | jq
Those rates are not guesses. credits.go sets pricingURL to https://console.x.com/api/credits/pricing and fetches it with a 24-hour cache, falling back to a hardcoded table only when the fetch fails. That endpoint is public, it answers an unauthenticated curl, and on 18 October 2026 it returns the live list: Post at $0.005 per resource, User and Follow and DirectMessage at $0.010, Like and Mute and Block and OwnedRead at $0.001, and on the write side PostCreate at $0.015, UserInteractionCreate at $0.015, and ContentCreateWithUrl at $0.200.
That last one deserves a second look. Creating a Post that contains a link is priced at twenty cents a request, forty times a plain Post create. X's pricing page lists it as "Post: Create (with URL)". A scheduler that posts 50 links a day is spending $300 a month on write calls alone, which is the kind of number you want to discover in a local meter rather than in a Developer Console invoice. The rest of the rate card, including the $20 and $50 free credit incentives X added on 2 October 2026, is in our X API pricing breakdown.
Metering also copies a billing rule most developers miss. Read charges are per resource, and X deduplicates a resource within a 24-hour UTC window, so fetching the same Post twice in a day is billed once. The playground implements the same 24-hour window against the resource IDs in the response body, which means a pagination loop that re-reads overlapping pages prices correctly instead of looking twice as expensive as it is.
Where the emulation stops matching the real API
Open issues on the repo are a decent map of the gaps, and they are specific.
| Issue | Filed | What breaks |
|---|---|---|
| #7 | 12 Jun 2026 | The OpenAPI validator parses multipart/form-data bodies as JSON, so chunked media append returns 403 "invalid JSON" |
| #6 | 11 May 2026 | GET /2/users/{id}/tweets rejects valid expansions values that the real API accepts |
| #5 | 23 Apr 2026 | Install fails on Windows 11 by both documented routes |
| #3 | 7 Jan 2026 | users/me returns a differently-shaped error body than api.x.com for an invalid user.fields value |
| #2 | 23 Dec 2025 | No PowerStream support |
Issue #3 is the one to internalise. The playground returns an error, but not X's error, so a test that asserts on errors[0].parameters passes locally and fails in production. Anything that depends on exact failure shapes has to be verified against the real API at least once.
Two more things it does not do. There is no OAuth flow: authentication is accepted, not performed, and the bearer token you send is used to derive an account ID rather than validated. And the repo has no LICENSE file despite the README saying MIT, which may matter if your employer's policy checks for one.
When to use it, and when to spend real credits
Use the playground for the work that is expensive precisely because it is repetitive: wiring a client, iterating on pagination, shaping a database around response payloads, running integration tests on every commit, and estimating what a feature will cost before you ship it.
Spend real credits for anything where fidelity is the thing under test. Auth flows need the real token exchange, which is covered in X API OAuth. Media upload needs real multipart handling. Rate-limit behaviour under genuine concurrency needs the real limiter. Error handling needs at least one pass against real error bodies.
A sensible split is a single environment variable for the base URL, defaulting to http://localhost:8080 in development and CI and https://api.x.com in a staging job that runs on merge rather than on every push. That gives you the fast free loop most of the time and a real check before anything reaches production.
Worth knowing what the playground is not competing with. It is a mock, not an access route, so it does nothing about the parts of X that the API has not covered since the 2026 restrictions. If what you actually need is an account that posts and replies on your behalf rather than a server that pretends to, that is a different category of tool: X-Autopilot runs in your own browser on your own machine instead of calling endpoints that no longer sell what you want. And if you are wiring a model into X rather than a service, the X MCP server is the path X does support.
Getting a key first
No credentials are needed to run the playground, which makes it a good place to start before you have any. When you do need the real thing, the account, project and app setup is unchanged, and how to get an X API key walks the current console flow.
One habit worth forming early: run playground start with the cost endpoints open in a second terminal while you build. Watching a number tick up per request changes how people write pagination loops, and it is a great deal cheaper than learning the same lesson from a bill.
Frequently asked
Answers indexed by Google + AI assistants.
What is the X API Playground?+
It is a standalone local HTTP server, written in Go and published by X at github.com/xdevplatform/playground, that simulates the X API v2 for development and testing. You install it with go install, run 'playground start', and point your client at http://localhost:8080 instead of https://api.x.com. It seeds realistic data, keeps state between requests, and ships a web UI at /playground for building requests by hand.
Does the X API Playground use API credits?+
No. Nothing leaves your machine except one call to download X's OpenAPI specification and one to fetch the current price list, and neither of those is a billable X API request. That is the point of the tool: X's own docs describe it as a local mock server for testing X API v2 endpoints without using real credits.
Is the X API Playground still maintained?+
It is published but quiet. The repo shipped four releases between 23 December 2025 and 9 January 2026, ending at v1.2.1, and has had no commits since. Open issues from April, May and June 2026 are unanswered. The code still runs, and because endpoint discovery is driven by the live OpenAPI spec rather than by hardcoded routes, new endpoints still appear.
Can I test media upload against the playground?+
Not reliably. Issue #7, filed 12 June 2026, reports that the OpenAPI validator tries to parse multipart/form-data bodies as JSON, so chunked media upload to POST /2/media/upload/{id}/append fails with a 403 and an 'invalid JSON' message. Any flow that posts binary chunks needs the real API or your own stub.
How accurate is the playground's cost estimate?+
The rates are accurate because they are fetched live from console.x.com/api/credits/pricing rather than hardcoded, and cached for 24 hours. The counts are only as accurate as your test traffic. The playground bills what your local requests return, so if your seeded dataset is smaller than production, a per-resource read looks cheaper than it will be.
- X Developers forum - 'Introducing X API Playground: Local Development Tool for X API v2' by @taycaldwell: the go install command, the localhost:8080 default, and the stated use cases of local development, API learning and CI/CD (posted 23 December 2025)
- GitHub - xdevplatform/playground README: install routes, the 'playground start' / 'status' / 'refresh' commands, the management endpoints, and the usage and cost tracking endpoints (accessed 18 October 2026)
- GitHub - xdevplatform/playground DOCUMENTATION.md: the OpenAPI cache at ~/.playground/.playground-openapi-cache.json, the 24-hour refresh rule, the api.x.com/2/openapi.json source, and the default-off rate limit and error simulation blocks (accessed 18 October 2026)
- GitHub - xdevplatform/playground internal/playground/credits.go: pricingURL set to https://console.x.com/api/credits/pricing, the 24-hour pricing cache, the hardcoded fallback table, and the 24-hour de-duplication window on event-type resources (accessed 18 October 2026)
- X developer docs - 'Tools & Libraries': the API Playground card describing a local mock server for testing X API v2 endpoints without using real credits (accessed 18 October 2026)
- X developer docs - 'Pricing': the per-resource read table, Post: Create (with URL) at $0.200 per request, Owned Reads at $0.001, the 3 million Post read cap per billing cycle, and the 24-hour UTC deduplication rule (accessed 18 October 2026)
Product designer and indie hacker. Runs the agent on his own X account every day and writes up what the data shows, including when it's inconvenient.
Follow on X →