X (formerly Twitter) API, OAuth 2.0 user context
Curated guide, researched and checked, updated 2026-10-30 · x.com
About 30 minutes to a working OAuth app; gated by prepaid pay-per-use credits and strict AI and automation policy rather than review
Registering an X app takes about 30 minutes with no human review. You sign in at console.x.com, accept the Developer Agreement, describe your use case, create an app, and enable OAuth 2.0 with PKCE. The hard part is price and policy, not approval. Since February 2026 the X API is pay-per-use only: there is no free read tier, every read and write is billed from prepaid credits (post read $0.005, post create $0.015, post with a URL $0.20), and the Developer Agreement forbids using X content to train foundation or frontier models.
How long until your users can connect
Depends on who connects and what you ask forStandard pay-per-use access needs no manual review: credentials are generated when you create the app, and access works once credits are purchased. Approval is needed only for Enterprise volume (above the 3M post-read monthly cap) or special access such as Ads API, through X sales forms. X publishes no timeline for those. X may also review or enforce against your use case at any time after the fact, because the use case description is binding.
Choose your launch path to filter the steps
Do these first
- 1Estimate your agent's monthly reads and writes and price them with the published rates (post read $0.005, post create $0.015, post with URL $0.20) before committing
- 2Sign in at console.x.com, accept the Developer Agreement, and write a precise use case description
- 3Add a card, buy a small credit pack, and set a spending limit
- 4Create one app, choose Type of app 'Web App, Automated App or Bot', and register exact callback URIs including http://127.0.0.1 for local dev
- 5Implement PKCE with scopes tweet.read users.read offline.access (plus tweet.write if posting) and test with your own account
What you're actually registering
App in the X Developer Console (console.x.com). One X app represents your product. Its OAuth 2.0 Client ID (and Client Secret for confidential clients) drives the Authorization Code Flow with PKCE at https://x.com/i/oauth2/authorize. Each end user who connects creates one user-context grant and token set bound to that app. All API usage by all of your users is billed to your developer account's credit balance. The Developer Policy forbids registering multiple apps for the same or overlapping use case, so do not create one app per customer. There is no dynamic client registration.
Access tokens last 2 hours. You get a refresh token only if you request the offline.access scope; without it, users must re-authorize every 2 hours. Authorization codes must be exchanged within 30 seconds. Confidential clients (Web App, Automated App or Bot) authenticate to /2/oauth2/token with HTTP Basic (client_id:client_secret). Public clients (Native App, Single Page App) send client_id in the body and use PKCE only. X keeps a single live grant per (app, user), so the same user authorizing the same app from a second client revokes the first client's tokens. OAuth 2.0 works only with API v2. Existing OAuth 1.0a user tokens can be converted with the token-exchange grant.
What you'll need
- X account and Developer Agreement acceptance
Sign in at console.x.com with an X account (minimum age 13 under the X Terms) and accept the Developer Agreement and Policy. Use an account your company controls, not a personal one, because the app and billing live under it.
- Use case description
Describe what your app does with X data. This description is binding: substantive deviations can lead to suspension, and you must notify X and get approval before using X content for a new purpose.
- Payment card and prepaid credits
A credit or debit card (prepaid cards do not earn incentives). API calls are blocked when the balance is zero or negative. Configure auto-recharge (minimum $5) and a per-billing-cycle spending limit.
- Callback URL(s) registered exactly
Up to 10 callback URLs per app. They must match exactly, including the trailing slash, and use https in production. For local development the apps doc says to use http://127.0.0.1 rather than localhost (but see the contradiction in the verification log).
- Website URL
The app's authentication settings require a Website URL alongside the callback URI. Use your product's homepage.
- Automation Rules compliance for write actions
Posting, following, liking or DMing on users' behalf must follow the Automation Rules. That means explicit consent before automated replies or DMs, honouring opt-outs, no bulk or aggressive actions, and no identical content across accounts. Bot accounts must disclose they are bots and who runs them.
- No model training on X content
Clause (k) of the Developer Agreement prohibits using the X API or X Content to fine-tune or train a foundation or frontier model. An agent may read and act on content at inference time, but must not pipe it into training datasets.
- Enterprise contract
Required for more than 3M post reads per monthly billing cycle, or for Enterprise-only features such as team management.
Step by step
7 steps- 1You do this
Sign in to the Developer Console and accept the Developer Agreement
About 5–15 min
Requires your X login and a legal acceptance of the Developer Agreement and Policy, which an agent must not do for you.
- Go to https://console.x.com and sign in with the X account that should own the app (preferably a company account).
- Read the Developer Agreement and Developer Policy. Pay attention to clause (k), the ban on training models on X content, and the Automation Rules.
- Accept the Developer Agreement and Policy.
- Complete the profile by describing how you will use the API. Be specific: say that end users connect their own accounts through OAuth 2.0 and what the agent reads and writes. This description is binding.
- Use case description
AI assistant that lets each user connect their own X account via OAuth 2.0 to read their timeline/mentions and draft or publish posts they approve. No X content is used for model training; no automated replies without explicit consent.- Adapt to what your agent actually does. Deviating later can trigger enforcement.
- 2You do this
Add a payment card, buy credits, and set a spending limit
About 5–15 min
Entering payment details and purchasing credits must be done by a human.
- In the Developer Console open Billing and use Billing information, then Add payment method, to save a credit or debit card. Prepaid cards do not earn the incentive.
- Buy a small amount of credits (for example $5-$10). The first purchase with your first eligible card grants a one-time $20 free credit, which expires 3 months after grant.
- Set a Spending limit per billing cycle so a runaway agent cannot drain the balance.
- Optionally enable auto-recharge (Recharge amount and Trigger threshold). The first successful auto-recharge is matched up to $50. Auto-recharge fires at most once per 5 minutes and is paused at zero or negative balance.
- Check current per-endpoint rates in the console. Docs list post read $0.005, user read $0.010, post create $0.015, post create with URL $0.200, and Owned Reads $0.001 (as of 2026-10-30).
- 3You do this
Create the app
About 3–10 min
Needs your authenticated console session. An agent can draft the name and description.
- From the Developer Console dashboard click New App (some doc pages call it Create App).
- Enter the app name, description and use case. Create one app per use case; do not create one app per customer, which violates the policy against multiple apps for one use case.
- Credentials shown at creation (API Key and Secret, Bearer Token) are displayed only once. Copy them into a secret manager immediately.
- App name
<YourProduct> Agent- Shown to users on the X consent screen.
- 4You do this
Enable OAuth 2.0: app permissions, type of app, callback URI, website URL
About 5–15 min
Done in the authenticated console. An agent can tell you the exact values to paste.
- Open the app's settings and find the authentication settings. On the legacy portal this was 'User authentication settings', then 'Set up' (or 'Edit').
- Set App Permissions. These apply to OAuth 1.0a; OAuth 2.0 access is governed by scopes, but choose 'Read and write' (or 'Read and write and Direct message' if you need DMs) so 1.0a tokens match.
- Set Type of app: 'Web App, Automated App or Bot' if your agent backend can keep a secret (confidential client, gets a Client Secret). Choose 'Native App' or 'Single page App' only for public clients (PKCE only, no secret).
- Under Callback URI / Redirect URL add each exact redirect URI (max 10), for example https://app.example.com/oauth/x/callback, plus a local dev URI.
- Enter the Website URL (your product homepage), and optionally organization name, terms of service and privacy policy URLs.
- Save. Then open Keys and tokens and copy the OAuth 2.0 Client ID (the long string, not the numeric app ID) and, for confidential clients, the Client Secret.
- Type of app
Web App, Automated App or Bot- Confidential client. Token requests use HTTP Basic client_id:client_secret; X rejects client_secret_post per its Ads MCP doc.
- Callback URI / Redirect URL
https://<your-domain>/oauth/x/callback- Exact match including trailing slash.
- Callback URI / Redirect URL (local)
http://127.0.0.1:8080/callback- The apps doc says to use 127.0.0.1, not localhost.
- Website URL
https://<your-domain>
Apps: OAuth 2.0 app types and callback URLsOAuth 2.0 Authorization Code Flow with PKCEPointer ready: highlights “User authentication settings” - 5An agent can do this
Implement Authorization Code Flow with PKCE and refresh
About 30–120 min
Pure code work an AI agent can do once Client ID, Secret and callback are in env vars.
- Build the authorize URL https://x.com/i/oauth2/authorize with response_type=code, client_id, redirect_uri, scope (space-separated), state (up to 500 chars), code_challenge and code_challenge_method=S256.
- Request minimal scopes. A typical agent needs tweet.read users.read offline.access, plus tweet.write to post, media.write to upload media, and dm.read/dm.write only if needed.
- Always include offline.access. Without it no refresh token is issued and users must re-consent every 2 hours.
- On callback verify state, then POST to https://api.x.com/2/oauth2/token (Content-Type application/x-www-form-urlencoded) with code, grant_type=authorization_code, redirect_uri, and code_verifier, within 30 seconds. Confidential clients send Authorization: Basic base64(client_id:client_secret); public clients send client_id in the body.
- Refresh with grant_type=refresh_token and store the newly returned refresh token every time.
- Call GET https://api.x.com/2/users/me to identify the connected user (75 requests per 15 min per user).
- scope
tweet.read users.read offline.access- Add tweet.write / media.write / like.write etc. only as needed.
- token endpoint
https://api.x.com/2/oauth2/token- authorize endpoint
https://x.com/i/oauth2/authorize
- 6Agent prepares, you submit
Connect a test account end to end and watch costs
About 10–30 min
The agent can run the flow and API calls; a human must click Authorize on X's consent screen while logged in.
- Open your authorize URL, log in to X as a test user, and click Authorize app.
- Exchange the code, call /2/users/me, then make one read and one write call.
- Check Developer Console usage. Remember a post containing a URL costs $0.20 versus $0.015 without one, and reads are charged per returned resource, deduplicated per 24-hour UTC day.
- Optionally poll GET /2/usage/tweets to track daily post consumption.
- 7Agent prepares, you submit
Production: compliance, bot labelling, and Enterprise if needed
About 1–4 hours
The agent can implement consent gates and rate-limit handling; a human owns policy attestations, bot account settings, and any Enterprise contract.
- Gate all automated replies, mentions and DMs behind explicit user consent, and honour opt-outs immediately.
- If the agent operates its own bot account, label it under the account's Settings > Your account > Automation and state in the bio who runs it.
- Handle HTTP 429 using the x-rate-limit headers. POST /2/tweets allows 100 per 15 min per user and 10,000 per 24h per app.
- Exclude all X content from any model fine-tuning or training pipelines (Developer Agreement clause (k)).
- If you will exceed 3M post reads per month, submit the Enterprise API interest form.
What can block you, and the way around
- API calls fail with out-of-credits / payment required
You'll see: A newly created app's calls are rejected even though the credentials are valid.
Do this: Buy credits in Developer Console > Billing. There is no free read allowance for new accounts. If the balance went slightly negative, add credits to cover it. Raise the auto-recharge amount if bursts drain a top-up within 5 minutes.
- 'Callback URL not approved for this client application' (code 415)
You'll see: The authorize redirect or token exchange errors immediately.
Do this: Register the exact redirect_uri, including protocol, port and trailing slash, in the app's callback list, and percent-encode it in the query string. For local dev the apps doc recommends http://127.0.0.1 instead of localhost.
- Users disconnected every 2 hours
You'll see: Calls return 401 two hours after connection and there is no refresh token to use.
Do this: Add offline.access to the requested scopes and have users reconnect. Persist the rotated refresh token after each refresh.
- invalid_request on code exchange
You'll see: The token exchange fails intermittently, especially when debugging.
Do this: Exchange the auth code within 30 seconds, send the same redirect_uri and the original code_verifier, and for confidential clients use an HTTP Basic header rather than client_secret in the body.
- Tokens revoked when the same user connects through another client
You'll see: A user's earlier tokens stop working after they authorize the same app from a different client or environment.
Do this: X keeps one live grant per (app, user). Use separate apps for separate clients or environments (for example dev and prod), which docs also recommend.
- App suspended for policy violation
You'll see: Email from the X platform team and the app shows as suspended.
Do this: Common causes are automated replies or DMs without consent, duplicate or bulk posting, or deviating from the stated use case. Fix the behaviour and appeal through the Platform Help Form (help.x.com/forms/platform).
- Costs explode on link posts or timeline reads
You'll see: The credit balance drains far faster than expected.
Do this: A post with a URL costs $0.20 versus $0.015 without one, and reads are billed per returned resource. Cap max_results, cache (24h UTC dedup applies), use Owned Reads where possible, and set a spending limit.
What we checked
- CorrectedCurrent access model and whether the Free/Basic/Pro tiers still existCommonly repeated advice (Free = write-only around 500 posts/month, Basic $200/month for reads, Pro $5,000/month) is outdated. docs.x.com/x-api/getting-started/pricing now describes only pay-per-usage credits plus Enterprise: no subscriptions, per-resource reads and per-request writes, capped at 3M post reads per monthly billing cycle. The legacy portal sign-up path (developer.x.com/en/portal/petition/essential/basic-info) still appears in older doc pages.Read against official docs, 2026-10-30
- CorrectedDeveloper console locationDocs now send developers to console.x.com (the Developer Console), not developer.x.com/en/portal/dashboard. Some older doc pages still link the old portal. The pointer urlPattern covers both.Read against official docs, 2026-10-30
- CorrectedFree credit incentive for new accountsThe $20 card-add credit is now granted only after the first credit purchase (changed October 13, 2026). Adding a card alone no longer qualifies. Incentive credits expire 3 months after grant and are spent first.Read against official docs, 2026-10-30
- ConfirmedAccess token lifetime and refresh tokensAccess tokens from the PKCE flow are valid for two hours. A refresh token is issued only with the offline.access scope. Auth codes expire after 30 seconds.Read against official docs, 2026-10-30
- CorrectedLocalhost vs 127.0.0.1 for local callback URLsThe Apps doc says local development should use http://127.0.0.1, not localhost. However, X's own MCP docs register http://localhost:8080/callback for the xurl bridge and Claude Code. The docs contradict each other; 127.0.0.1 is the safer documented choice.Read against official docs, 2026-10-30
- ConfirmedAI/model-training restriction in Developer AgreementDeveloper Agreement (Last Updated April 27, 2026), Section restrictions clause (k), forbids using the X API or X Content to fine-tune or train a foundation or frontier model.Read against official docs, 2026-10-30
- ConfirmedOne live grant per (app, user)The X Ads MCP doc states that signing in from a second client revokes the first client's tokens for the same app and user. This is rarely mentioned in OAuth guides and matters for agents with multiple clients.Read against official docs, 2026-10-30
- ConfirmedDynamic client registration for MCP-style agentsThe X MCP doc says there is no dynamic client registration. You must create your own developer app and register its callback.Read against official docs, 2026-10-30
- ConfirmedRate limits for key endpointsPOST /2/tweets: 10,000/24h per app, 100/15min per user. GET /2/users/me: 75/15min per user. GET /2/tweets/search/recent: 450/15min per app, 300/15min per user.Read against official docs, 2026-10-30
- ConfirmedAutomated: developer console (https://console.x.com/)Loaded: "Developer Console".Live HTTP probe, 2026-10-30
- ConfirmedAutomated: authorize endpoint with a fake client_id (https://x.com/i/oauth2/authorize)Endpoint answered HTTP 200 ("Authorize app / X").Live HTTP probe, 2026-10-30
- ConfirmedAutomated: 27 quotes re-fetched and matched against their cited pages27 of 27 quotes found verbatim in the live page HTML. 15/16 source URLs returned HTTP 200.Read against official docs, 2026-10-30
What we couldn't confirm
- The exact current console labels for OAuth settings are uncertain. 'User authentication settings' and 'Set up' are legacy developer-portal labels, while current docs mention only App Permissions / Type of app / Callback URI / Redirect URL / Website URL / Keys and tokens. Not verified by a console walk-through.
- Whether Website URL is still mandatory in the new console is not stated in current official docs.
- Free tier: official docs list no free tier. The date it closed to new sign-ups (reported as February 6, 2026) and the treatment of legacy Basic/Pro subscribers (reported migrations around June 1 and September 1, 2026) come from community sources only.
- The Developer Agreement (Last Updated April 27, 2026) still contains monthly 'Subscription Terms' language that does not match the pay-per-use docs.
- Refresh-token lifetime and whether refresh tokens are single-use (rotating) are not documented. Community reports say they rotate; treat as unverified and always store the latest.
- Enterprise onboarding time is not published. The 2-8 week range is an unverified estimate.
- The 'Post: Create (summoned)' price ($0.010) is listed, but the qualifying conditions were not found in the pages reviewed.
- The Automation Rules page on help.x.com could not be fetched directly (bot protection). Its requirements are cited via the Developer Policy summary.
- Prices were read from docs.x.com on 2026-10-30 and X states they are subject to change. The Developer Console is the source of truth.
Sources
- s1X API pay-per-usage pricing and credits (official docs, accessed 2026-10-30)
- s2Free credit incentives for X API pay-per-use accounts (official docs, accessed 2026-10-30)
- s3Developer Console (official docs, accessed 2026-10-30)
- s4Getting Access (official docs, accessed 2026-10-30)
- s5Apps (official docs, accessed 2026-10-30)
- s6OAuth 2.0 Authorization Code Flow with PKCE (reference) (official docs, accessed 2026-10-30)
- s7OAuth 2.0 Authorization Code Flow with PKCE (how to connect) (official docs, accessed 2026-10-30)
- s8Rate limits (official docs, accessed 2026-10-30)
- s9X Developer Agreement (official policy, accessed 2026-10-30)
- s10X Developer Policy (official policy, accessed 2026-10-30)
- s11Restricted uses of the X API (official policy, accessed 2026-10-30)
- s12MCP servers (X MCP and Docs MCP) (official docs, accessed 2026-10-30)
- s13X Ads MCP (official docs, accessed 2026-10-30)
- s14X shifts API to Pay-Per-Use; free plan effectively discontinued (roboin) (community, accessed 2026-10-30)
- s15X is moving legacy Basic API plans to pay-per-use (maxrave.dev) (community, accessed 2026-10-30)
- s16X Automation Rules (official policy, accessed 2026-10-30)
- p1Live probe (console): Loaded: "Developer Console". (probe, accessed 2026-10-30)
- p2Live probe (authorize-endpoint): Endpoint answered HTTP 200 ("Authorize app / X"). (probe, accessed 2026-10-30)