# AGENT
Source: https://docs.x.com/AGENT
# X Developer Platform — Agent Instructions
This document provides guidance for AI agents, coding assistants, and LLM-based tools interacting with the X Developer Platform documentation at [https://docs.x.com](https://docs.x.com).
## Preferred Documentation Access Methods
**Always prefer these methods for the most accurate, up-to-date, and agent-friendly content:**
1. **llms.txt** (recommended starting point)
* [https://docs.x.com/llms.txt](https://docs.x.com/llms.txt) — Small, curated root index with links to section-specific indexes.
* Section indexes (follow the links in the root):
* [https://docs.x.com/x-api/llms.txt](https://docs.x.com/x-api/llms.txt) (X API v2 — 370+ pages)
* [https://docs.x.com/enterprise-api/llms.txt](https://docs.x.com/enterprise-api/llms.txt)
* [https://docs.x.com/x-ads-api/llms.txt](https://docs.x.com/x-ads-api/llms.txt)
* [https://docs.x.com/xdks/llms.txt](https://docs.x.com/xdks/llms.txt) (Python + TypeScript XDKs)
2. **llms-full.txt** — Complete documentation as a single Markdown file for maximum context:
* [https://docs.x.com/llms-full.txt](https://docs.x.com/llms-full.txt)
3. **Raw Markdown for any individual page**
* Append `.md` to any documentation URL.
* Example: `https://docs.x.com/x-api/posts/get-post-by-id.md`
* Every page supports this. Use it instead of the HTML view when possible.
4. **MCP Server** (for tool-using agents)
* [https://docs.x.com/tools/mcp](https://docs.x.com/tools/mcp) — Hosted X MCP (`api.x.com/mcp` via `xurl`) + documentation search MCP.
5. **skill.md** (capability summary)
* [https://docs.x.com/skill.md](https://docs.x.com/skill.md) — Structured description of every action an agent can perform with the X API (agentskills.io format).
## Site Structure & Navigation
* **X API v2** (`/x-api/...`): Posts, Users, Direct Messages, Lists, Spaces, Media, Streams (filtered + volume), Compliance, Webhooks, Account Activity, Trends, News, Usage, Connections.
* **Enterprise APIs** (`/enterprise-api/...`): Account Activity (webhooks), X Activity (XAA), GNIP/PowerTrack historical & real-time, Compliance.
* **Ads API** (`/x-ads-api/...`): Campaign Management, Creatives, Audiences, Analytics, Measurement, Catalog.
* **SDKs (XDKs)** (`/xdks/python/...` and `/xdks/typescript/...`): Official client libraries with full type coverage, pagination, and streaming helpers.
* **Fundamentals**: Authentication, rate limits, data dictionary, expansions, fields, pagination, versioning, consistency.
* **AI & Agent Tools** (`/tools/ai`, `/tools/llms-txt`, `/tools/skill-md`, `/tools/mcp`).
All pages are available in the navigation tree defined in `docs.json`.
## Important Technical Notes for Agents
* **Authentication**: The platform supports OAuth 1.0a (user context), OAuth 2.0 (user context + PKCE, app-only Bearer), and Basic Auth for some enterprise endpoints. See `/fundamentals/authentication/...`.
* **Rate Limits**: Most endpoints have both app-level and user-level rate limits. See `/fundamentals/rate-limits.md` and per-endpoint documentation.
* **Data Model**: Use the official data dictionary, fields, expansions, and metrics pages. Posts, Users, and Spaces are the core objects.
* **Real-time Data**: Filtered Stream, Volume Streams, Account Activity webhooks, and X Activity (XAA) are the primary real-time mechanisms.
* **Compliance & Safety**: Always respect developer terms, display requirements, and restricted use cases. See `/developer-guidelines.md` and `/developer-terms/...`.
## How to Use This Documentation Effectively
* Start with the root `llms.txt` to discover relevant pages.
* Fetch individual pages via the `.md` suffix for clean, structured Markdown.
* For deep context on the entire platform, load `llms-full.txt`.
* For structured capabilities (what actions are possible), load `skill.md`.
* For live tool calling against the X API, use the MCP server.
* When writing code, prefer the official Python or TypeScript XDKs (full references available in their `llms.txt` files).
## Do Not
* Rely solely on the HTML-rendered pages when a clean Markdown alternative exists.
* Assume deprecated v1.1 endpoints are still primary (focus on v2 and Enterprise equivalents).
* Ignore rate limits, authentication context (app-only vs user context), or pagination requirements.
* Generate code that violates the X Developer Agreement or Display Requirements.
## Additional Resources
* OpenAPI spec: [https://docs.x.com/openapi.json](https://docs.x.com/openapi.json) (or [https://api.x.com/2/openapi.json](https://api.x.com/2/openapi.json))
* Changelog: [https://docs.x.com/changelog.md](https://docs.x.com/changelog.md) (RSS feed: [https://docs.x.com/changelog/rss.xml](https://docs.x.com/changelog/rss.xml))
* Status page: [https://developer.x.com/status](https://developer.x.com/status) (incident history: [https://docs.x.com/incidents.md](https://docs.x.com/incidents.md))
* Developer Guidelines: [https://docs.x.com/developer-guidelines.md](https://docs.x.com/developer-guidelines.md)
* Support & Community: [https://devcommunity.x.com](https://devcommunity.x.com)
This documentation is designed to be consumed reliably by AI agents. Use the machine-readable formats (`llms.txt` family, `.md` suffix, `skill.md`, MCP) for the best results.
# AGENTS
Source: https://docs.x.com/AGENTS
# X Developer Platform — Agent Instructions
This document provides guidance for AI agents, coding assistants, and LLM-based tools interacting with the X Developer Platform documentation at [https://docs.x.com](https://docs.x.com).
## Preferred Documentation Access Methods
**Always prefer these methods for the most accurate, up-to-date, and agent-friendly content:**
1. **llms.txt** (recommended starting point)
* [https://docs.x.com/llms.txt](https://docs.x.com/llms.txt) — Small, curated root index with links to section-specific indexes.
* Section indexes (follow the links in the root):
* [https://docs.x.com/x-api/llms.txt](https://docs.x.com/x-api/llms.txt) (X API v2 — 370+ pages)
* [https://docs.x.com/enterprise-api/llms.txt](https://docs.x.com/enterprise-api/llms.txt)
* [https://docs.x.com/x-ads-api/llms.txt](https://docs.x.com/x-ads-api/llms.txt)
* [https://docs.x.com/xdks/llms.txt](https://docs.x.com/xdks/llms.txt) (Python + TypeScript XDKs)
2. **llms-full.txt** — Complete documentation as a single Markdown file for maximum context:
* [https://docs.x.com/llms-full.txt](https://docs.x.com/llms-full.txt)
3. **Raw Markdown for any individual page**
* Append `.md` to any documentation URL.
* Example: `https://docs.x.com/x-api/posts/get-post-by-id.md`
* Every page supports this. Use it instead of the HTML view when possible.
4. **MCP Server** (for tool-using agents)
* [https://docs.x.com/tools/mcp](https://docs.x.com/tools/mcp) — Hosted X MCP (`api.x.com/mcp` via `xurl`) + documentation search MCP.
5. **skill.md** (capability summary)
* [https://docs.x.com/skill.md](https://docs.x.com/skill.md) — Structured description of every action an agent can perform with the X API (agentskills.io format).
## Site Structure & Navigation
* **X API v2** (`/x-api/...`): Posts, Users, Direct Messages, Lists, Spaces, Media, Streams (filtered + volume), Compliance, Webhooks, Account Activity, Trends, News, Usage, Connections.
* **Enterprise APIs** (`/enterprise-api/...`): Account Activity (webhooks), X Activity (XAA), GNIP/PowerTrack historical & real-time, Compliance.
* **Ads API** (`/x-ads-api/...`): Campaign Management, Creatives, Audiences, Analytics, Measurement, Catalog.
* **SDKs (XDKs)** (`/xdks/python/...` and `/xdks/typescript/...`): Official client libraries with full type coverage, pagination, and streaming helpers.
* **Fundamentals**: Authentication, rate limits, data dictionary, expansions, fields, pagination, versioning, consistency.
* **AI & Agent Tools** (`/tools/ai`, `/tools/llms-txt`, `/tools/skill-md`, `/tools/mcp`).
All pages are available in the navigation tree defined in `docs.json`.
## Important Technical Notes for Agents
* **Authentication**: The platform supports OAuth 1.0a (user context), OAuth 2.0 (user context + PKCE, app-only Bearer), and Basic Auth for some enterprise endpoints. See `/fundamentals/authentication/...`.
* **Rate Limits**: Most endpoints have both app-level and user-level rate limits. See `/fundamentals/rate-limits.md` and per-endpoint documentation.
* **Data Model**: Use the official data dictionary, fields, expansions, and metrics pages. Posts, Users, and Spaces are the core objects.
* **Real-time Data**: Filtered Stream, Volume Streams, Account Activity webhooks, and X Activity (XAA) are the primary real-time mechanisms.
* **Compliance & Safety**: Always respect developer terms, display requirements, and restricted use cases. See `/developer-guidelines.md` and `/developer-terms/...`.
## How to Use This Documentation Effectively
* Start with the root `llms.txt` to discover relevant pages.
* Fetch individual pages via the `.md` suffix for clean, structured Markdown.
* For deep context on the entire platform, load `llms-full.txt`.
* For structured capabilities (what actions are possible), load `skill.md`.
* For live tool calling against the X API, use the MCP server.
* When writing code, prefer the official Python or TypeScript XDKs (full references available in their `llms.txt` files).
## Do Not
* Rely solely on the HTML-rendered pages when a clean Markdown alternative exists.
* Assume deprecated v1.1 endpoints are still primary (focus on v2 and Enterprise equivalents).
* Ignore rate limits, authentication context (app-only vs user context), or pagination requirements.
* Generate code that violates the X Developer Agreement or Display Requirements.
## Additional Resources
* OpenAPI spec: [https://docs.x.com/openapi.json](https://docs.x.com/openapi.json) (or [https://api.x.com/2/openapi.json](https://api.x.com/2/openapi.json))
* Changelog: [https://docs.x.com/changelog.md](https://docs.x.com/changelog.md) (RSS feed: [https://docs.x.com/changelog/rss.xml](https://docs.x.com/changelog/rss.xml))
* Status page: [https://developer.x.com/status](https://developer.x.com/status) (incident history: [https://docs.x.com/incidents.md](https://docs.x.com/incidents.md))
* Developer Guidelines: [https://docs.x.com/developer-guidelines.md](https://docs.x.com/developer-guidelines.md)
* Support & Community: [https://devcommunity.x.com](https://devcommunity.x.com)
This documentation is designed to be consumed reliably by AI agents. Use the machine-readable formats (`llms.txt` family, `.md` suffix, `skill.md`, MCP) for the best results.
# X API changelog and release notes
Source: https://docs.x.com/changelog
Release notes and version history for the X API v2, Enterprise APIs, Ads API, SDKs, streaming, webhooks, and the developer platform.
To subscribe to updates, please [**“Turn on notifications”**](https://help.x.com/en/managing-your-account/notifications-on-mobile-devices#:~:text=In%20the%20top%20menu,%20you,you%20would%20like%20to%20receive) for [**@API**](https://x.com/api). You can also follow this changelog in your feed reader via the [**RSS feed**](https://docs.x.com/changelog/rss.xml).
### Updated `video_total_views` definition
We updated the definition of the `video_total_views` metric in the `VIDEO` metrics group of the [X Ads API Analytics endpoints](/x-ads-api/analytics). It now reports views that are 100% in-view for at least 3 seconds, plus any view where a user manually clicks the play button.
The previous definition (at least 50% in-view for 2 seconds, per the MRC standard) no longer applies. The prior "100% in-view for 3 seconds" definition remains available as the `video_3s100pct_views` metric, and you can continue bidding on it via the `VIEW_3S_100PCT` bid unit.
### Mute and block events for X Activity API
Today, we added mute and block events to the [X Activity API](https://docs.x.com/x-api/activity/introduction). You can now subscribe by User ID to receive real-time notifications when a user mutes or unmutes (`mute.mute`, `mute.unmute`) or blocks or unblocks (`block.block`, `block.unblock`) another user.
These are private events: they require user-context (OAuth 2.0) authentication with the `mute.read` or `block.read` scope, respectively, and the `user_id` filter matches the user performing the action.
### Articles draft and publish endpoints
Today, we added [new endpoints](/x-api/articles/introduction) for drafting and publishing Articles via the X API.
### Post create and delete events for X Activity API
Today, we added `post.create` and `post.delete` events to the [X Activity API](https://docs.x.com/x-api/activity/introduction). You can now subscribe by User ID to receive real-time notifications when a user creates or deletes a Post.
For basic per-user post activity, use XAA. For advanced keyword filtering and the full set of Filtered Stream operators, continue to use the [Filtered Stream](/x-api/posts/filtered-stream/introduction).
### `paid_partnership` Post field
Added support for the `paid_partnership` field on Posts.
* When creating a Post via `POST /2/tweets`, set `"paid_partnership": true` to indicate the Post is a paid partnership (i.e., the author is disclosing that it contains paid promotion). The Post will be labeled as a paid promotion.
* When reading Posts, request `tweet.fields=paid_partnership` to retrieve the value (`true` if the author has disclosed the Post as containing paid promotion).
### Search endpoints migrating to new search index
Today, we migrated the X API v2 search endpoints (`/2/tweets/search/recent`, `/2/tweets/search/all`, `/2/tweets/counts/recent`, `/2/tweets/counts/all`) to the new X core platform search index. This brings major performance improvements, dramatically fewer 503 errors, and three new precision operators: `min\_likes:`, `min\_replies:`, and `min\_reposts:`. Note: retweets are no longer returned in keyword-based search results (the Filtered Stream is unchanged). Learn more [here](https://devcommunity.x.com/t/important-update-x-api-search-endpoints-migrating-to-new-search-index/264595).
### X API pricing update: Owned Reads now \$0.001
Effective April 20, 2026, we introduced new **"Owned Reads"** pricing at **\$0.001** per resource (1,000 for **\$1**) for qualifying endpoints when accessing your own data:\
`GET /2/users/{id}/bookmarks`, `/blocking`, `/muting`, `/pinned_lists`, `/tweets`, `/mentions`, `/liked_tweets`, `/followers`, `/following`, `/owned_lists`, `/followed_lists`, and `/list_memberships`.
We also updated writes — `POST /2/tweets` is now **\$0.015** per post, and Posts containing a URL are **\$0.20** per Post (summoned replies remain **\$0.01**).
Following, Likes, and Quote-Posts via the API have been removed from all self-serve tiers.
Learn more [here](https://devcommunity.x.com/t/x-api-pricing-update-owned-reads-now-0-001-other-changes-effective-april-20-2026/263025).
### Deprecation of Account Activity replay endpoint
Today, we announced the deprecation of `POST /2/account_activity/replay/webhooks/{webhook_id}/subscriptions/all`, effective March 25, 2026 at 12:00 PM ET. Use the new consolidated `POST /2/webhooks/replay` endpoint instead — it provides identical functionality. Learn more [here](https://devcommunity.x.com/t/deprecation-of-account-activity-replay-endpoint/260354).
### Direction filter for X Activity API subscriptions
Today, we added an optional `direction` filter to X Activity API subscriptions. Subscribers can now scope DM and chat events to `sent`, `received`, or both, reducing noise when only outgoing or incoming events are needed.
### Updates to event types format in the X Activity API
Today, we announced changes to event type naming in the X Activity API, effective March 18, 2026. PascalCase event types (e.g., `ProfileBioUpdate`) are being deprecated in favor of a dot-separated lowercase format (e.g., `profile.update.bio`). Update any filtering, switch statements, or deserialization logic that relies on the old values. Learn more [here](https://devcommunity.x.com/t/updates-to-event-types-format-in-the-x-activity-api/259765).
### Legacy Direct Message events in the X Activity API
Today, we added legacy DM events (`dm.received`, `dm.sent`, `dm.read`, `dm.indicate_typing`) to the [X Activity API](https://docs.x.com/x-api/activity/introduction). This brings DM event delivery from the Account Activity API into the lower-latency XAA pipeline.
### Addressing LLM-generated spam
Today, we made changes to reduce automated, low-quality replies on X. Programmatic replies via `POST /2/tweets` are now only permitted when the original Post's author has "summoned" the replier (by @mentioning that account or quoting one of its Posts). Additional restrictions apply to programmatically @mentioning or quoting users. These changes affect self-serve tiers only — Enterprise access is not impacted. Learn more [here](https://devcommunity.x.com/t/x-api-v2-update-addressing-llm-generated-spam/257909).
### Launch of X API Pay-Per-Use pricing
Today, we officially launched **X API Pay-Per-Use** pricing — a flexible credit-based model built for indie builders, startups, and hobbyists. Highlights:
* A new Developer Console at [console.x.com](https://console.x.com)
* The [XDK (X Developer Kit)](https://docs.x.com/xdks/overview) with first-party Python and TypeScript SDKs
* An interactive [Playground](https://github.com/xdevplatform/playground) for testing
* An [MCP server](https://github.com/xdevplatform/xmcp) for AI models
* Earn up to **20% back in xAI/Grok API credits** on every dollar spent on the X API
Public Utility Apps continue to receive free scaled access. Recently active Legacy Free tier users receive a one-time \$10 voucher. Basic and Pro plans remain available, and existing subscribers can opt in to Pay-Per-Use. Learn more [here](https://devcommunity.x.com/t/announcing-the-launch-of-x-api-pay-per-use-pricing/256476).
### Spaces events in the X Activity API
Today, we added Spaces lifecycle events (`spaces.start`, `spaces.end`) to the [X Activity API](https://docs.x.com/x-api/activity/introduction). Subscribe by User ID to be notified in real time when a Space starts or ends.
### Deprecating count-based operators
Today, we deprecated the `min\_likes`, `min\_replies`, and `min\_reposts` operators on `/2/tweets/search/recent` and `/2/tweets/search/all`. This change does not affect the equivalent operators in the Filtered Stream. We are evaluating how to best re-enable these in the future. Learn more [here](https://devcommunity.x.com/t/deprecating-count-based-operators-in-the-x-api/254933).
### OAuth 2.0 support added to Account Activity API v2
Today, we added full OAuth 2.0 support to the [Account Activity API v2](https://docs.x.com/x-api/account-activity/introduction). Developers can now create subscriptions using OAuth 2.0 with fine-grained scopes (e.g., `follow.read`) instead of the all-or-nothing OAuth 1.0a permission model. Existing OAuth 1.0a-based integrations continue to work without disruption — when present, OAuth 1.0a permissions fully override OAuth 2.0 scopes. Learn more [here](https://devcommunity.x.com/t/announcement-oauth2-0-support-added-to-account-activity-api-v2/254633).
### Introducing X API Playground
Today, we introduced the [X API Playground](https://github.com/xdevplatform/playground) — a self-hosted local server that emulates X API v2 endpoints. Develop and test integrations without making real API calls or hitting rate limits. Includes realistic mock data, state persistence, OpenAPI validation, rate-limit simulation, and a web UI. Install with `go install github.com/xdevplatform/playground/cmd/playground@latest`. Learn more [here](https://devcommunity.x.com/t/introducing-x-api-playground-local-development-tool-for-x-api-v2/253442).
### Launch of news endpoints
Today, we launched the new [News endpoints](https://docs.x.com/x-api/news/introduction) in the X API v2:
* `GET /2/news/search` — returns trending news stories matching a search query
* `GET /2/news/{id}` — looks up a specific news story by ID
Both endpoints support `news.fields` for selecting fields like `name`, `summary`, `contexts`, `cluster\_posts\_results`, and `last\_updated\_at\_ms`. Learn more [here](https://devcommunity.x.com/t/announcing-the-news-endpoints-in-the-x-api-v2/251833).
### Launch of the Python and TypeScript XDKs
Today, we launched the official first-party [Python](https://docs.x.com/xdks/python/overview) and [TypeScript](https://docs.x.com/xdks/typescript/overview) XDKs (X Developer Kits) for the X API v2. The XDKs handle authentication (Bearer Token, OAuth 2.0 PKCE, OAuth 1.0a), automatic pagination, real-time streaming with reconnect handling, and comprehensive coverage of all v2 endpoints. Install with `pip install xdk` or `npm install @xdevplatform/xdk`. Learn more [here](https://devcommunity.x.com/t/announcing-the-python-and-typescript-xdks-for-the-x-api-v2/250860).
### Keyword filtering for X Activity API subscriptions
Today, we added keyword filtering to X Activity API subscriptions. In addition to filtering by User ID, subscribers can now narrow event delivery further by keyword — useful for News events and other event types where high event volumes warrant additional filtering.
### Verified badge, affiliate badge, and handle update events in the X Activity API
Today, we expanded the [X Activity API](https://docs.x.com/x-api/activity/introduction) to deliver additional profile-related event types:
* `profile.update.verified` — when a user's verification status changes
* `profile.update.affiliate` — when a user's affiliate badge changes
* `profile.update.screenname` — when a user changes their @handle
### X API Pay-Per-Use pricing pilot
Today, we announced a limited closed pilot for a new credit-based, usage-based pricing model. Developers buy credits upfront and are charged per request — no fixed subscription fees and no monthly object caps. Initial pilot rates: $0.005/Post Read, $0.01/User Read, $0.01/DM Event Read, $0.01/Content Create, $0.01/DM Interaction, $0.015/User Interaction. Learn more [here](https://devcommunity.x.com/t/announcing-the-x-api-pay-per-use-pricing-pilot/250253).
### Launch of the X Activity API open beta
Today, we launched the open beta of the [X Activity API](https://docs.x.com/x-api/activity/introduction) — a new suite of endpoints for subscribing to real-time activity events on X with sub-second latency. Subscribe to profile event types (`ProfileBioUpdate`, `ProfilePictureUpdate`, `ProfileBannerUpdate`, `ProfileGeoUpdate`, `ProfileUrlUpdate`), filter by User ID, and receive matching events via persistent HTTP stream (`GET /2/activity/stream`) or webhooks. Subscriptions are managed via `POST /2/activity/subscriptions`. Learn more [here](https://devcommunity.x.com/t/announcing-the-x-activity-api-open-beta/250099).
### Post editing via the X API
Today, we launched the ability to programmatically edit recent Posts via the X API. Use the existing `POST /2/posts` endpoint with a new `edit_options` object containing `previous_post_id`. Requirements: the authenticated user must have X Premium, the Post must be your own, and it must have been created within the last hour. See the updated [Create or Edit Post](https://docs.x.com/x-api/posts/create-post) docs. Learn more [here](https://devcommunity.x.com/t/announcing-post-editing-via-the-x-api/249534).
### Connections API for managing active streaming connections
Today, we launched the [Connections API](https://docs.x.com/x-api/connections/introduction) for managing active streaming connections programmatically:
* `GET /2/connections` — list active and historical streaming connections
* `DELETE /2/connections/all` — terminate all active streaming connections for the app
* `DELETE /2/connections/{endpoint_id}` — terminate connections for a specific streaming endpoint
* `DELETE /2/connections` — terminate specific connections by UUID
This helps developers resolve "TooManyConnections" errors and clean up stale connections without waiting for timeouts.
### Community Notes: evaluate note endpoint
Today, we added the `POST /2/evaluate_note` endpoint to the [Community Notes API](https://docs.x.com/x-api/community-notes/introduction). AI Note Writers can now evaluate a drafted note before submission to receive signals about its potential helpfulness, claim/opinion alignment, and other model feedback.
### Launch of the Filtered Stream Webhooks API
Today, we launched the [Filtered Stream Webhooks API](https://docs.x.com/x-api/webhooks/stream/introduction), which delivers matching public Posts asynchronously to a registered webhook instead of requiring a persistent connection. Rules are managed using the existing `/2/tweets/search/stream/rules` endpoints, and matching Posts (including edit history) are delivered as JSON to your webhook. Available to Enterprise developers; supports 25,000+ rules per project with rules up to 2,048 characters. Learn more [here](https://devcommunity.x.com/t/announcing-the-filtered-stream-webhooks-api/248464).
### Removal of like and follow endpoints from Free tier
To combat abuse, platform manipulation, and fake engagement, we removed `POST /2/users/:id/likes` and `POST /2/users/:id/following` from the X API Free tier, effective immediately. Paid tiers (Basic, Pro, Enterprise) are unaffected. Learn more [here](https://devcommunity.x.com/t/update-to-x-api-free-tier-removal-of-like-and-follow-endpoints/247646).
### PowerStream rules lookup endpoint
Today, we added the `GET /2/powerstream/rules` endpoint, allowing PowerStream customers to programmatically retrieve the rules configured against their PowerStream instances.
### Broadcasting community posts via `share_with_followers`
Today, we added a new optional `share_with_followers` boolean parameter to `POST /2/tweets`. When posting with a `community_id` and `share_with_followers: true`, the community Post is also broadcast to the authenticated user's followers' timelines — matching the "Also share with followers" checkbox on x.com.
### Launch of the Community Notes API
Today, we launched the [Community Notes API](https://docs.x.com/x-api/community-notes/introduction) — a new suite of endpoints for AI Note Writers to programmatically participate in Community Notes:
* `GET /2/notes/search/posts_eligible_for_notes` — search Posts eligible to receive a Community Note
* `GET /2/notes/search/notes_written` — retrieve notes previously written by the authenticated AI Note Writer
* `POST /2/notes` — submit a Community Note
Access requires X Developer AI enrollment and Community Notes AI Note Writer approval.
### Change to DM events behavior
Today, we made a change to X API V2 DM Events behavior. With the new change participant\_ids array will only be included for ParticipantsJoin and ParticipantsLeave events, and it will list only the participants who joined or left at the time of the event. The MessageCreate event will no longer include the participant\_ids array. Learn more [here](https://devcommunity.x.com/t/upcoming-change-to-x-api-dm-events-endpoints-behavior/241841).
### Launch of Account Activity API endpoints
Today, we launched new X API v2 [Account Activity API endpoints](/x-api/webhooks/introduction). Learn more [here](https://devcommunity.x.com/t/account-activity-api-is-now-available-in-v2/242895).
### Improvements to media upload endpoint
We made a few improvements to media upload endpoint to improve the developer experience. We introduced Dedicated Endpoints for Chunked Media Upload [Media Upload endpoints](/x-api/media/introduction). Learn more [here](https://devcommunity.x.com/t/media-upload-endpoints-update-and-extended-migration-deadline/241818).
### Support for email address retrieval with OAuth 2.0
Today, we added support for email address retrieval with OAuth 2.0 in X API V2. Learn more [here](https://devcommunity.x.com/t/announcing-support-for-email-address-retrieval-with-oauth-2-0-in-the-x-api-v2/240555).
### Changes to user affiliation data
Today, we made changes to X API V2 User Affiliation Data. With the new change affiliation.user\_id will return an array of user\_ids. Earlier it used to return a single user\_id as a string, even if a user had multiple affiliations. Learn more [here](https://devcommunity.x.com/t/change-to-x-api-user-affiliation-data/237164).
### Launch of media upload endpoints
Today, we launched new X API v2 [Media Upload endpoints](/x-api/media/introduction). Learn more [here](https://devcommunity.x.com/t/announcing-media-upload-endpoints-in-the-x-api-v2/234175/3).
### Launch of new documentation site
Today, we launched our new X Developer Platform documentation site, [https://docs.x.com](https://docs.x.com).
### Launch of xurl tool
Today, we launched [xurl](https://github.com/xdevplatform/xurl), a new tool that simplifies API testing for X developers, which now supports OAuth 2.0.
### Addition of community ID tweet field
Today, we added the `community_id` Tweet Field to the X API v2. Learn more about it [here](https://x.com/tapshah21/status/1860061806653317126).
### Addition of DM blocking endpoints
Today, we added the DM blocking and DM unblocking endpoints to the X API v2.
### Support for longform posts
Today, we added the ability to create longform Posts with a length of 25k instead of 4k.
### Support for long form posts
Today, we added the ability to create long form Posts using the X API v2
### Retrieve user affiliation
Today, we added the ability to retrieve a User's affiliation programmatically using the X API v2
### Get article metadata
Today, we added the ability to get Article metadata using the X API v2
### Get profile image and cover picture
Today, we added the ability to get profile Image and cover picture URL via the X V2 API
### Addition of connection status field
Today, we added the connection\_status field in the X API v2. Learn more about it [here](https://devcommunity.x.com/t/announcing-connection-status-field-in-the-user-object-in-the-x-api-v2/212588).
### Addition of trends lookup endpoint
Today, we added the Trends lookup endpoint in the X API v2. Learn more about it [here](https://devcommunity.x.com/t/announcing-the-users-search-and-trends-lookup-endpoints-in-the-x-api-v2/210567).
### Addition of users search endpoint
Today, we added the Users Search endpoint in the X API v2. Learn more about it [here](https://devcommunity.x.com/t/announcing-the-users-search-and-trends-lookup-endpoints-in-the-x-api-v2/210567).
### Get DM permissions
Today, we added the ability to the get DM permissions via the X API v2. Learn more about it [here](https://devcommunity.x.com/t/dm-permissions-available-in-the-x-api-v2/209688).
### Launch of subscription type field
Today, we launched a subscription\_type field on the User object in the X API v2. Learn more about it [here](https://devcommunity.x.com/t/new-subscription-type-field-is-available-in-the-twitter-api-v2/209219/2).
### Get posts usage endpoint
Today, we launched an endpoint to programmatically get your posts usage in the X API v2. Learn more about it [here](https://developer.x.com/en/docs/twitter-api/usage/tweets/api-reference/get-usage-tweets).
### Launch of reposts lookup endpoint
Today, we launched an endpoint to lookup reposts of a post in the X API v2. Learn more about it [here](https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/get-tweets-id-retweets).
### Deprecation of search endpoints
Today, we are deprecating the search/tweets, users/search, and geo/search endpoints in the X API v1.1. Learn more [here](https://developer.x.com/en/docs/twitter-api/enterprise/powertrack-api/guides/powertrack_recovery_and_redundancy_features).
### Deprecation of Replay API endpoint
Today, we are deprecating the Replay API endpoint from the enterprise X API. You can use the [recovery](https://developer.x.com/en/docs/twitter-api/enterprise/powertrack-api/guides/powertrack_recovery_and_redundancy_features) feature instead.
### Deprecation of historical Powertrack endpoints
Today, we are deprecating the Historical Powertrack and Insights track endpoints from the enterprise X API.
### Removal of follows endpoints from Basic and Pro Tiers
Today, we are removing the Follows and List Follows endpoints from the Basic and Pro tiers of the X API v2.
### Removal of manage blocks endpoint
Today, we are removing the Manage Blocks endpoint from X API v2.
### Support for Bookmarks count and long posts
Today, we added support for retrieving bookmarks count and the ability to retrieve posts with more than 280 characters in the X API v2.
### Deprecation of Statuses/Filter endpoint
Today, we are deprecating the statuses/filter endpoint in the X API v1.1 Developers can use the filtered stream endpoint in the X API v2.
### Support for view counts
Today, we are adding support for view counts in the X API v2. A new field called impression\_count is made available in the public\_metrics of the post payload.
### Addition of verified type field
Today, we are adding a verified\_type user field to the X API v2 that indicates the type of verification a user account has (blue, business, government or none).
### Removal of source field
Today, we are removing the source field from the post payload in the X APIs.
### Addition of Direct Messages endpoints
Today, we are adding six v2 Direct Messages endpoints. This release includes three GET methods for retrieving Direct Message conversation events and three POST methods for creating new Direct Messages. These methods support group conversations for the first time.
Please visit our [blog post](https://developer.x.com/en/blog/product-news/2022/new-v2-direct-messages-endpoints) to learn more about this update.
### Support for edited post metadata
Today, we are adding the ability for developers to retrieve edited post metadata using the X API v2.
Please visit our [blog post](https://developer.x.com/en/blog/product-news/2022/supporting-edit-tweet-functionality) to learn more about this update.
### Addition of filtering operator aliases
Filtering/query operator "aliases" were added to search and filtered stream endpoints, across enterprise, premium, and v2. In many cases, the operator refers to posts instead of statuses, e.g. "in\_reply\_to\_tweet\_id" as an alias for "in\_reply\_to\_status\_id." In other cases, the new operator alias adds more clarity to the matching performed. For example., since posts can only have one video attachment, a new "has:video\_link" alias is provided for "has:videos." Check out the [v2 filtered stream operator table](https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/integrate/build-a-rule#list) to see more examples.
### Updates to reverse chronological home timeline
Beginning today, the reverse chronological home timeline v2 endpoint can return every post created on a timeline over the last 7 days and the most recent 800 regardless of the creation date.
### New filtering operators for Filtered Stream
Today, 10 new v2 filtering operators are now available to all developers building with the filtered stream endpoints, and another 10 are now more widely available.
Please visit our [blog post](https://developer.x.com/en/blog/product-news/2022/twitter-api-v2-filtered-stream) to learn more about this update.
### Updates to streaming endpoints latency
Today, we’re making updates to the streaming endpoints in the X API v2 to reduce the latency by 50%.
### Enabling v1.1 media endpoints in Essential Access
Today, we're enabling the v1.1 media endpoints in Essential access of the X API v2.
Please visit our [forum announcement](https://devcommunity.x.com/t/v1-1-media-endpoints-available-for-essential-access-in-the-twitter-api-v2/171664) to learn more about this update.
### Launch of Reverse Chronological Home Timeline endpoint
Today, we’re launching a new endpoint that enables you to retrieve a collection of the most recent posts and reposts posted by who you follow.
Please visit our [forum announcement](https://devcommunity.x.com/t/reverse-chronological-home-timeline-in-the-twitter-api-v2/171549) to learn more about this launch.
Along with the new endpoints, the variants field is now available for the [media object](https://developer.x.com/en/docs/twitter-api/data-dictionary/object-model/media). This will give you the type of content attached with the URL.
### Launch of Bookmarks endpoints
Today, we’re launching new endpoints that enable you to manage and lookup Bookmarks using the X API v2. The Bookmarks feature has long been available in the X app, but until now, there hasn’t been an endpoint that allows you to retrieve, create or build solutions to manage your Bookmarks via the API.
Please visit our [forum announcement](https://devcommunity.x.com/t/build-with-bookmarks-on-the-twitter-api-v2/168804) to learn more about this launch.
### Launch of quotes lookup endpoint
Today, we’re launching the [quotes lookup endpoint](https://developer.x.com/en/docs/twitter-api/tweets/retweets/introduction) that lets you get the quotes for a post ID.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/introducing-the-quote-tweets-lookup-endpoint-to-the-twitter-api-v2/168370) to learn more about this launch.
### Updates to documentation navigation
We’ve heard your feedback. Finding content in our documentation could be difficult, and it was confusing when you clicked on a link and were taken to an entirely different side navigation.
Today, we’ve released an updated docs navigation that enables you to browse the full offering of the X Developer Platform from a single side navigation. With this launch, we eliminated redundant pages, removed confusing icons, and improved how you can interact with the different elements within the navigation.
If you have any feedback, please let us know via our [feedback channel](https://twitterdevfeedback.uservoice.com/forums/930250-twitter-api).
### Improvements to reposts and likes lookup endpoints
Today, we’re launching improvements to the [reposts lookup](https://developer.x.com/en/docs/twitter-api/tweets/retweets/introduction) and the [Likes lookup](https://developer.x.com/en/docs/twitter-api/tweets/likes/introduction) endpoints, allowing you to get back the complete list of accounts who have Liked or reposted a post, not just the last 100 accounts to do so.
To learn more about this launch, please visit our forum announcement to learn more about this launch.
### Support for OAuth 2.0 authentication
Today, all developers can now authenticate using OAuth 2.0 by selecting OAuth 2.0 as an authentication method in the Developer Console. We’ve added support for confidential and public clients and all relevant v2 endpoints to use this authentication method as part of this release.
OAuth 2.0 is an industry-standard authorization protocol that provides developers more control over an application’s scopes and improves authorization flows across multiple devices. In other words, developers building applications for people on X will have more control over the information their App requests from its users, so that you only have to ask your end-users for the data and information you need.
This modern authorization protocol will allow you to present your end-users with a more streamlined consent flow for authorizing your app, which only displays the specific scopes you have requested from them.
To learn more about this launch, please visit our forum announcement.
### Major platform updates to X API v2
**Major platform updates: X API v2 is now the primary version, new Essential and Elevated access, and Policy changes**
Today, we are announcing that X API v2 is now the primary version of the X API. We have launched enough endpoints and functionality into X API v2 to satisfy the needs of 90% of all existing Apps built on the X API.
We are launching the following changes today to further improve upon the X API v2 developer experience:
* Fast and free Essential access to the API, and free Elevated access to developers who have had their use cases approved. We have a lot more details on these access levels available on our About the X API page.
* We are removing language in our Developer Policy that restricted how you build with X’s core features, and limited the number of users you can support through your app.
* We are opening up our platform to encourage you to build tools and products that make X better, healthier, and extend the public conversation. [See a list of solutions we’d love to see you build](https://developer.x.com/en/docs/twitter-api/what-to-build).
* Specifically, we’ve removed terms that restricted replication of the X experience, including X’s core features as well as terms that required permission to have high numbers of user tokens.
* We know that building solutions that help people on X often means a developer has to build (or replicate) some of the things that are available on X. These changes to our Developer Policy are intended to drive clarity for the developer ecosystem and provide an open API platform that makes it easier for developers to build, innovate, and make an impact on the public conversation.
We go into a lot more detail on this launch and the X API launches that led to this moment in our [forum post](https://devcommunity.x.com/t/ushering-in-a-new-era-for-the-twitter-developer-platform-with-the-twitter-api-v2/162087).
In addition to exploring earlier changelog entries, we’ve put together some key resources that you can review to understand what all has released to X API v2 to-date:
* [X API endpoint map](/x-api/migrate/x-api-endpoint-map)
* [About the X API](/x-api/getting-started/about-x-api)
### Launch of list lookup endpoints
Today, we’re launching the new List lookup endpoints to X API v2. These endpoints will allow users to retrieve details on specified Lists such as followers, members, posts and more. The data retrieved can be used to build solutions that solve for curation, analysis and discoverability use cases and needs. In addition to new List endpoints, a new list: operator has been made available at the Academic Research access level. This will be available to use on search posts and post counts.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-list-lookup-endpoints-for-the-twitter-api-v2/161965).
### Additions to Spaces endpoints
We are adding functionality to the Spaces endpoint to return the list of people who purchased a ticket to a Space, as well as support for Topics.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/adding-new-functionality-to-spaces-endpoints/161959).
### Launch of manage posts endpoints
Today, we’re launching new manage posts endpoints to the X API v2. In addition to post and post delete functionality, we’ve added the ability to post polls, tag people in images, create posts with reply settings, and post to Super Followers.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-manage-tweets-endpoints-for-the-twitter-api-v2/161501).
### Changes to embedded buttons
Today, we're making some changes to X's embedded buttons. Buttons are now more rounded to match X.com buttons and we've (very slightly) updated our color palette.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/embedded-buttons-have-a-new-look/160528).
### Launch of lists endpoint group
Today, we’re launching the new Lists endpoint group to X API v2. These endpoints will allow you to build solutions that curate and organize posts based on preferences, interests, groups, or topics.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-new-twitter-api-v2-manage-list-endpoints/159980).
### Launch of mutes lookup endpoint
Today, we’re launching the new [mutes lookup](https://developer.x.com/en/docs/twitter-api/users/mutes/introduction) endpoint to the X API v2. This endpoint will allow authenticated users to retrieve and get information on the accounts they have muted.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-new-mutes-lookup-endpoint-for-the-twitter-api-v2/159680).
### Launch of OAuth 2.0 beta
Today, we’re launching a beta of OAuth 2.0 and fine-grained scopes on the X API v2. Developers interested in shaping the future of OAuth 2.0 on the X Developer Platform, can request access to the OAuth 2.0 beta.
OAuth 2.0 is the industry standard for authentication and will allow for a more modern authorization experience.
The OAuth 2.0 beta lets you test this new functionality in a v2 Project and associated App and give us feedback before a General Availability release. However, since this implementation of OAuth 2.0 is currently in development, we strongly recommend that you refrain from testing on a public, production environment, or app.
To learn more about this launch, please visit our forum announcement.
### Launch of Batch Compliance endpoints
Today, we’re launching the new [batch compliance endpoints](https://developer.x.com/en/docs/twitter-api/compliance/batch-compliance/introduction) to the X API v2 to make it easier for developers using the X API to keep their X data in compliance with our [Developer Agreement and Policy](https://developer.x.com/en/developer-terms/policy). These endpoints allow developers and researchers to batch upload large amounts of post or User IDs and understand what action is needed to ensure that their datasets reflect user intent and the current state of the content on X.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/new-batch-compliance-endpoints-available-on-the-twitter-api-v2/158534).
### Launch of Spaces endpoints
Today, we’re launching the new [Spaces endpoints](https://developer.x.com/en/docs/twitter-api/spaces/overview) and a [new top-level Spaces data dictionary](https://developer.x.com/en/docs/twitter-api/data-dictionary/object-model/space) to the X API v2. The Spaces endpoints enable you to lookup Spaces by Space ID or user ID, or using keywords, hashtags, or usernames of people mentioned in a title. The new data dictionary contains relevant information about a Space such as its title, ticketed status, and participant metrics; all user IDs can be expanded into full objects.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/introducing-new-spaces-endpoints-on-the-twitter-api-v2/158213).
### New object for video views limitation
Previously, when you requested video view metrics using the enterprise [Engagement API](/x-api/enterprise-gnip-2.0/fundamentals/engagement-api) on posts that are older than 1800 days old, we delivered a zero value without much context. Today, we will start delivering a new object in these cases called unsupported\_for\_video\_views\_tweet\_ids, which will include a comma-separated list of post IDs that are older than 1800 days old. You will still receive all other requested metrics for these posts in a separate object.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/new-engagement-api-video-views-object-to-clarify-limitation/158163).
### Addition of alt text field
Today, we are making the alt\_text field available in the X API v2 media object, in order to enable developers to build more consciously for accessibility.
To request this field, you must pass the expansions=attachments.media\_keys parameter, as well as the media.fields=alt\_text parameter. If included in your request, this field will return the alt text for any posts that include images with alt text.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/media-alt-text-field-now-available-in-twitter-api-v2/157939).
### Launch of reposts endpoints
Today, we’re launching new [reposts](https://developer.x.com/en/docs/twitter-api/tweets/retweets) endpoints to X API v2. Developers can now use these endpoints to repost or undo a repost on behalf of an authenticated user, or to look up who reposted a given post.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-new-twitter-api-v2-retweets-endpoints/156827).
### Launch of manage mutes endpoints
Today, we’re launching new [manage mutes](https://developer.x.com/en/docs/twitter-api/users/mutes/introduction) endpoints to the X API v2. These endpoints will allow authenticated users to mute or unmute accounts.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-new-manage-mutes-endpoints-for-the-twitter-api-v2/156261).
We have now reduced the `max_results` that can deliver with the [full-archive search](/x-api/posts/full-archive-search) endpoint when you are requesting the `context_annotations` field with the `tweet.fields` parameter to 100, meaning that you can only pull up to 100 posts with the field per page.
### Reliability features for streaming endpoints
Today, we are launching two reliability streaming features for X API v2’s filtered stream and sampled stream called backfill and redundant connections, which are now available on the Academic Research product track.
The redundant connections feature enables you to connect to a given stream two times, which can help to ensure that you maximize streaming up-time in case one of your streams experiences a disconnection.
Backfill can be utilized by adding the backfill\_minutes parameter and a whole number between one and five to your streaming request, and allows you to request missed data that might have resulted from a disconnected stream.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/new-reliability-and-recovery-functionality-available-for-twitter-api-v2-streaming-endpoints/156244/2).
### Launch of post counts endpoints
Today, we’re launching the new [post counts endpoints](/x-api/posts/counts/introduction) to the X API v2. This includes two different endpoints: Recent post counts, which is available to all product tracks, and full-archive post counts, which is currently only available to the Academic Research Product Track. You can use these endpoints to receive the count of posts that matches a specified query.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/introducing-new-tweet-counts-endpoints-to-the-twitter-api-v2/155997).
### Improvements to teams
Today, we’re launching key improvements to the functionality of teams based on feedback we’ve heard from the community. We have updated the style and design of the team page. We also made changes to the invitation flow to make it easier to invite team members or to learn more about why an invitation might have failed. If you have a team account you can check out the changes by viewing the [teams page](https://developer.x.com/en/portal/teams) of the Developer Console. To learn more about teams check out our [documentation on the subject](https://developer.x.com/en/docs/Developer%20Console/overview#team) and related [FAQ](https://developer.x.com/en/docs/Developer%20Console/faq#dev-portal-management-faq).
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-improvements-to-the-functionality-of-teams/155447/2).
### Retirement of configuration endpoint
Today, we retired the standard v1.1 GET /help/configuration endpoint.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/retiring-the-1-1-configuration-endpoint/153319).
### Consolidation of oembed endpoint
Today, we’re sharing that the v1.1 oEmbed endpoint will be retired and removed on November 23, 2021, so that new features can be supported in a consistent manner. After that date, the only official and supported API endpoint for X oEmbeds (embedded posts and timelines) will be via publish.x.com/oembed.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/consolidating-the-oembed-functionality/154690/2).
### Launch of blocks and likes lookup endpoints
Today, we’re launching the new [blocks](/x-api/users/blocks) and [Likes](/x-api/posts/likes) lookup endpoints to the X API v2. These endpoints enable you to use the v2 API to get information about which posts an account has liked, what users have liked a post, and who you or an authenticated user has blocked.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-twitter-api-v2-likes-lookup-and-blocks-lookup/154353).
### Launch of manage likes endpoints
Today, we’re launching the new [manage Likes](https://developer.x.com/en/docs/twitter-api/tweets/likes) endpoints to the X API v2. These endpoints enable you to use the v2 API to like and unlike posts.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-new-manage-likes-endpoints-for-thetwitter-api-v2/152780).
### Launch of manage blocks endpoints
Today, we’re launching the new [manage blocks](/x-api/users/blocks) endpoints to the X API v2. These endpoints enable you to block or unblock accounts on behalf of a user using user IDs.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/announcing-manage-blocks-for-twitter-api-v2/152358/2).
### Removal of support for embedded timelines
Today we’re sharing our plans for the future of [embedded timeline widgets](https://developer.x.com/en/docs/x-for-websites/timelines/overview). On June 23rd 2021, we plan to retire the Likes, Collections, and Moments timelines. We recommended you use the [Profile](https://developer.x.com/en/docs/x-for-websites/timelines/guides/profile-timeline) and [Lists](https://developer.x.com/en/docs/x-for-websites/timelines/guides/list-timeline) timelines, which we’re updating to become faster, easier to use, and more up-to-date with X features and functionality.
You can learn more about this change in our [forum announcement](https://devcommunity.x.com/t/removing-support-for-embedded-like-collection-and-moment-timelines/150313).
### Launch of manage follows endpoints
Today, we’re launching the new [manage follows](/x-api/users/follows) endpoints to the X API v2. These endpoints enable you to follow or unfollow accounts on behalf of a user using their user ID. This launch comes just a few months after the launch of the [follows lookup](/x-api/users/follows) endpoints, which allow you to retrieve an account’s followers and who they are following.
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/introducing-the-new-manage-follows-endpoints-to-the-twitter-api-v2/149465).
### Introduction of Academic Research product track
Today, we are introducing the new [Academic Research product track](/resources/fundamentals/developer-apps) to [X API v2](/x-api/introduction). This update introduces a new application process for Academic Researchers that will provide those that are approved with an Academic Research [Project](/resources/fundamentals/developer-apps) that will unlock greater access and advanced functionality.
With the new Academic Research product track, you will be able to access the following:
* The new X API v2 [full-archive search endpoint](/x-api/posts/full-archive-search), which is only available to the Academic Research product track at this time.
* An increased [post cap](/x-api/fundamentals/post-cap) of 10 million, up from the 500,000 that is available to the [Standard product track](/resources/fundamentals/developer-apps) at the Basic [access level](https://developer.x.com/en/products/x-api/early-access/guide#na_2).
* New filter operators available to [recent search](/x-api/posts/recent-search), [full-archive search](/x-api/posts/full-archive-search), and [filtered stream](/x-api/posts/filtered-stream), including `$` (aka cashtag), `bio` (only available via filtered stream), `bio_name` (only available via filtered stream), `bio_location` (only available via filtered stream), `place`, `place_country`, `point_radius`, `bounding_box`, `-is:nullcast`, `has:cashtags` and `has:geo`.
* An increased rule limit for filtered stream of 1,000 concurrent rules, up from the 25 that is available to the Standard product track at the Basic access level.
* An increased query and rule character limit of 1,024 characters long, up from the 512 character limit that is available to the Standard product track at the Basic access level
To learn more about this launch, please visit our [forum announcement](https://devcommunity.x.com/t/introducing-the-new-academic-research-product-track/148632).
### Addition of reply settings field
Today we are launching a new field in the post object called reply\_settings. This field is available on all X API v2 endpoints that return posts including post lookup, hide replies, recent search, sampled stream, filtered stream, follows lookup, user post timeline, and user mention timeline endpoints or by [expanding](/x-api/fundamentals/expansions) the post object in any endpoint.
This field indicates how the post author has allowed others to reply to their posts, whether it’s everyone, just the people they mention in the post, or those they follow. The field values returned by the `reply_settings` field include `everyone`, `mentionedUsers`, and `following`. If no conversation controls are set for the post, this will still show up in the post object with `everyone` value for the field.
### Launch of user post and mention timeline endpoints
Today, we’re launching the new [user post timeline and user mention timeline endpoints](/x-api/posts/timelines) to the X API v2. These endpoints enable you to request the posts composed by, or mentioning, a specified account on X. Learn more in the forum post announcement.
### Launch of follows lookup endpoints
Today, we’re launching the new [follows lookup endpoints](/x-api/users/follows) to the X API v2. These endpoints enable you to retrieve an account’s followers and who they are following using their user ID. Learn more in the forum post announcement.
### Retirement of Labs v2 endpoints
Retired Labs v2 recent search and hide replies endpoints
We have retired the following endpoints. If you were using the Labs versions of these endpoints, you can use the linked migration guides to update your integration to start using the new X API v2 versions:
* [Recent search v2](/x-api/posts/search/migrate/overview)
* [Hide replies v2](/x-api/posts/hide-replies/migrate)
We also have additional details about migration to the new X API v2 via our [migration hub](/x-api/migrate/overview).
If you have any questions, please reach out to our [Labs forum category](https://devcommunity.x.com/c/labs/57).
### Retirement of Labs v1 endpoints
On August 12th, 2020, we launched the new X API v2: Early access. With this release, we graduated several endpoints to X API v2 from the Labs program, and announced that the Labs version of the endpoints would remain in a deprecated state for 60 days before retiring them.
Today marks 60 days since the launch, meaning that we have retired the following endpoints. If you are using the Labs versions of these endpoints, you can use the linked migration guides to update your integration to start using the new X API v2 versions:
* post metrics v1
* Filtered stream v1
* Sampled stream v1
We also have additional details about migration to the new X API v2 via our [migration hub](/x-api/migrate/overview).
If you have any questions, please reach out to our [Labs forum category](https://devcommunity.x.com/c/labs/57).
### Addition of post consumption status bar
In the [main dashboard page](https://developer.x.com/en/portal/dashboard) of the new Developer Console, you can now check your usage towards the [post cap](/x-api/fundamentals/post-cap) of 500,000 posts per month. This cap is applied at the Project level, across the following v2 endpoints in Basic access: filtered stream, and recent search.
In order to see this feature and use the new v2 endpoints, you will need to activate the [new Developer Console experience](https://developer.x.com/en/portal/opt-in.html).
### Launch of Hide Replies endpoint
Today, we’re launching the new hide replies endpoint into the v2 X API. This endpoint enables you to hide abusive, distracting, or misleading replies to posts – a crucial piece to improving the health of the public conversation. Learn more in the forum post announcement.
The same endpoint in X Developer Labs is now deprecated, and it will be retired in 90 days. Learn how to [migrate to the v2 endpoint.](/x-api/posts/hide-replies#comparing-twitter-apis-hide-replies-endpoints)
### Early access to X API v2 endpoints
Today we announced [Early Access to the first endpoints of the new X API](https://blog.x.com/developer/en_us/topics/tools/2020/introducing_new_twitter_api.html)!
The new X API features a new API foundation which will allow us to deliver new functionality faster; an updated data format and new functionality that gives you more control over which fields you receive; new post, user, and media fields; and a set of updated endpoints that enable you to listen to and analyze posts, including the following:
* [post lookup](/x-api/posts/post-lookup-by-post-ids)
* [User lookup](/x-api/users/user-lookup-by-id)
* [Recent search](/x-api/posts/recent-search)
* [Filtered stream](/x-api/posts/filtered-stream)
* [Sampled stream](/x-api/stream/stream-sampled-posts)
You can find a full list of the new functionality available, and find migration resources on our [X API v2: Early Access docs page](https://developer.x.com/en/docs/x-api/early-access).
Learn more about what we have planned in our “[Guide to the future of the X API](https://developer.x.com/en/docs/x-api/early-access)”.
### Deprecation of Labs endpoints
We are deprecating certain Labs endpoints due to the launch of their X API v2 replacements in this release.
The following Labs v1 endpoints will be retired 60 days from today's release:
* post metrics v1
* Filtered stream v1
* Sampled stream v1
The following Labs v2 endpoint will be retired 90 days from today’s release:
* Recent search v2
### Improvements to hide replies
We added the ability to unhide a reply. Additionally, previously unhidden replies can now be hidden again via this endpoint.
Get more details in the [Hide replies documentation](https://developer.x.com/en/docs/labs).
### Retirement of Labs v1 endpoints
Today we are retiring the Labs v1 posts and users, hide replies, and recent search endpoints.
You can read more about our Labs v1 plan in our [forum announcement](https://devcommunity.x.com/t/update-on-labs-v1-endpoints/138641).
### Addition of quote tweets metric
Today, the `quote_tweets` metric is now available for 'unowned' posts via the [/totals](/x-api/enterprise-gnip-2.0/fundamentals/engagement-api#post-insights-engagement) endpoint. This means that you can access the quote count for all posts by using app-only authentication.
You can read more about this change in our [forum post](https://devcommunity.x.com/t/how-the-new-retweets-and-comments-metric-is-returned-with-the-twitter-api/139131).
### Addition of new post metrics
Today we are adding two new non-public metrics subfields, `user_profile_clicks` and `url_link_clicks`, to the post object in the X Developer Labs post lookup endpoints. They will be returned when using the `tweet.fields` parameter with any of the following values: `non_public_metrics`, `organic_metrics`, or `promoted_metrics`.
To learn more, please visit the [post lookup API reference](https://developer.x.com/en/docs/labs/tweets-and-users/api-reference/get-tweets-id)
### Changes to repost counts
Starting today, X web, iOS and Android will be showing the total 'reposts and comments' count per post. Using the X API, the total 'reposts and comments' number matching the X interface can be calculated by adding the `retweet_count` and `quote_count` when available. Additionally `quote_count` will be the total unique accounts that have quoted the post, rather than the total posts quoting the post. For more details, please see our [forum post](https://devcommunity.x.com/t/how-the-new-retweets-and-comments-metric-is-returned-with-the-twitter-api/139131/2).
### Organic and promoted metrics groupings
We are adding `organic_metrics` and `promoted_metrics` to the post and media objects in the post lookup endpoints.
### Addition of metrics to endpoints
We are adding metrics to the post and media objects in the post lookup and recent search endpoints.
You can read more about these changes in our [forum announcement](https://devcommunity.x.com/t/adding-metrics-to-the-tweets-and-recent-search-endpoints-in-labs/135315)
### Launch of COVID-19 endpoints
Today we are launching a new COVID-19 stream endpoint and an accompanying compliance endpoint.
You can read more about these changes in our [forum announcement.](https://devcommunity.x.com/t/new-covid-19-stream-endpoint-available-in-twitter-developer-labs/135540)
### Updates to Replay API user profiles
Starting today, the Replay API will deliver user profile objects that reflect the referenced user at the time the Replay API is running. This change to deliver current user profile objects is similar to the recent Historical PowerTrack update below from Nov. 25, 2019.
### Addition of post annotations
We are adding annotations to the post object in the posts and recent search endpoints.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/adding-annotations-to-tweets-and-recent-search-endpoints-in-labs/135193).
### Updates to developer policy
Today, we announced a significant [update to the Developer Policy](https://developer.x.com/en/developer-terms/policy). We encourage you to read more about this via our [forum](https://devcommunity.x.com/t/a-new-easier-to-understand-twitter-developer-policy/135038) and [blog](https://blog.x.com/developer/en_us/topics/community/2020/twitter_developer_policy_update.html) posts, and to review the revised policy. The Developer Policy is one of the foundations for your use of the X API and it is important to understand your commitments.
### Launch of Hide Replies endpoint
We want to help people feel safe and comfortable having conversations on X. As part of that, today we’re excited to give post authors more control over the conversations they start by supporting the hide replies feature with a new [endpoint](/x-api/posts/hide-replies).
You can read more about this new endpoint in our [forum announcement](https://devcommunity.x.com/t/introducing-the-hide-replies-endpoint/134683).
### Release of v2 Labs endpoints
Today, we are bringing our posts and Users, Recent Search and Hide Replies endpoints to v2 of Labs. We are deprecating Labs v1 endpoints and will fully retire them 90 days after this initial release. We will also keep our v1 documentation available for this duration. You can provide us feedback on this versioning strategy via our [feedback channel](https://twitterdevfeedback.uservoice.com/).
We're releasing the following changes to posts and Users:
* Introduce [fields](/x-api/fundamentals/fields) as a query parameter
* Remove [formats](https://developer.x.com/en/docs/labs#payload) as a query parameter
* Add path variable for single ID [lookup](https://developer.x.com/en/docs/labs/overview/versioning/migration-guide#id-lookup-path) in posts and Users
* Adjusting the path and query parameters for single and multi-username [lookup](/x-api/migrate/overview#username-lookup-path) in GET /users
* Change field name `stats` to `public_metrics`
Other changes include:
* Remove the `most_recent_tweet_id` expansion in Users
* Remove HTML tags from the `source` field in posts to make that field easier to parse
The core search, pagination and other functionality of Recent Search will stay the same.
We have put together some [migration materials](/x-api/migrate/overview) for when you update from v1 to v2.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/releasing-a-new-version-of-labs-endpoints/134219).
### Addition of drop/undrop events to Compliance Firehose
Today we added new drop/undrop event types to the Compliance Firehose API. You can read more about them in our [documentation.](/x-api/enterprise-gnip-2.0/fundamentals/firehouse)
### Changes to access token management
Today, we're making changes to the way that Access Tokens and Access Token Secrets are presented and managed within the [applications Dashboard on developer.x.com](https://developer.x.com/content/developer-twitter/en/apps).
In order to make API integrations more secure, we will no longer show the Access Token and Access Token Secret on the Dashboard beyond the first time that these values are generated.
After the first time, these credentials can not be retrieved. You will be able to regenerate the tokens on the Dashboard, but this will invalidate your current token and secret.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/upcoming-changes-to-access-token-and-secret-management/130851).
### Removal of SPDY support
Starting January 15, 2020, all connections to the X API (and all other X domains) will no longer support SPDY connections.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/removing-support-for-spdy-protocol-on-twitter/132530).
### Launch of recent search endpoint in Labs
Today, we are releasing a new endpoint to [search for posts posted in the last 7 days](/x-api/posts/recent-search).
Learn more about this launch via our [forum announcement.](https://devcommunity.x.com/t/new-recent-search-endpoint-available-in-labs/133076)
### Update to Twurl CLI
A new updated major release of our X API CLI, `[twurl](https://github.com/twitter/twurl)`, is now available. This release includes a number of bug fixes and enhancements and introduces Bearer Token support which helps to add functionality around the Premium and X Developer Labs endpoints. Read more in our [forum post](https://devcommunity.x.com/t/twurl-0-9-5-released/132966).
### Addition of post annotations in streams
Today in X Developer Labs, we are releasing new metadata elements to the default post payload. These new fields, rendered as part of the post payload, will provide more contextual information about the post.
Learn more about this launch via our [forum announcement](https://devcommunity.x.com/t/tweet-annotations-added-to-the-tweet-object-for-the-sampled-stream-and-filtered-stream-endpoints-in-labs/132407).
### Updates to Historical PowerTrack user profiles
Today, we’re updating our "batch historical posts" endpoint (Historical PowerTrack) to provide user profile location, bio description, and display name information that reflects values in place at the time of the job processing. When the updated user objects are delivered, there will be a new "updated" string array in the User/Actor object.
There are up to three possible values: name, description, location:
`"updated": ["name", "description", "location"]`
See the [documentation on Historical PowerTrack's data format](https://aem-author-production-version-6-3.twitter.biz/content/developer-twitter/en/docs/tweets/batch-historical/guides/powertrack-data-format.html) for more details.
### Addition to Account Activity API
Today, we’re releasing a new feature to the Account Activity API that will provide developers with the ability to view whether an account that mentions your subscribed user is blocked.
You can read more about the `user_has_blocked` [data object structure](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#account-activity-data-object-structure) and check out our [forum announcement](https://devcommunity.x.com/t/new-release-account-activity-api-user-has-blocked-field/131157) for more details.
### Launch of sampled stream endpoint in Labs
Today, we are releasing a new endpoint to [stream a sample of all public posts](/x-api/posts/recent-search) in real-time, as they are posted.
Learn more about this launch via our [forum announcement.](https://devcommunity.x.com/t/new-sampled-stream-endpoint-available-in-labs/130958)
### Launch of Filtered Stream endpoint in Labs
Today, we are releasing a [new streaming endpoint](/x-api/posts/filtered-stream) to retrieve posts, and an endpoint to manage your filters in X Developer Labs. With these endpoints, you will be able to retrieve up to 500,000 posts per month (maximum 50 posts per second); you can set up to 10 filter rules on your stream (these can be applied at the same time).
Learn more about this launch via our [forum announcement](https://devcommunity.x.com/t/new-filtered-stream-endpoints-available-in-labs-and-the-future-of-statuses-filter/129888).
Requests parameters documented in the API reference pages are now clearly marked as either optional or required. Additionally, API reference pages will describe a JSON body payload when this is allowed by a request.
### Launch of post metrics in Labs
You can now retrieve engagement data for any post or list of posts from owned/authorized accounts. The posts you query must be no older than 30 days and cannot be reposts.
[GET /tweets/metrics/private](https://developer.x.com/en/docs/labs/tweet-metrics/overview.html) supports the following metrics:
* `impressions`
* `reposts`
* `quotes`
* `likes`
* `replies`
* `video views`
* `video view quartiles` (where the requester is also the author of the media)
Learn more about this launch via our [forum announcement](https://devcommunity.x.com/t/new-twitter-developer-labs-release-metrics-endpoint/129122).
### Changes to DM permissions
Starting today, applications that need to create Direct Messages will be required to have "Read, Write, and Direct Messages" app permissions (RW+DM). Applications attempting to create Direct Messages with only the RW app permission will receive the following error:
`{"code": 93,"message": "This application is not allowed to access or delete your direct messages."}`
You can learn more about this change via our [forum announcement](https://devcommunity.x.com/t/updates-to-app-permissions-direct-message-write-permission-change/128221).
### Addition of pinned post expansion
`pinned_tweet_id` will expand a user’s pinned post through our user object expansion.
### Addition of quote counts metadata
Developers can use the new Labs endpoints to pull counts of quotes.
### Addition of most recent post expansion
`most_recent_tweet_id` will expand a user’s most recent post through our user object expansion.
Learn more about this launch via our [forum announcement](https://devcommunity.x.com/t/update-to-twitter-developer-labs/128060).
### Requirement for TLS 1.2
Today, all connections to the X API (and all other X domains) will require TLS 1.2.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/removing-support-for-legacy-tls-versions-1-0-1-1-on-twitter/126648/2).
### New Account Activity API endpoint
Starting today, we are introducing the new [Account Activity API endpoint](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#api-reference) to deactivate user subscriptions using application-only OAuth.
This new endpoint offers developers the convenience of only having to provide a bearer token to deactivate a subscription, without requiring the subscribed user’s access token.
We are immediately marking the existing enterprise Account Activity API endpoint used to deactivate user subscriptions with 3-Legged OAuth as deprecated. The endpoint will be retired and no longer be available starting from January 15, 2020.
Developers can learn more about this API in our [documentation](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#api-reference).
### New expansions for tweets endpoint
We added two new expansions to the [GET /tweets](https://developer.x.com/en/docs/labs/tweets-and-users/api-reference/get-tweets.html) endpoint:
entities.mentions.username will expand the username of any recognized user mention in a post into a full user object.
`referenced_tweets.id.author_id` expands the ID of the author of any referenced post, when one of the posts requested is a repost, Quoted post or Reply. This expansion will also expand the referenced post ID into a full object.
### Support for tweets and users endpoints in Labs
The first two endpoints are now available via the Labs portal. Make sure you have an approved developer account and have applied for Labs access to get started with these endpoints.
[Key differences](https://developer.x.com/content/developer-twitter/en/docs/labs/overview/whats-new) from equivalent v1.1 functionality include:
* Single endpoint for single object "show" function and batch "lookups"
* Expansion parameters support the inclusion of additional objects as part of one request (e.g. mentioned users, referenced posts, e.g.)
* Format parameters support different data projections with more or less verbose payloads
* Rate limiting is at the app level, regardless of auth method (user context or bearer token)
Learn more about this launch via our [forum announcement](https://devcommunity.x.com/t/twitter-developer-labs-is-open-to-all-developers/126717).
### Retirement of terms and privacy endpoints
We have fully retired the Terms of Service and Privacy Endpoints. The current status of our [Privacy Policy](https://x.com/en/privacy) and [Terms of Service](https://x.com/en/tos) is best served by our up-to-date web pages.
You can learn more about this change via our [forum announcement](https://devcommunity.x.com/t/terms-of-service-and-privacy-endpoints-will-no-longer-serve-content-after-june-10/125714).
### Changes to user object fields
Today some user object fields, including user.lang, will start returning 'null' for updated metadata fields previously announced in our [forum post](https://devcommunity.x.com/t/upcoming-changes-to-user-object-and-get-users-suggestions-endpoints/124732).
Developers can learn about this change through our [documentation.](/x-api/fundamentals/data-dictionary/reference#user)
### Launch of Account Activity Replay API
Starting today, we are introducing the [Account Activity Replay API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity), a data recovery tool available with the enterprise tier of the [Account Activity API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity)
The [Account Activity Replay API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity) allows you to retrieve events from as far back as five days. It should be utilized to recover data in scenarios where your [webhook](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#api-reference) server misses events
Developers can learn more about this API in our [documentation](/x-api/enterprise-gnip-2.0/fundamentals/account-activity).
### Support for native media in quotes
Starting today, native media (photos, videos, and GIFs) can be added to quotes on X, which will be shown as additional media metadata in the entities sections of quote payloads.
Developers can learn more about this in our [documentation](https://developer.x.com/en/docs/x-api/v1/data-dictionary/object-model/tweet).
### Addition of is:reply operator
Today, the operator is:reply becomes available to use with the [enterprise search APIs](/x-api/enterprise-gnip-2.0/fundamentals/search-api) and the paid version of the [premium search endpoints](https://developer.x.com/content/developer-twitter/en/docs/tweets/search/api-reference/premium-search).
The is:reply Boolean operator can be used to filter all replies to posts, or to filter out explicit replies that match a rule. This operator functions in the same way as the is:quote operator.
Remember that, with the Search API, all ‘is:’ and ‘has:’ operators must be used in conjunction with a standalone operator like a keyword or hashtag.
You can learn more about this operator in the [documentation](/x-api/enterprise-gnip-2.0/fundamentals/rules-filtering).
### Changes to expanded URL enrichment
Today, the expanded URL enrichment will no longer contain the unwound URL object and metadata (including the title and description fields) for URLs linking to posts, Moments, or profiles. Please note that other URLs (to websites, etc.) will continue to be enriched with this metadata, and the url, expanded\_url, and `display_url` will still be available. This change applies to [Decahose](/x-api/enterprise-gnip-2.0/fundamentals/decahose-api), [PowerTrack](/x-api/enterprise-gnip-2.0/powertrack-api), [Historical PowerTrack](https://developer.x.com/content/developer-twitter/en/docs/tweets/batch-historical/overview), and the [Search APIs](https://developer.x.com/en/docs/x-api/v1/tweets/search/overview).
### Addition of is:reply operator in PowerTrack
Today, we are introducing a new operator, is:reply, to help you narrow conversations to those you care about most. You can now filter out replies from your results (in addition to the pre-existing ability to filter out reposts, is:retweet, and Quoted posts, is:quote). This new operator is available today within [PowerTrack](/x-api/enterprise-gnip-2.0/powertrack-api), [Historical PowerTrack](https://developer.x.com/content/developer-twitter/en/docs/tweets/batch-historical/overview), and [Replay](/x-api/enterprise-gnip-2.0/powertrack-api#replay-api).
The is:reply Boolean operator can be used to filter all replies to posts, or to filter out explicit replies that match a rule. This operator functions in the same way as the is:quote operator.
You can learn more about this operator in the [documentation](/x-api/enterprise-gnip-2.0/fundamentals/rules-filtering).
### Access to apps in Developer Console
Today, we've added the ability for developers to view and edit their existing [X apps](/resources/fundamentals/developer-apps) via the [X app dashboard](https://developer.x.com/content/developer-twitter/en/apps) on developer.x.com as long as they're logged into their X account. Previously, you could only view and edit your existing X apps on developer.x.com if you had applied or been approved for a [developer account](/resources/fundamentals/developer-portal).
You still must have an approved developer account to be able to create new X apps.
### Support for video subtitles
Today, we are announcing that advertisers and publishers are now able to add subtitle files (SRT) to their videos via ads.x.com, Media Studio and our publisher upload API. Subtitles will be viewable on auto-playing video (when no sound is available) on Android and Web. We will release the functionality for iOS in the coming weeks.
To read more about the new subtitles endpoints, please review their respective API reference pages:
* [POST media/subtitles-create](/x-api/media/create-media-subtitles)
* [POST media/subtitles-delete](/x-api/media/delete-media-subtitles)
### Update to Account Activity API endpoint
Today we are announcing an update to the [Account Activity API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity) endpoint, [GET subscriptions/count](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#get-direct-messages-events-list#get-account-activity-subscriptions-count). To enable greater visibility into your billing details and use of the API, beginning today, you can programmatically pull the number of provisioned subscriptions associated with your Account Activity API instance within the JSON. This means you can now see both what your provisioned number of subscriptions are, and how close you are to hitting that limit via the GET subscriptions/count API endpoint.
This update has been documented with the [Account Activity API documentation](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#get-direct-messages-events-list#get-account-activity-subscriptions-count).
### New rate limits on POST endpoints
Today we are implementing new app-level rate limits on several of our standard POST endpoints:
* [POST statuses/update](https://developer.x.com/en/docs/x-api/v1/tweets/post-and-engage/api-reference/post-statuses-update)
* [POST statuses/retweet/:id](https://developer.x.com/en/docs/x-api/v1/tweets/post-and-engage/api-reference/get-statuses-retweets-id)
* [POST favorites/create](https://developer.x.com/en/docs/x-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create)
* [POST direct\_messages/events/new](https://developer.x.com/en/docs/x-api/v1/direct-messages/sending-and-receiving/api-reference/new-event)
* [POST friendships/create](https://developer.x.com/en/docs/x-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create)
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/new-post-endpoint-rate-limit-enforcement-begins-today/115355).
### Update to twitter-text library
Today, we are announcing an update to the [twitter-text](https://github.com/twitter/twitter-text) library to account for the recent changes to the way that X counts emojis. If an emoji previously counted as more than two characters, its count will now be reduced to just two characters to allow for users to make the most out of their 280 characters.
You can read more about this change in our [forum announcement](https://devcommunity.x.com/t/new-update-to-the-twitter-text-library-emoji-character-count/114607).
### Retirement of legacy DM endpoints
We have fully retired the legacy Direct Message endpoints. You can find a list of the retired DM endpoints, as well as their replacements on [this page](https://developer.x.com/content/developer-twitter/en/docs/direct-messages/sending-and-receiving/api-reference).
You can learn more about this update via our [forum announcement](https://devcommunity.x.com/t/details-and-what-to-expect-from-the-api-deprecations-this-week-on-august-16-2018/110746).
### Changes to DM media access
Today, we are implementing some changes to the process where you [retrieve attached media from Direct Messages](https://developer.x.com/en/docs/x-api/v1/direct-messages/message-attachments/overview). We will no longer support accessing `media_url` or `media_url_https` via an authenticated [www.x.com](http://www.x.com) session. The request to fetch `media_url_https` MUST always be signed with the user’s access token using OAuth 1.0A.
You can learn more about this update via our [forum announcement](https://devcommunity.x.com/t/direct-message-api-change-to-how-apps-can-access-images-sent-in-direct-messages/112722).
### Retirement of user and site streams
We have fully retired [User Streams](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction) and [Site Streams](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction).
You can learn more about this update via our [forum announcement](https://devcommunity.x.com/t/details-and-what-to-expect-from-the-api-deprecations-this-week-on-august-16-2018/110746).
### New version of Usage API
Today we are launching a new version of the Usage API. With this update, we’re making the API more stable by moving to a new system.
With the system update, users will experience a data "hole" as developers will only be able to pull data back to May 1, 2018. Therefore for the upcoming year, they will be missing out on a few months of historical data (until June 2019).
A product name is changing within the Usage API from Historical PowerTrack Subscription to Historical PowerTrack 2.0 which will make the product naming consistent with the rest of our user-facing wording. Customers will receive the exact same data in the same format with the update. You will see this change within the products.type JSON object.
If you have any questions, please reach out to your account manager.
### API deprecations
The [Account Activity API DM Beta](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction) product was fully retired today.
The following services and endpoints will experience degraded service starting today:
* [User Streams](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction)
* [Site Streams](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction)
* [GET direct\_messages](https://developer.x.com/en/docs/x-api/v1/direct-messages/sending-and-receiving/api-reference/list-events)
* [GET direct\_messages/sent](https://developer.x.com/content/developer-twitter/en/docs/direct-messages/sending-and-receiving/api-reference/get-sent-message)
* [GET direct\_messages/show](https://developer.x.com/content/developer-twitter/en/docs/direct-messages/sending-and-receiving/api-reference/get-message)
* [POST direct\_messages/new](https://developer.x.com/content/developer-twitter/en/docs/direct-messages/sending-and-receiving/api-reference/new-message)
* [POST direct\_messages/destroy](https://developer.x.com/content/developer-twitter/en/docs/direct-messages/sending-and-receiving/api-reference/delete-message)
User Streams and Site Streams will be fully retired on August 23rd.
The legacy Direct Messages endpoints will be fully retired on September 17th.
You can learn more about this update via our [forum announcement](https://devcommunity.x.com/t/details-and-what-to-expect-from-the-api-deprecations-this-week-on-august-16-2018/110746).
### Changes to app creation and rate limits
As of today, you will no longer be able to create new [X apps](/resources/fundamentals/developer-apps) via [apps.x.com](https://apps.x.com/). You will now be redirected to either your [Developer Console](/resources/fundamentals/developer-portal) account or, if you don't have a Developer Console account yet, to the page where [you can apply](https://developer.x.com/content/developer-twitter/en/apply-for-access).
We also announced that we will be implementing new app-level rate limits to the following POST endpoints on September 10th, 2018.
* [POST statuses/update](https://developer.x.com/en/docs/x-api/v1/tweets/post-and-engage/api-reference/post-statuses-update)
* [POST statuses/retweet:id](https://developer.x.com/en/docs/x-api/v1/tweets/post-and-engage/api-reference/post-statuses-retweet-id)
* [POST friendships/create](https://developer.x.com/en/docs/x-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-create)
* [POST favorites/create](https://developer.x.com/en/docs/x-api/v1/tweets/post-and-engage/api-reference/post-favorites-create)
* [POST direct\_messages/events/new](https://developer.x.com/en/docs/x-api/v1/direct-messages/sending-and-receiving/api-reference/new-event)
Finally, we are introducing a new option for people to report suspected violations of our platform policies to you for review.
You can learn more about all of these updates via our [blog post](https://cli.re/g32qKr).
### App management in Developer Console
If you have a [Developer Console](/resources/fundamentals/developer-portal) account, you can now create and manage your [X apps](/resources/fundamentals/developer-apps). Please read our [forum post](https://devcommunity.x.com/t/app-creation-and-management-now-available-in-the-Developer%20Console/107723) for more details.
### Changes to Sign in with X and Account Activity
Today, we started requiring that you register the [callback URLs](/resources/fundamentals/developer-apps#callback-urls) that you use with the Sign in with X process. You can read more about this update [here](https://devcommunity.x.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342).
We also announced the addition of the tweet\_delete\_events activity to the Account Activity API. This new activity will be sent for those corresponding deleted events to enable developers to more easily provide a compliant experience for their customers and application users. You can read more about this new activity in our [forum post](https://devcommunity.x.com/t/adding-delete-events-to-the-account-activity-api/106783) or on our [documentation](/x-api/enterprise-gnip-2.0/fundamentals/account-activity).
### Updates to terms and policies
Today, we made some changes to our [Terms of Service](https://x.com/en/tos), [Privacy Policy](https://x.com/en/privacy), and [X Developer Agreement](https://developer.x.com/en/developer-terms/agreement-and-policy) that include privacy, security, and data protection updates. Please read our [forum post](https://devcommunity.x.com/t/upcoming-changes-to-the-developer-platform/104603) for more details.
### Timezone fields made private
Today, the timezone values in X user objects became private fields. From here on out, all\* time\_zone and utc\_offset data objects will return as null. Please read our [forum post](https://devcommunity.x.com/t/upcoming-changes-to-the-developer-platform/104603) for more details.
\* They will continue to be available on the account/settings endpoint, for authenticated users only.
### Removal of Klout data
Today, we removed all Klout data from post payloads as part of our GDPR updates.
### Changes to profile background and Account Activity
Today, we are changing all instances of profile\_background\_image\_url and profile\_background\_image\_url\_https to their default values. Please read our [forum post](https://devcommunity.x.com/t/upcoming-changes-to-the-developer-platform/104603) for more details.
In addition to the above change, we are adding a new field to the [Account Activity API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity) payloads to reference which subscription the activity was delivered for. This JSON object is called for\_user\_id and will include the subscribed user's ID who produced that activity as its value. You can see some examples of this new JSON object in our [account activity objects](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#account-activity-data-object-structure) page.
### Changes to quote payload rendering
Today, we are adding a change to the way that URLs will be rendered in the quote payload.
We’re adding a new entity called the "quoted\_status\_permalink" entity to ensure the quoted post can be referenced and we will be removing the t.co link from the quoted post "text" field.
With the new format, the t.co link is no longer appended to the "text" field of the quoted post in the "quoted\_status" object.
Further, we will no longer put the quoted post t.co url, expanded\_url, and display\_url in the ‘urls’ entity. Instead, these will be added to a new "quoted\_status\_permalink" object with "url", "expanded", and "display" URL attributes. This means that the "quoted\_status\_permalink" object will be reserved for the t.co link back to the quoted post, whereas the "entities.urls" array can be used to identify any links shared within the original post or quote.
Please read our [forum post](https://devcommunity.x.com/t/updating-how-urls-are-rendered-in-the-quote-tweet-payload/105473) and [updated documentation](https://devcommunity.x.com/t/upcoming-changes-to-the-developer-platform/104603) for more details.
### Deprecation of X Kit
The announcement of [X Kit](https://developer.x.com/en/docs/x-for-websites) deprecation, after October 31, 2018 X Kit will no longer be actively maintained. Please read our [blog post](https://blog.x.com/developer/en_us/topics/tools/2018/discontinuing-support-for-twitter-kit-sdk.html) for more details.
### Platform updates for GDPR
Today we announced several updates to the platform related to GDPR. Please read our [forum post](https://devcommunity.x.com/t/upcoming-changes-to-the-developer-platform/104603) for more details.
### Addition of additional media info object
The addition of a new object to the post payload – additional\_media\_info object – and also restricting some video details (video\_info) for promoted posts where advertisers have requested we limit video playback to X owned clients. You can find additional information about this change at the following link: [Extended Entities Objects > post with native video](https://developer.x.com/en/docs/x-api/v1/data-dictionary/object-model/extended-entities).
### Launch of premium full-archive search
Launch of the [premium full-archive search endpoint](https://blog.x.com/developer/en_us/topics/tools/2018/access-the-full-history-of-tweets.html).
### Launch of Account Activity APIs
Launched both ([All Activities](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction)) and ([Direct Messages](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction)) Standard beta Account Activity APIs, read more about this launch [on our blog](https://blog.x.com/developer/en_us/topics/tools/2017/announcing-more-functionality-to-improve-customer-engagements-on-twitter.html). Announced User streams & Site streams deprecation and sunset date of Tuesday June 19, 2018.
### Update to twitter-text library
Version 2.0 of twitter-text is now available [on GitHub](https://github.com/twitter/twitter-text). This update addresses the change in our character limit that was rolled out on November 7th, 2017. To learn more about this update, please [visit our forum](https://devcommunity.x.com/t/shipped-twitter-text-2-0/98577).
### Launch of premium APIs
Launched the Premium APIs.
These new APIs build on the quality and stability of our enterprise data platform, and make it available more widely via a tiered pricing model. For the first time, you can start to search across 30 days of posts (instead of the limited 7 days of data on the standard endpoint), and optionally, you can also access our premium enrichments for profile geo, URL expansion, and poll data. Here’s a taste of some of the new features:
* More posts per request (Sandbox + Premium)
* A far more rich query language enabling more complex queries (Sandbox + Premium)
* A counts endpoint that returns time-series counts of posts (Premium)
* Metadata enrichments, such as expanded URLs and Profile Geo (Premium)
Read more about this launch [on our blog](https://blog.x.com/developer/en_us/topics/tools/2017/introducing-twitter-premium-apis.html).
### Launch of 280 character posts
Official launch of 280 character posts in languages where cramming was an issue. Please see our [forum announcement](https://devcommunity.x.com/t/updating-the-character-limit-and-the-twitter-text-library/96425) or official [blog post](https://blog.x.com/official/en_us/topics/product/2017/tweetingmadeeasier.html) for further reference.
### Removal of DM commands in Statuses/Update
The ability to send Direct Messages via the statuses/update API endpoint has been completely removed, and the `enable_dm_commands` and `fail_dm_commands` parameters will no longer have any effect. Read more about this update [on our forum](https://devcommunity.x.com/t/retiring-legacy-dm-commands-on-the-standard-tweet-api/86653 "on our forum").
### Changes to OAuth login flow
A change was made to X’s backend OAuth API endpoints which altered the behaviour of the /oauth/authenticate endpoint to match that of the /oauth/authorize endpoint. Read more about this update [on our forum](https://devcommunity.x.com/t/recent-changes-to-twitter-s-oauth-login-flow-and-api-endpoints/94943).
### Updates to Engagement API metrics
The Engagement API was updated to use the same metrics aggregation methodology in use by the X analytics dashboard. Read more about this update [on our forum](https://devcommunity.x.com/t/changes-to-the-engagement-api/94523).
### Changes to DM commands failure
The default value of the `fail_dm_commands` parameter within the DM statuses/update endpoint has been switched to *true*. All status updates intended as Direct Messages will start to return errors (unless `enable_dm_commands` is *false*, in which case the post will be posted). Read more about this update [on our forum](https://devcommunity.x.com/t/retiring-legacy-dm-commands-on-the-standard-tweet-api/86653).
### Treatment of 280 character tweets
The response payload for 280 character tweets will be treated the same way as long tweets. Read more about this update [on our forum](https://devcommunity.x.com/t/testing-280-characters-for-certain-languages/94126).
### Addition of additional media info
Adding new data to the post payload (`additional_media_info object`) and also restricting some video details (`video_info`) for promoted posts where advertisers have requested we limit video playback to X owned clients. You can find additional information about this change at the following link: [Extended Entities Objects > post with native video](https://developer.x.com/en/docs/x-api/v1/data-dictionary/object-model/extended-entities)
### End of support for url\_contains operator in 30-Day Search
30-Day and Full-Archive Search ended support for url\_contains: operator. Deprecation of this operator was announced as part of the Gnip 2.0 migration in August 2016. Any Search query using the url\_contains: Operator will be rejected as invalid.
### Upcoming removal of url\_contains operator in search APIs
The 30-Day Search API (both 30-Day and Full-Archive) will no longer support the url\_contains: operator beginning 30 days from today, or after August 4, 2017 (Support of url\_contains: will actually end with the first deploy after that date). Deprecation of this operator was announced as part of the Gnip 2.0 migration in August 2016. When Operator support is ended, any query using the url\_contains: will be rejected as invalid.
### Retirement of xAuth
The xAuth authentication mechanism has been removed from all X APIs. Read more about this update [on our forum](https://devcommunity.x.com/t/retirement-of-xauth/88022).
### HTTP headers forced to lowercase
All HTTP headers have been forced into lowercase (`content-type`, `x-rate-limit-remaining`, `x-access-level` etc). Read more about this update [on our forum](https://devcommunity.x.com/t/upcoming-http-header-changes/86715).
### Optional parameters for DM commands
The optional `enable_dm_commands` parameter to statuses/update will enable applications to remove DM command support early, before the transition period ends. The default value is *true* (i.e. current legacy behavior), but this may be set to *false* to get the new, post-November 1 behavior. The optional fail\_dm\_commands parameter to statuses/update will make DM commands return HTTP 403 (error code 151) from the API when set to *true*. The default value is *false*. Read more about this update [on our forum](https://devcommunity.x.com/t/retiring-legacy-dm-commands-on-the-standard-tweet-api/86653).
### Support for emojis in rules
Rules with emojis are now available in the enterprise Search APIs
### Wider availability of Direct Message APIs
Access to several new Direct Message APIs are now more widely available. Read more about this update [on our blog](https://blog.twitter.com/developer/en_us/topics/tools/2017/new-apis-to-power-the-future-of-customer-engagement-in-direct-me.html).
### Retirement of MPEG-DASH video support
MPEG-DASH URLs (.mpd) has been removed from the payload of a post that contains video. Read more about this update [on our forum](https://devcommunity.x.com/t/retiring-mpeg-dash-video-support-on-march-9th-2017/82761).
### New enrichments and payload changes
New Enrichment! Poll Metadata is now available through our enterprise APIs. See the [documentation](/x-api/enterprise-gnip-2.0/fundamentals/account-activity#migration-introduction) for more details.
New payload field: Image Alt-Text (description) field may be present in the entities.media\[] and extended\_entities.media\[] section of the payload if a user chooses the "Add description" option when adding a photo to a post. This is available in enriched native format only.
Default payload format: Newly created streams on Gnip products will now default to original format JSON.
### Updates to Historical PowerTrack and Replay API
Historical PowerTrack API & Replay API
* quote filtering is now supported
* Quoted posts are now fully rehydrated within HPT and Replay post payloads
### New payload fields for counts
New payload fields: quote\_count and reply\_count are now available in native enriched format payloads across Realtime and Historical APIs
### Support for geo operators in Full-Archive Search
Full-Archive Search API (FAS):
* Added support for additional geo operators:
* place:
* place\_country:
* has:profile\_geo:
* profile\_country:
* profile\_region:
* profile\_locality:
### Rule management by ID in PowerTrack
Rule management (GET and DELETE) by Rule ID is now available for PowerTrack 2.0 and PowerTrack Replay 2.0
### Support for geo operators in 30-Day Search
30-Day Search API:
* Added support for additional geo operators:
* place:
* place\_country:
* has:profile\_geo:
* profile\_country:
* profile\_region:
* profile\_locality:
# Developer Guidelines
Source: https://docs.x.com/developer-guidelines
Developer policies and guidelines for the X API, covering allowed use cases, restricted behaviors, compliance requirements, and best practices for apps.
**Violations can result in app suspension, API access revocation, or permanent account bans.** Always review the official policies before building.
Binding legal terms for API access
Rules for building on X
Specific rules for bots
Prohibited activities
***
## Quick check: is my app allowed?
Before building, ask yourself these questions. If you answer **"no"** to any of them, your app likely violates X's policies.
For interactions, did the user **explicitly request** it?
Is your app's purpose and behavior **clear to users**? (Automated accounts must be labeled.)
Can users **easily opt out** of any ongoing interactions?
Does it provide **real value** beyond self-promotion?
Are you **only using the official API** (not scraping/browser automation)?
Are you **within rate limits** and respecting usage policies?
When in doubt, ask: "Would a user be happy with this experience?" If not, reconsider your approach.
***
## Common scenarios: allowed or not?
Real-world examples to help you understand what's permitted. **These rules apply to all apps**—whether you're building a bot, mobile app, web integration, browser extension, analytics dashboard, or any other tool that uses the X API.
| Scenario | Allowed? | Why |
| --------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------- |
| Automated account posts scheduled content (news, weather, quotes) | | Informational, no unsolicited mentions |
| App posts RSS feed updates on behalf of user | | Helpful broadcasting |
| Alert service posts earthquake/disaster notifications | | Public safety value |
| Sports app posts game updates to user's timeline | | Informational |
| App posts stock/crypto prices on schedule | | Informational, no manipulation |
| App posts identical content across multiple accounts | | Spam / platform manipulation |
| App posts to trending topics to gain visibility | | Trend manipulation |
| Multiple city-specific alert accounts (e.g., @WeatherNYC, @WeatherLA) | | Allowed—non-duplicative, location-specific content |
| Scenario | Allowed? | Why |
| ------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------- |
| App responds to @mentions asking for help | | User-initiated request |
| App auto-replies to anyone mentioning a keyword | | Unsolicited interaction |
| App auto-replies to users who reply to your post | | User engaged first—limit 1 reply. [Conditions apply](#gray-areas-explained) |
| AI-powered app generates and posts replies | | Requires **prior approval** from X |
| App replies with "follow me for more!" to random users | | Spam, unsolicited |
| Utility app that unrolls threads when mentioned | | User-initiated utility |
| Scenario | Allowed? | Why |
| --------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----------------------------------------------------------------------- |
| App responds to DMs with helpful info | | User-initiated |
| App sends affiliate links when user DMs first | | User-initiated—must disclose. [Conditions apply](#gray-areas-explained) |
| App auto-DMs new followers with welcome message | | Unsolicited, even to followers |
| App bulk-DMs users about a product launch | | Spam |
| Support integration asks "How can I help?" after user DMs | | User-initiated conversation |
| Scenario | Allowed? | Why |
| ----------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------- |
| Third-party app lets user tap a like button on a post | | User-initiated through the app |
| App auto-likes posts containing a hashtag | | Automated, not user-initiated |
| Mobile app has "auto-like" feature for selected users | | Automated, not user-initiated |
| Service sells likes or offers "bulk like" packages | | Selling engagement is prohibited |
| App reposts content from a curated list | | OK for informational purposes, no bulk spam. [Conditions apply](#gray-areas-explained) |
| Growth tool bulk-follows accounts to grow audience | | Manipulation |
| App follows back anyone who follows it | | Bulk/aggressive following |
| App adds users to lists in bulk | | Indiscriminate list manipulation |
**Likes must be directly initiated by the authenticated user.** Automated, bulk, or indiscriminate liking — including auto-liking by keyword, hashtag, user, or schedule — is prohibited. Apps may not offer "auto-like" features or sell likes as a service. This applies to all apps—bots, mobile apps, browser extensions, or any integration.
| Scenario | Allowed? | Why |
| ---------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------- |
| App sends product recommendations when asked | | User-initiated |
| App replies to random posts with affiliate links | | Unsolicited spam |
| Giveaway app that requires follows/retweets to enter | | Risky—can be seen as engagement manipulation |
| Service selling likes/follows/retweets | | Strictly prohibited |
| Tip service that sends crypto when user requests | | User-initiated—comply with financial regulations. [Conditions apply](#gray-areas-explained) |
| Scenario | Allowed? | Why |
| ------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------- |
| App tracks brand mentions for analytics dashboard | | Valid use case |
| App scrapes X via browser automation (not API) | | **Permanent suspension**—API only |
| App stores X data to train AI/ML models | | Prohibited (except Grok) |
| App redistributes >1.5M posts in 30 days | | Exceeds redistribution limits |
| App benchmarks X performance vs competitors | | Prohibited competitive analysis |
| Academic research on public conversation trends | | Valid with proper data handling |
**Non-API automation (scraping, browser automation) results in permanent suspension.** Always use the official X API.
***
## Prohibited activities
These activities will get your app suspended or permanently banned. There are no exceptions.
| Category | Examples |
| ----------------------------- | ------------------------------------------------------------------------------------ |
| **Spam & Manipulation** | Identical content across accounts, fake engagement, trend manipulation, bulk posting |
| **Unsolicited Outreach** | Auto-replies to random users, bulk DMs, uninvited @mentions |
| **Deceptive Bots** | Impersonating humans, hiding bot identity, misleading links/redirects |
| **Engagement Selling** | Apps that sell likes, follows, retweets, or views |
| **Rate Limit Abuse** | Exceeding limits, designing apps that encourage overuse |
| **Non-API Automation** | Browser scripting, scraping, any automation outside official API |
| **Account Farms** | Multiple accounts for same duplicative purpose |
| **Surveillance** | Profiling, tracking, or monitoring users without consent |
| **Unauthorized AI Training** | Using X data to train ML models (Grok excepted) |
| **Sensitive Data Derivation** | Inferring health, political, religious, or other sensitive attributes |
| **Excessive Redistribution** | Sharing >1.5M Post IDs per 30-day period |
***
## Automation rules
This section applies specifically to **automated accounts** (bots) that post, reply, or interact on behalf of users. If you're building an analytics dashboard, research tool, or other non-automated app, these labeling requirements don't apply to you—but the technical restrictions still do.
### Requirements for automated accounts
All automated accounts using the X API must meet these requirements:
This label appears under your bot's name/handle on its profile. Enable it in your app settings to ensure transparency.
State clearly that it's a bot and who operates it. Example: *"Bot by @yourcompany"* or *"Automated account managed by Example Inc."*
For accountability and contact purposes, your bot must be associated with a human-managed account.
If a user says "stop," stop. Implement keyword detection for common opt-out phrases.
No scraping, browser automation, or unofficial methods. Violations result in permanent suspension.
Don't try to circumvent or abuse rate limits. Design your app to handle limits gracefully.
### Automated actions: what's allowed?
| Action | Allowed? | Rules |
| ------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -------------------------------------------------------------------------------------------- |
| **Post tweets** | | No unsolicited @mentions. No identical cross-posting. |
| **Reply to users** | | Only if user engaged first. Max **1 reply per interaction**. |
| **Send DMs** | | Only after user DMs you first. Easy opt-out required. |
| **Like posts** | | Must be directly user-initiated. Auto-liking, bulk liking, and selling likes are prohibited. |
| **Repost** | | OK for informational/entertainment. No bulk spam. |
| **Quote tweet** | | Same rules as repost—no spam or manipulation. |
| **Follow/Unfollow** | | No bulk, aggressive, or automated following. |
| **Add to Lists** | | No bulk or indiscriminate additions. |
| **Bookmark** | | Fine for personal/automated use. |
| **Search/Read** | | Standard use within rate limits. |
***
## Gray areas explained
Many developers have questions about edge cases. Here's guidance on common gray areas.
**Allowed if:**
* User explicitly requests it (e.g., DMs asking for a recommendation)
* You clearly disclose the affiliate/sponsored relationship
* Links are not misleading (no deceptive redirects)
**Not allowed if:**
* You auto-reply to random posts with affiliate links
* You DM users who didn't ask
* You hide the commercial relationship
* **Requires prior approval from X** before deployment
* Must still follow all rules (no unsolicited mentions, properly labeled)
* Contact X via the [Policy Support form](https://help.x.com/forms/platform) before launching
* Even with approval, cannot impersonate humans
Deploying AI-generated replies without approval is a violation, even if the content itself is helpful.
**Not allowed** as automated DMs—this counts as unsolicited contact, even though they followed you.
**Alternatives:**
* Pinned tweet welcoming new followers
* Bio with intro info and links
* Auto-reply only if they DM you first
**Allowed if:**
* Each account serves **non-duplicative** purposes (e.g., @EarthquakeJP, @EarthquakeCA)
* Content is meaningfully different (location-specific, language-specific)
* Not used to bypass limits or amplify the same message
**Not allowed if:**
* Posting identical/similar content across accounts
* Created to evade suspensions or rate limits
**Allowed if:**
* User initiates (mentions you, DMs you, or explicitly opts in)
* Clear opt-out mechanism exists
* Responses are helpful, not promotional
* Includes privacy policy link in DMs
**Not allowed if:**
* You reach out to users who complained publicly (unsolicited)
* Responses are primarily promotional
**Proceed with caution:**
* Requiring follows/retweets as entry can be seen as engagement manipulation
* Must comply with [X's contest guidelines](https://help.x.com/en/rules-and-policies/x-contest-rules)
* Don't use multiple accounts to amplify
* Ensure prizes are real and delivered
Consider entry methods that don't require engagement actions, like replying with a specific phrase.
***
## Data handling and display requirements
These requirements are legally binding under the Developer Agreement. Non-compliance can result in termination and legal action.
### Content deletion
You must delete X Content from your systems when requested:
| Trigger | Deadline |
| --------------------------------- | --------------------------------------------- |
| X requests deletion | **24 hours** |
| User requests deletion | **24 hours** |
| Content is suspended/removed on X | **24 hours** |
| Your API access is terminated | **10 business days** (must delete all X data) |
Use [Compliance Firehose](https://docs.x.com/x-api/compliance/streams) to receive real-time deletion events and stay compliant automatically.
### Off-X matching
**Off-X matching** means associating X data (username, user ID, posts) with off-platform identifiers (your customer database, email lists, device IDs, etc.).
**Allowed with express opt-in consent:**
* User explicitly agrees to link their X account with your service
* Clear disclosure of what data will be matched and why
**Without consent, you may only match:**
* Information the user directly provided to you
* Publicly available X data (posts, bio, display name, username)
* Public resources like professional directories
**Never match if it would surprise the user.**
### Sensitive data
You **cannot** derive, infer, or store information about X users in these categories:
| Category | Examples |
| ------------------------------- | -------------------------------------------- |
| **Health** | Medical conditions, pregnancy, disabilities |
| **Financial status** | Negative financial condition, credit issues |
| **Political** | Party affiliation, political beliefs, voting |
| **Racial/Ethnic** | Origin, ethnicity |
| **Religious/Philosophical** | Beliefs, affiliations |
| **Sex life/Sexual orientation** | Any inference about sexuality |
| **Trade union** | Membership or affiliation |
| **Criminal** | Alleged or actual criminal activity |
**Exception:** Aggregate analysis without storing personal identifiers (no user IDs, usernames, or linkable data) may be allowed for research purposes, subject to applicable laws.
### Displaying X content
| Requirement | Details |
| -------------------- | -------------------------------------------------------------------------------------------------------- |
| **Attribution** | Use proper X branding. Follow [Brand Guidelines](https://about.x.com/en/who-we-are/brand-toolkit). |
| **No alterations** | Only modify for display formatting (resizing). Don't edit content, remove timestamps, or strip metadata. |
| **No iframes** | Don't display X Content in iframes. Use official embeds or render directly. |
| **Respect removals** | Remove content within 24 hours if deleted on X. |
***
## Technical restrictions
These limits apply to all developers. Exceeding them can result in rate limiting or suspension.
| Restriction | Limit |
| ----------------------------------- | ------------------------------------------------------------------------- |
| **Post ID redistribution** | Max 1.5M Post IDs per 30-day period to any single entity |
| **Hydrated content redistribution** | Max 50,000 hydrated Posts or Users per recipient per day |
| **Rate limits** | Vary by endpoint and tier—[see API docs](/x-api/fundamentals/rate-limits) |
| **AI/ML training** | Prohibited (except for Grok) |
| **Non-API access** | Prohibited—scraping and browser automation = permanent ban |
| **Competitive benchmarking** | Prohibited—can't measure X performance vs. competitors |
| **Multiple apps for same use case** | Prohibited—don't create duplicate apps to bypass limits |
### Special use cases
| Use Case | Requirement |
| ------------------------------------ | ---------------------------------------------------------------- |
| **Government use** | Requires Enterprise tier |
| **Commercial use** | Requires appropriate paid tier; free tier is non-commercial only |
| **Academic research** | May have different redistribution limits; contact X for details |
| **EU Digital Services Act research** | Specific non-commercial research provisions available |
***
## Security and compliance
Your obligations as a developer:
* Use **industry-standard security** practices to protect X data
* Never share your API credentials or tokens
* Store credentials securely (environment variables, secret managers—not in code)
* Implement proper authentication in your apps
If you experience a security breach involving X data:
* **Notify X immediately**
* Take steps to mitigate the breach
* Cooperate with X's investigation
* Treat any non-public information from X as confidential
* Don't disclose API rate limits, internal X data, or non-public features
* Don't use confidential info for competitive purposes
* X may audit your compliance **up to once per year**
* You must provide reasonable access and documentation
* Keep records of how you use X data
***
## Summary: do's and don'ts
**For Automated Accounts:**
* Enable "Automated" profile label
* Disclose operator in bio
* Wait for users to initiate interaction
* Provide easy opt-out
* Get approval for AI-generated replies
**For All Apps:**
* Use only the official X API
* Respect rate limits and redistribution limits
* Delete content within 24 hours when requested
* Get opt-in consent for off-X matching
* Use proper attribution when displaying X Content
* Secure your credentials and notify X of breaches
* Keep records of your X data usage
**For Automated Accounts:**
* Hide automated nature
* Send unsolicited DMs, replies, or @mentions
* Ignore "stop" requests
* Post identical content across accounts
* Auto-like, bulk-like, or sell likes (likes must be user-initiated)
**For All Apps:**
* Scrape or use browser automation
* Train AI/ML models on X data (except Grok)
* Derive sensitive user data (health, politics, religion, etc.)
* Match X data to off-platform IDs without consent
* Display X Content in iframes
* Redistribute more than limits allow
* Create multiple apps for the same use case
* Use X data for surveillance or user tracking
# Policies and agreements
Source: https://docs.x.com/developer-terms
X developer policies, agreements, and display requirements, covering the Developer Agreement, Developer Policy, Ads API agreement, and restricted use cases.
## Overview
Developer use of X materials and content is subject to and governed by our Developer Policy and agreements.
# Ads API Agreement
Source: https://docs.x.com/developer-terms/ads-api-agreement
The X Ads API Agreement governs use of X advertising endpoints, including allowed integrations, restrictions, and obligations for advertising partners.
We have updated our Ads API Agreement. The changes below are effective as of February 23, 2025.
## X Ads Products and Services Agreement
**Effective: February 23, 2025**
This X Ads Products and Services Agreement (the “**Agreement**”) is made and entered into by and between the entity identified in the “X Ads API Program” application form submitted to X by such entity (or its authorized representative) (referred to herein as “**Company**”) and X Corp., if Company is outside of the European Union, EFTA States, or the United Kingdom, including if your Company is in the United States of America, or X Internet Unlimited Company, if Company is in the European Union, EFTA States, or the United Kingdom, on behalf of itself and its Affiliates (as defined below) (in either case, “**X**”) and governs Company’s access to and use of the Ad Products (as defined below). As used herein, “**Affiliate**” means any other entity that directly or indirectly controls, is controlled by, or is under common control with X.
PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY, INCLUDING, WITHOUT LIMITATION, ALL EXHIBITS ATTACHED HERETO AND ANY LINKED TERMS AND CONDITIONS APPEARING OR REFERENCED BELOW, WHICH ARE HEREBY MADE PART OF THIS AGREEMENT. BY CHECKING THE BOX LABELED “Yes, I Agree” AND CLICKING “SUBMIT” (OR LANGUAGE THAT IS THE EQUIVALENT OF “Yes, I Agree” SUCH AS, FOR EXAMPLE ONLY, “I Accept”) OR USING THE X MATERIALS, COMPANY IS AGREEING THAT COMPANY HAS READ, AND THAT COMPANY AGREES TO COMPLY WITH AND TO BE BOUND BY, THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF COMPANY DOES NOT AGREE TO BE BOUND BY THIS AGREEMENT, THEN COMPANY MAY NOT ACCESS OR OTHERWISE USE THE X MATERIALS. THIS AGREEMENT IS EFFECTIVE AS OF THE EARLIER OF: (I) THE DATE COMPANY CHECKS “Yes, I Agree” AND CLICKS “SUBMIT” TO ACCEPT THIS AGREEMENT, OR (II) THE FIRST DATE THAT COMPANY ACCESSES THE X MATERIALS (“**EFFECTIVE DATE**”). IF AND TO THE EXTENT, HOWEVER, THAT COMPANY’S APPLICATION TO ACCESS AND USE THE X MATERIALS IS NOT APPROVED BY X (IN ITS SOLE AND ABSOLUTE DISCRETION), THIS AGREEMENT WILL BE NULL, VOID AND OF NO EFFECT. IF YOU ARE AN INDIVIDUAL REPRESENTING COMPANY, YOU ACKNOWLEDGE, REPRESENT, AND WARRANT, THAT YOU (A) HAVE READ AND UNDERSTAND THIS AGREEMENT, (B) HAVE THE APPROPRIATE AUTHORITY TO ACCEPT THIS AGREEMENT ON BEHALF OF COMPANY, AND (C) YOU AGREE, ON BEHALF OF COMPANY, TO THE TERMS OF THIS AGREEMENT. YOU MAY NOT USE THE X MATERIALS AND MAY NOT ACCEPT THIS AGREEMENT IF YOU DO NOT HAVE THE LEGAL AUTHORITY TO BIND COMPANY, ARE NOT OF LEGAL AGE OR ARE OTHERWISE UNABLE TO FORM A BINDING CONTRACT WITH X, OR YOU ARE BARRED FROM USING OR RECEIVING THE X MATERIALS UNDER APPLICABLE LAW.
### 1. Introduction; Scope; Individual Product Terms.
**1.1 Introduction.** X maintains, operates, and offers a suite of products and services that enable various functionalities for X’s advertising partners. The specific products, services and programs (each, an “**Individual Product**”) that enable or are related to these functionalities are: (i) the X Ads API Program (as further described in [Exhibit A](#Exhibit-A)); and (ii) X’s Custom Audiences Program (as further described in [Exhibit B](#Exhibit-B)). Collectively, these Individual Products are referred to herein as the “**Ads Products**”. This Agreement governs the use of, and/or access to, the Ads Products collectively, and the Individual Products individually. In addition, to the extent that Company participates in the X Marketing Partner (“**TMP**”) program in connection with an Ads Product covered under this Agreement, the terms and conditions set forth in [Exhibit C](#Exhibit-C) will apply to Company.
**1.2 Scope.** Subject to this Agreement, during the Term, Company may access and use the specific Individual Products to which X has granted or provided Company with access. Company is under no obligation to use any or all of the Individual Products to which X has granted or provided Company with access, and X is under no obligation to provide (nor continue to provide) Company with the use of, and/or access to, any given Individual Product or feature of the Ads Products. X may grant or deny use of and/or access to any given Individual Product, or any feature thereof, at any time at X’s sole discretion. To the extent that Company accesses or uses any feature of the Ads Products, the terms of this Agreement will govern any such access or use. For the avoidance of doubt, this Agreement shall solely govern Company’s use of the Ads Products described herein. Access and use by Company of any data, content or other materials provided (directly or indirectly) by X to Company under a separate agreement and/or in connection with a separate X program shall be governed wholly by the terms and conditions of such separate agreement and/or program (and not the terms and conditions of this Agreement), unless otherwise mutually agreed in writing by X and Company.
**1.3 Individual Product Terms.** Each Individual Product may include specific terms and conditions that, in addition to and without limitation of the terms of this Agreement, will be applicable to the extent that Company accesses or uses the given Individual Product. Company’s access to any given Individual Product and/or the associated X Materials (as defined below) is conditioned upon Company’s acceptance of, and compliance with, the Individual Product Terms and any technical limitations on access, calls, and use of the Individual Products. The Individual Product Terms are attached hereto as [Exhibit A](#Exhibit-A) and [Exhibit B](#Exhibit-B). X may establish and modify such Individual Product policies or terms in X’s sole discretion, as set forth in Section 15.15 below.
### 2. Definitions.
**2.1** "**Campaign**" means a desktop, mobile website, or mobile application advertising campaign, or fraction thereof.
**2.2** "**Client**" means a X advertiser (who is also a Company customer) that utilizes one (1) or more of the Ads Products, as approved by X in each instance.
**2.3** "**Company Marks**" means Company’s name and any Company logos, trademarks and/or service marks supplied by Company to X for use hereunder (or otherwise authorized by Company for X’s use hereunder).
**2.4** "**Company Materials**" means any Company data, deliverables, or user content provided by Company to X via the Ads Products.
**2.5** "**Company Service**" means Company’s websites, applications and other offerings that display or otherwise use X Materials or aspects thereof.
**2.6** "**Data**" means metrics, data and any other information and/or content X makes available to Company, including any results, usage statistics, data or other information (in the aggregate or otherwise) derived from analyzing or using any of the foregoing.
**2.7** "**End Users**" means an employee or authorized agent of a Client who uses the Ads Products on behalf of such Client.
**2.8** "**Marks**" means the X Marks and/or Company Marks, as the case may be (based on context).
**2.9** "**Materials**" means X Materials and/or Company Materials, as the case may be (based on context).
**2.10** "**Personal Data**" means data relating to a living individual who is or can be identified either from the data or from the data in conjunction with other information that is in, or is likely to come into, the possession of the data controller.
**2.11** "**X Ads**" means X advertising products and services, including the placement of advertisements on the X Network.
**2.12** "**X Code**" means computer code that will call (at a minimum) a X server, developed by X and provided to Company.
**2.13** "**X Marks**" means X’s name and any X logos, trademarks and/or service marks supplied by X to Company for use hereunder (or otherwise authorized by X for Company’s use hereunder).
**2.14** "**X Materials**" means any X data, deliverables, or user content (including derivatives thereof) generated by X, and any X data, deliverables, or user content (including derivatives thereof) generated, collected or developed by X, or that is provided or made available to Company by X pursuant to this Agreement, including any data derived from, based upon, or arising out of, Company’s partnership with X, or any device-level data, or any conversion, engagement, tracking or targeting data that Company or any X-approved third party collects, infers, derives, or obtains from or in connection with Company’s X advertising campaigns. For clarity and without limitation, “X Materials” includes the X Ads API (as defined in [Exhibit A](#Exhibit-A)), X Code, Data, the Ads Products, and any X user ID used to create a Custom Audience (defined below).
**2.15** "**X Network**" means the network of advertising channels, including all forms of media, applications, and devices, through which X may distribute ads, in any medium now known or hereafter developed.
**2.16** "**X Marketing Partners Program**" means the partnership and branding program offered by X, as further described in [Exhibit C](#Exhibit-C).
**2.17** "**X Service**" means: (i) real-time content and information services operated by X, (ii) the technology and systems that enable such services, which includes, collectively, the consumer and advertising products and services currently provided by X or at its websites, and X-owned, operated and/or controlled mobile applications and social plug-ins and APIs, including, without limitation, the Measurement Code, any HTML tags or other codes, internet portals, dashboards, systems and analytic tools and related services, and (iii) all other products or services offered by X and its Affiliates, including (without limitation and for example only) the X Audience Platform and Data & Enterprise Solutions.
### 3. X Ads/Campaign Management; Liability Assumption.
**3.1 X Ads/Campaign Management.** Company may have access to one or more Individual Products that will allow Company, in Company’s sole discretion and/or at the direction of Company’s Clients, to optimize, modify, manage, initiate or manipulate X Ads on the X Network, or otherwise make ad management and targeting decisions (referred to herein as “**Campaign Management**”). If Company accesses or uses any such Individual Products: (a) Company must promptly provide any advertising materials it intends to post to the X Network; and (b) Company authorizes X to place Company and/or Client’s advertising materials on any content or property available through the applicable Individual Product, whether such content or property is provided on the X Network or through a third party. Company will obtain the necessary licenses and authorizations from the applicable Client for Company to use such advertising materials on behalf of such Client. Company is not required to use any Individual Product that permits Campaign Management, but if Company uses any such products, services or features, then Company hereby assumes any and all risk, and accepts any and all responsibility and liability arising out of or in connection with Company’s Campaign Management, including but not limited to: (i) audience creation and selection, data entry errors, tactic selection, and associated inventory, data, and other third-party costs; (ii) properties to which any ads provided by Company directs viewers (e.g. landing pages) and any redirects therefrom; (iii) services and products advertised in any landing pages; and (iv) any associated Company Materials including without limitation, the advertising materials, technology, and/or creative provided to X. Company hereby acknowledges and agrees that X shall bear no responsibility or liability in connection with Company’s Campaign Management. Without limiting the generality of the foregoing, X shall not be responsible, and Company shall be solely responsible, for training Company’s personnel in Campaign Management and the Ads Products functionality.
**3.2 Binding of Clients to these Terms; Liability Assumption.** If Company accesses or uses the Ads Products (or any aspect thereof, including by Campaign Management) on behalf of Clients or any other third parties, Company warrants that it: (i) is authorized to act on behalf of such Clients or other third parties, and has bound such Clients or other third parties to the applicable Our Policies (as defined in Section 6 below), including the applicable X Master Services Agreement (“**MSA**”), which shall govern all purchases of X Ads made by Company, and the terms of this Agreement that apply to the access and use of the applicable Ads Products (or any aspect thereof) and (ii) will be responsible for their compliance with, and liable for their breach thereof.
### 4. Privacy.
**4.1 Direct Data Gathering.** Company represents and warrants that (i) in the event Company is collecting data from users directly (including, without limitation, on or through the Company Service), it has provided such users with legally-sufficient notice (including, without limitation, by conspicuously posting a legally-sufficient privacy policy from all websites, mobile applications, and other services from which data from users are collected and/or made available to X that complies with all applicable laws and regulations, discloses the fact that third parties collect information about users’ activities on or through the relevant websites, mobile applications, and other services (e.g., browsing or shopping) for interest-based advertising purposes, and provides users with legally sufficient instructions for such users to opt out of interest-based advertising); (ii) it has obtained all legally-required informed consent from such users, including regarding Company’s use of cookies and/or tracking pixels in connection with such data collection; and (iii) the Company Materials do not contain or relate to, and any audience data provided, made accessible, or imported by Company to X does not contain or relate to, any data pertaining to any user(s) or data subject(s) who has or have exercised an option to opt-out of receiving interest-based advertising.
**4.2 Personal Data.** Company represents and warrants that Company will not, and will not attempt to, connect or combine any X Materials either directly or indirectly with any Personal Data or to identifiers that are themselves directly or indirectly associated with any Personal Data. In addition, Company will put reasonable safeguards in place to prohibit X Materials from being linked to any Personal Data (whether directly or by inference).
**4.3 Privacy Compliance.** Company represents and warrants that (i) it will not provide X with Company Materials relating to sensitive information, including alleged or actual commission of a crime, health, negative financial status or condition, political affiliation or beliefs, racial or ethnic origin, religious or philosophical affiliation or beliefs, sex life, or trade union membership, or collected from websites, mobile applications, or other services where the product, message, or service that is being offered is prohibited by X’s Ads policies ([https://business.x.com/en/help/ads-policies](https://business.x.com/en/help/ads-policies)), and (ii) it will not (1) provide X with any Company Materials regarding children under the age of thirteen (13), or (2) send X any Company Materials or other data from a website, mobile application or online service directed to children, as defined in the Children’s Online Privacy Protection Act, currently at 16 CFR 312. Company acknowledges and agrees that it will at all times comply with the terms of the X Data Processing Addendum located at [https://privacy.x.com/en/for-our-partners/global-dpa](https://privacy.x.com/en/for-our-partners/global-dpa).
**4.4 Third Party Data.** Company represents and warrants that, in the event Company is obtaining data about users indirectly from one or more third parties (including, without limitation, data partners and/or advertisers, including, without limitation, Clients) to support Company’s performance obligations vis-à-vis X under this Agreement, it has contractually bound each such third party to the requirements contained in this Agreement including, without limitation, in this Section 4.
### 5. Ownership; License; Limitations and Restrictions.
**5.1 Ownership.** As between Company and X, Company retains all worldwide right, title and interest in and to the Company Materials, Company Marks, and the Company Service, excluding any X Materials, X Marks and X Service (and any derivative works or enhancements of any of the foregoing) incorporated therein, including but not limited to all intellectual property rights therein. Any rights not expressly granted herein are withheld. As between Company and X, X owns all worldwide right, title and interest in and to the X Materials, X Marks, and X Service and all future improvements, developments, enhancements, derivative works, and related rights based upon, related to, arising from, or associated with the (i) X Materials, (ii) the X Marks, and (iii) the X Service, including where such improvements, developments, enhancements or derivative works are created by using or referencing data, insights, information, or learnings derived from any Company Materials in accordance to the terms of this Agreement, or data related to the Company advertising activity on the X Service), including but not limited to all intellectual property rights therein.
**5.2 License to Company.** During the Term (including, any Wind-Down Period), to the extent that Company uses, or has access to, the Ad Products (or any aspect thereof), X hereby grants to Company a limited, royalty-free, non-exclusive, non-sublicensable, non-transferrable right and license to use and maintain any X Materials and X Marks that X may provide to Company under this Agreement solely if and as necessary to use the Ads Products (or any Individual Product) which X provides or makes accessible to Company, and to exercise its rights and fulfill its obligations under this Agreement, in each instance in accordance with the terms of this Agreement (including without limitation the restrictions and/or limitations on the use of X Materials). Company agrees that its use of the X Marks will at all times comply with the X Trademark Guidelines (defined below in Section 6).
**5.3 License to X.** During the Term (including, any Wind-Down Period), if Company uses, or has access to, the Ad Products (or any aspect thereof), Company grants to X a royalty-free, non-exclusive, sublicensable, non-transferable right and license to use, copy, display, maintain, transfer, modify, duplicate, and transmit the Company Materials and the Company Marks as necessary to fulfill Company instructions (including without limitation via the purchase and/or placement of ads on any ad inventory accessible on the X Network), to operate the Ad Products (or any Individual Product), and to exercise its rights and fulfill its obligations under this Agreement, in each instance in accordance with the terms of this Agreement.
**5.4 Limitations and Restrictions.**
5.4.1 X Materials are being provided to Company, and Company Materials are being provided to X, solely for the use of and/or provision of the Ads Products and for any other purpose expressly permitted under this Agreement.
5.4.2 Except as expressly permitted under this Agreement or unless otherwise mutually agreed in writing in advance by X and Company, Company shall not, nor allow any other party (including Clients) to, exploit, duplicate, copy, modify, derive, and/or re-use any X Materials, or any information, data, or insights derived from X Materials for any internal or external purpose (including, but not limited to, ad targeting, ad optimization, remarketing, behavioral targeting, retargeting, redirecting, or creating or augmenting in any manner groupings of users or devices segments, or creating or appending end user profiles, including those associated with any mobile device identifier or other unique identifier connected to any end user, computer, browser or device, or redirecting a user with advertising via advertising networks or exchanges, data brokers or any other advertising or monetization services). Further, Company will not use X Materials for identifying or re-identifying users in any way whatsoever (including by combining X Materials or data derived therefrom with data derived from third party sources).
5.4.3 Company may not, nor allow any other party (including Clients) to, incorporate any X Materials (including, without limitation, computer code, pixels, tags, or any other digital products provided by X to Company) into another product or service (except as necessary for the performance of this Agreement and permitted by the terms and conditions of this Agreement), translate, modify, reverse engineer or reverse compile, disassemble, make derivative works of, or otherwise attempt to discover any source code, underlying ideas, or algorithms of any X Materials without X’s express written permission.
5.4.4 Company will not, nor allow any other party (including Clients) to, interfere with, modify, disrupt or disable features or functionality of any X Materials, including without limitation any mechanism used to restrict or control the functionality, or defeat, avoid, bypass, remove, deactivate or otherwise circumvent any software protection or monitoring mechanisms of the X Materials.
5.4.5 Company will not, nor allow any other party (including Clients) to, sell, rent, lease, sublicense, distribute, redistribute, syndicate, create derivative works of, assign or otherwise transfer or provide access to, in whole or in part, the X Materials to any third party except as expressly permitted herein.
5.4.6 Company will not, nor allow any other party (including Clients) to, remove or alter any proprietary notices or marks in or on the X Materials.
5.4.7 Company will not, nor allow any other party (including Clients) to, provide use of the X Materials on a service bureau, rental or managed services basis or permit other individuals or entities to create links to the X Materials or "frame" or "mirror" the X Materials on any other server, or wireless or Internet-based device, or if applicable, otherwise make available to a third party, any token, key, password or other login credentials to the X Materials.
5.4.8 Company will not, nor allow any other party (including Clients) to, use the X Materials for any illegal, unauthorized or other improper purposes.
5.4.9 Company may not, nor allow any other party (including Clients) to, share the X Materials (including, without limitation, Data) with any third party (whether verbally or in writing), including any of Company’s clients or business partners or any Company personnel unrelated to the Ads Products, except if and as explicitly outlined herein, or as permitted by X in advance in writing (email accepted).
5.4.10 Company may not, nor allow any other party (including Clients) to, co-mingle or otherwise create any combined display of X Materials with Company Materials, data, content or other materials received from X under a separate agreement, or any other third-party materials or across advertising campaigns, except if and as expressly detailed herein or as approved by X in writing in advance.
5.4.11 Company may not, nor allow any other party (including Clients) to, offer or provide the Company Service and/or the X Materials as part of an advertising network and may not enable any programmatic export or otherwise enable machine consumption of X Materials by or to any third party (including, without limitation, Clients) without X’s prior written consent.
5.4.12 Company may not, nor allow any other party (including Clients) to, encourage or require users to engage with any Ads Products in such a fashion that may be misleading or deceptive to the user accessing the X Network, which may include methods such as offering incentives, points, rewards, cash, prizes, or anything else of monetary value, or any other methods that are malicious or fraudulent.
### 6. Incorporated Terms.
Company’s access to any given Individual Product and/or the associated X Materials is conditioned upon Company’s acceptance of, and compliance with, the following policies (collectively, the "**X Policies**"), each solely to the extent applicable to the Individual Product and X Materials that Company is accessing and/or using:
**6.1** Privacy Policy ([https://x.com/privacy](https://x.com/privacy))
**6.2** Terms of Service ([https://x.com/tos](https://x.com/tos))
**6.3** Applicable X Master Services Agreement ([https://legal.x.com/ads-terms/us.html](https://legal.x.com/ads-terms/us.html)) ([https://legal.x.com/ads-terms/international.html](https://legal.x.com/ads-terms/international.html)) or other such X Master Services Agreement referenced on an insertion order.
**6.4** Ads Policy Guidelines ([https://business.x.com/en/help/ads-policies](https://business.x.com/en/help/ads-policies)), including the Policies for Conversion Tracking and Custom Audiences ([https://business.x.com/en/help/ads-policies/campaign-considerations/policies-for-conversion-tracking-and-custom-audiences](https://business.x.com/en/help/ads-policies/campaign-considerations/policies-for-conversion-tracking-and-custom-audiences))
**6.5** Developer Agreement and Policy ([https://docs.x.com/developer-terms/agreement](/developer-terms/agreement))
**6.6** X Trademark and Brand Guidelines ([https://about.x.com/who-we-are/brand-toolkit](https://about.x.com/who-we-are/brand-toolkit))
Company agrees to the X Policies to the extent that Company accesses or uses Individual Products to which the individual policies apply. Company accepts and agrees that the X Policies may be modified by X from time to time in X’s sole discretion. In the event of a material modification to the X Policies that impacts Company, X will provide Company notice (such as by email or as may be posted on the X Service) of any such change. Company’s continued access or use of the X Materials and X Marks following any such updates or modifications will constitute binding acceptance of the updates and modifications.
### 7. Term; Termination Rights; Suspension Rights.
**7.1 Term.** This Agreement will commence on the Effective Date and will remain in effect for one (1) year (the “**Initial Term**”) and automatically continue thereafter for additional, successive one (1) year terms (each a “**Renewal Term**”), unless either party provides written notice of non-renewal at least thirty (30) days prior to the expiration of the Initial Term or terminates this Agreement in accordance with Section 7.2 below. The Initial Term and all Renewal Terms will collectively constitute the (“**Term**”).
**7.2 Termination; Suspension.** Upon completion of the Initial Term and the commencement of a Renewal Term, either party may terminate this Agreement for convenience upon provision of thirty (30) days’ prior notice to the other party. X may immediately terminate this Agreement upon written notice to Company if Company: (a) merges or is acquired, in whole or in part, by any third party, whether voluntarily or involuntarily, and/or by operation of law (including, without limitation, in connection with a merger, acquisition, or sale of assets, whether Company is the surviving or disappearing entity); or (b) has a receiver or similar party appointed for its property, becomes insolvent, acknowledges its insolvency in any manner, ceases to do business, makes an assignment for the benefit of its creditors, or files a petition in bankruptcy. Without limiting any other remedy in this Agreement or available at law or in equity, X may immediately suspend Company’s access to, or use of, the Ads Products, any given Individual Product, and/or the X Materials (or any part thereof) or terminate any and all license(s) granted to Company under this Agreement or this Agreement in its entirety, at any time and without notice, if X, in its sole discretion, believes or determines that: (i) Company is in violation of any of the Our Policies, or has breached or attempts to breach or is in non-compliance with any term or condition of this Agreement, and/or (ii) Company’s continued access to the Ads Products, a given Individual Product, and/or the X Materials will or may cause liability for X and/or X’s Clients or otherwise harm X or X’s Client’s service, business, or reputation.
**7.3 Effect of Termination.** Upon expiration or termination of this Agreement: (a) all rights and licenses granted hereunder will immediately cease and Company shall immediately cease accessing and using the X Materials; (b) within thirty (30) days of such expiration or termination, Company will remove, delete and securely erase all X Materials (including all copies and portions thereof) in all forms and types of media from the Company Service or otherwise in Company’s possession or control; and (c) within thirty (30) days of such expiration or termination, Company will delete and securely erase all copies of any Confidential Information (as defined below in Section 9) in Company’s possession or control. X will not be liable for any costs, expenses, or damages as a result of its termination of this Agreement.
**7.4 Wind Down Period.** Notwithstanding the foregoing, in the event that either party terminates this Agreement pursuant to this Section 7, the terms and conditions of this Agreement, and the respective rights and obligations of the parties hereto, shall, at X’s sole election (and upon X’s written notification to Company of such election), continue to apply during a Wind-Down Period (as defined below) solely with respect to any and all Client advertising campaigns that are then ongoing at the time of such termination (which shall include, without limitation, circumstances in which X and/or the applicable Client have elected to run an advertising campaign, even if such advertising campaign has not actually commenced at the time of termination). As used herein, “**Wind-Down Period**” shall mean a period commencing upon the termination of the Term and continuing until the earlier of: (i) ninety (90) days following such termination date; or (ii) the completion of all Client advertising campaigns that were then ongoing (as described above) as of such termination date.
**7.5 Survival.** Those terms that by their nature should survive either expiration or termination of this Agreement, shall survive, including, but not limited to, Sections 3-15.
### 8. Security; Security Breaches; Regulatory Notice; Data Deletion; Audit.
**8.1 Security.** Company will use industry-standard security measures in connection with its performance under this Agreement, including, but not limited to, administrative, technical, and physical security measures for data transmission and storage at least as restrictive as industry-standard security measures for the transmission and storage of the types of data included in the X Materials. Company will also use reasonable technical and organizational security measures (including, at a minimum, password protection and access protocol restrictions), and in no event less care than it uses in connection with transmitting and securing Company’s own data of the same or similar nature, to restrict access to X Materials and Confidential Information to only those individual Company personnel who need to access such X Materials in order to exercise Company’s rights and/or fulfill Company’s obligations pursuant to this Agreement.
**8.2 Security Breaches.** Company shall notify X in writing (which may include email) within twenty-four (24) hours of becoming aware of any security breach or other improper access that resulted, may have resulted, or had the potential to result, in exposure of any X Materials and/or data related to, based upon, or arising from, this Agreement. Company will consult and cooperate with X in any investigations, provide any required notices and/or provide any information reasonably requested by X.
**8.3 Regulatory Inquiries.** Company shall notify X in writing (which may include email) within twenty-four (24) hours of Company’s receipt of notice of any inquiry from a government or regulatory agency concerning a security breach (or similar incident), Company’s alleged misuse of consumer data, or any other aspect of Company’s operations that are reasonably related, either directly or indirectly, to this Agreement.
**8.4 Data Deletion.** Company shall delete and securely erase any and all X Materials from its systems when Company no longer has a legitimate business need to retain such X Materials in order to exercise Company’s rights and/or fulfill Company’s obligations under this Agreement (including, without limitation, in the event that the applicable Client ceases to use the Ads Products or otherwise ceases to use the Company Services), but in no event later than the earlier of: (a) ninety (90) days from the date that Company first receives the applicable Data, or (b) thirty (30) days following the expiration or termination date of the Agreement. In addition, at any time, Company agrees to delete and securely erase, immediately upon X’s written request (which may be delivered via email), any X Materials that X deems necessary or desirable to delete and securely erase (in X’s sole and absolute discretion).
**8.5 Audit.** Upon reasonable prior written notice (of no less than ten (10) days), no more than twice each calendar year during the Term and once during the six (6) month period after the date that this Agreement terminates or expires, at X’s expense, X shall be provided access to Company facilities to audit the processes, methodologies, practices and systems used by Company in performance of its obligations and exercising its rights under this Agreement. For clarity, Company acknowledges and agrees that (i) X may engage a third-party auditor to perform any such audit on its behalf; and (ii) notwithstanding anything to the contrary herein, X may share any relevant Confidential Information concerning Company (including, without limitation, the terms and conditions of this Agreement) with such third-party auditor solely as required to facilitate any such audit.
### 9. Confidential Information.
Each party agrees that all business, technical and financial information that is designated as “confidential” or “proprietary,” or that is disclosed in a manner that a reasonable person would understand the confidential nature of the information being disclosed by the disclosing party (“**Confidential Information**”). For clarity, all proprietary information provided by X to Company pursuant to this Agreement, which includes, without limitation, information (tangible or intangible) regarding X’s technology, designs, techniques, research, know-how, specifications, product plans, pricing, customer information, user data, current or future strategic information, current or future business plans, policies or practices, employee information, and other business and technical information (including, without limitation, results, analysis or data regarding uptime, reliability, traffic and growth metrics, network quality, and other usage statistics of the X Service, in the aggregate or otherwise, derived from Company’s use of the X Materials or the X Service and/or access to technical documentation, developer newsletters and/or online portals or forums) is X Confidential Information and proprietary to X. Without limiting the foregoing, the terms and conditions of this Agreement, the X Materials, any product requirements, and any other documentation, onboarding processes or other materials provided by X to Company under this Agreement shall be deemed X Confidential Information. Except as expressly allowed herein, the receiving party will hold in confidence and not use or disclose (except in connection with the performance of such party’s obligations under this Agreement) any Confidential Information of the disclosing party. The receiving party shall not be obligated under this Section with respect to information that the receiving party can document through writing or testimony that such information: (i) is or has become readily publicly available through no fault of the receiving party or its employees or agents; (ii) is received from a third party lawfully in possession of such information, and the receiving party has no knowledge of any disclosure restrictions on such third party to disclose such information; (iii) is disclosed to a third party by the disclosing party without restriction on disclosure; (iv) was rightfully in the possession of the receiving party without restriction prior to its disclosure by the other party; or (v) was independently developed by employees or consultants of the receiving party without reliance on such information. The receiving party may make disclosures required by law or court order, provided that the receiving party notifies the disclosing party of the issuance of such order and allows the disclosing party to participate in the proceeding.
### 10. Representations and Warranties.
Company represents and warrants that: (i) it has all requisite legal and corporate power to enter into this Agreement; (ii) it has taken all action required to make this Agreement a legal, valid and binding obligation; (iii) it has no agreement or understanding with any third party that interferes with or will interfere with its performance of its obligations under this Agreement; (iv) it has obtained and shall maintain all permissions, consents, rights, approvals and licenses necessary to perform its obligations and grant all rights and licenses granted under this Agreement including, without limitation, all rights necessary for Company to grant X a license to use Company Materials to place ads on any advertising inventory available or accessible to X on the X Service or otherwise and provide the Company Service; (v) the Company Service and Company Materials do not, and will not, infringe, misappropriate or otherwise violate any third party rights; and (vi) its business and performance under this Agreement, including its provision of the Company Service, is and shall be in compliance with all applicable foreign, federal, state and local laws and government rules and regulations. Company further represents and warrants that: (a) it has no knowledge of any actual, pending, or threatened claims, lawsuits, actions, or charges pertaining to the Company Service, any Company Materials or other deliverables related to this Agreement or Company’s practices regarding data security, data use, or privacy; and (b) in the event that Company is accessing or using the Ads Products (or any aspect thereof) on behalf of a Client, Company has the authority as agent to such third party to use such Company Materials on such third party’s behalf, to convey the rights to such third party materials as may be provided to X in the Company Materials, and to bind such third party to the terms of this Agreement.
### 11. Feedback. Beta Services.
If and to the extent that X provides (in its sole and absolute discretion) Company with any access to any features and functionality that are designated private, unreleased, in development, or in “alpha” or “beta” (collectively, “**Beta Services**”), Company acknowledges and agrees that Beta Services are not supported by X, and Beta Services (or any portion thereof) may be launched publicly or made unavailable at any time (in each case, in X’s sole and absolute discretion). Beta Services are provided “AS IS” to the fullest extent of the law, and Company’s use of such Beta Services is at Company’s own risk and consent. All Beta Services will be considered X Confidential Information. Company agrees that participation in any Beta Service will assist X in research, analyzing and validating some existing and/or prospective programs, products and/or tools, and that if Company provides X with any comments, feedback or other information to assist X in evaluating and improving such programs, products and/or tools (“**Feedback**”), X and its designees will be free to copy, modify, create derivative works, publicly display, disclose, distribute, license and sublicense, incorporate, and otherwise use the Feedback, including derivative works thereto, for any and all commercial and non-commercial purposes with no obligation or compensation of any kind to Company or any third party. For clarification, Feedback does not include and X will not use Company’s name or publicly disclose Company’s Beta Services performance results. Feedback will also include any Company comments concerning the X Materials, the Ads Products, and/or Company’s evaluation and use thereof. Company agrees that nothing in this Agreement will prevent X from developing products or services that may be competitive with Company’s or any Clients’ or End Users’ products or services.
### 12. Warranty Disclaimer.
THE X MATERIALS, THE ADS PRODUCTS, AND ANY OTHER X PRODUCTS AND SERVICES (INCLUDING, WITHOUT LIMITATION, ANY BETA SERVICES) AND ANY X MARKS PROVIDED HEREUNDER ARE PROVIDED “AS IS” AND ON AN “AS AVAILABLE” BASIS, WITHOUT WARRANTY OF ANY KIND. X DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTIES OR CONDITIONS ARISING OUT OF COURSE OF DEALING OR USAGE OF TRADE. X DOES NOT WARRANT THAT THE X MATERIALS, THE ADS PRODUCTS, AND ANY OTHER X PRODUCTS AND SERVICES (INCLUDING, WITHOUT LIMITATION, ANY BETA SERVICES) OR ANY X MARKS PROVIDED HEREUNDER WILL MEET COMPANY’S REQUIREMENTS OR THAT USE OF SUCH X MATERIALS, OTHER X PRODUCTS AND SERVICES AND/OR ANY X MARKS WILL BE ERROR-FREE, UNINTERRUPTED, VIRUS-FREE, OR SECURE. THIS DISCLAIMER OF WARRANTY MAY NOT BE VALID IN SOME JURISDICTIONS, AND COMPANY MAY HAVE WARRANTY RIGHTS UNDER LAW WHICH MAY NOT BE WAIVED OR DISCLAIMED. ANY SUCH WARRANTY EXTENDS ONLY FOR THIRTY (30) DAYS FROM THE EFFECTIVE DATE OF THIS AGREEMENT (UNLESS SUCH LAW PROVIDES OTHERWISE).
### 13. Indemnification.
Company will defend, at its own expense, any claim, suit or action against X brought by a third party to the extent that such claim, suit or action is based upon an allegation that (i) the Company Materials, the Company Service, the Company Marks, X’s use of the Company Materials or Company Marks, or the technology used to generate the Company Materials and/or the Company Service infringes any rights of any third party (including, without limitation, any intellectual property rights, privacy rights or publicity rights); (ii) Company has breached any of its obligations, representations or warranties hereunder, including Company’s data security, data use, and privacy obligations or (iii) Company’s unauthorized use of the X Materials and/or X Marks in violation of the terms, conditions and restrictions set forth in the Agreement. Company will indemnify and hold X harmless from and against any losses, damages, liabilities, penalties, costs and expenses attributable to any such claim. Company is responsible for defending any claim against X, subject to X’s right to participate with counsel of its own choosing, and for payment of all judgments, settlements, damages, losses, liabilities, costs, and expenses, including reasonable attorney’s fees, resulting from all claims against X, provided that Company will not agree to any settlement related to any claims without X’s prior express written consent regardless of whether or not such settlement releases X from any obligation or liability. X will give Company prompt notice of an indemnification obligation (provided that failure to do so will only relieve Company of its obligation to the extent it can demonstrate material prejudice from the failure).
### 14. Limitation of Liability.
IN NO EVENT WILL X BE LIABLE TO COMPANY OR ANY CLIENTS OR END USERS FOR ANY SPECIAL, INCIDENTAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR FOR LOST REVENUE, LOST PROFITS, COSTS OF REPLACEMENT OF GOODS OR SERVICES, LOSS OF TECHNOLOGY, GOODWILL, RIGHTS OF SERVICES, LOSS OF DATA OR INTERRUPTION OR OF LOSS OF USE OF SERVICE ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, OR FOR COMPANY’S OR CLIENT’S OR END USER’S USE OF THE X MATERIALS, X MARKS OR ANY X PRODUCTS AND/OR SERVICES (INCLUDING, WITHOUT LIMITATION, THE ADS PRODUCTS) PROVIDED HEREUNDER, WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY, OR OTHERWISE, AND WHETHER OR NOT X HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. INSOFAR AS APPLICABLE LAW PROHIBITS ANY LIMITATION ON LIABILITY HEREIN, THE PARTIES AGREE THAT SUCH LIMITATION WILL BE AUTOMATICALLY MODIFIED, BUT ONLY TO THE EXTENT SO AS TO MAKE THE LIMITATION COMPLIANT WITH APPLICABLE LAW. THE PARTIES AGREE THAT THE LIMITATIONS ON LIABILITIES SET FORTH HEREIN ARE AGREED ALLOCATIONS OF RISK AND WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY. IN ANY CASE, X’S AGGREGATE LIABILITY UNDER THIS AGREEMENT WILL NOT EXCEED FIFTY U.S. DOLLARS (U.S. \$50).
### 15. Miscellaneous.
**15.1 Publicity.** Company may not issue any press release, blog post or otherwise make any public announcement or disclosure concerning this Agreement, any of the activities contemplated hereunder, or concerning the relationship between Company and X without X’s prior written consent (which may be provided by email).
**15.2 User Protection.** Company will not (a) knowingly allow or assist any government entities, law enforcement, or other organizations to conduct surveillance on the X Service or the X Materials or obtain information on X’s users or their posts that would require a subpoena, court order, or other valid legal process, or that would otherwise have the potential to be inconsistent with X’s users’ reasonable expectations of privacy; or (b) display, distribute or otherwise make available X Materials to any person or entity that Company reasonably believes will use such data to violate the Universal Declaration of Human Rights (located at [https://www.un.org/en/universal-declaration-human-rights/index.html](http://www.un.org/en/universal-declaration-human-rights/index.html)), including without limitation Articles 12, 18, or 19. Any law enforcement personnel seeking information about X users will be referred to X’s Guidelines for Law Enforcement located at [https://help.x.com/rules-and-policies/x-law-enforcement-support](https://help.x.com/rules-and-policies/x-law-enforcement-support).
**15.3 Government Use.** The X Materials may be “commercial items” as that term is defined at 48 C.F.R. 2.101, consisting of “commercial computer software” and “commercial computer software documentation” as such terms are used in 48 C.F.R. 12.212. Any use, modification, derivative, reproduction, release, performance, display, disclosure or distribution of the X Materials by any government entity is prohibited, except as expressly permitted by the terms of this Agreement. Additionally, any use by U.S. government entities must be in accordance with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4. Contractor/manufacturer is X Corp., 865 FM 1209, Building 2, Bastrop, TX 78602, USA.
**15.4 Compliance with Laws; Export/Import.** Each party will comply with all applicable foreign, federal, state, and local laws, rules and regulations. Company shall not export or re-export X Services or X Data in violation of the Our Policies (as defined herein) or applicable law. The X Materials may be subject to U.S. export laws and may be subject to import and use laws of the country where it is delivered or used. Company agrees to abide by these laws. Under these laws, the X Materials may not be sold, leased, downloaded, moved, exported, re-exported, or transferred across borders without a license, or approval from the relevant government authority, to any country or to any foreign national restricted by these laws, including countries embargoed by the U.S. Government; or to any restricted or denied end-user including, but not limited to, any person or entity prohibited by the U.S. Office of Foreign Assets Control; or for any restricted end-use.
**15.5 Modifications.** X may update or modify the Our Policies, Analytics Data Display Requirements (attached as [Exhibit A-2](#Exhibit-A-2)), the “X Marketing Partner” program-related terms and conditions (attached as [Exhibit C](#Exhibit-C)) and any other technical documentation and any other guidelines or policies related to the X Materials from time to time, at X’s sole discretion, by posting the changes, as applicable, on X’s developer site, located at: [https://developer.x.com](https://developer.x.com) (as may be amended from time to time), the URL where the applicable X Policy is posted or by otherwise notifying Company (such notice may be via email). If any change is unacceptable to Company, Company’s only recourse is to cease all use of the X Materials and X Marks.
**15.6 Notices.** Except as otherwise stated in Sections 6 and 15.5, any notice required or permitted by this Agreement shall be in writing and shall be delivered as follows, with notice deemed given as indicated: (a) by personal delivery when delivered personally; (b) by overnight courier upon written verification of receipt; (c) by certified or registered mail, return receipt requested, upon verification of receipt; or (d) by electronic mail when the recipient acknowledges having received the applicable email. Notice shall be sent to the addresses set forth below or such other address as either party may specify in writing. Notices for breach sent by Company to X must be sent via overnight courier or certified or registered mail only. Notices to Company will be sent to the Company address on record with X. Notices to X Corp. will be delivered to: X Corp., 865 FM 1209, Building 2, Bastrop, TX 78602, USA, Attn: Legal Department, with a compulsory copy to: Head of Ads API and [legalnotices@x.com](mailto:legalnotices@x.com). Notices to X Internet Unlimited Company will be delivered to: Legal Department, X Internet Unlimited Company, One Cumberland Place, Fenian Street, Dublin 2, D02 AX07, Ireland.
**15.7 Assignment.** Company may not assign this Agreement or any of the rights or obligations granted hereunder, in whole or in part, to any third party, whether voluntarily, involuntarily and/or by operation of law (including, without limitation, in connection with a merger, acquisition, or sale of assets, whether Company is the surviving or disappearing entity), except with the express written consent of X, and any attempted assignment in violation of this paragraph is null and void, and X may immediately terminate this Agreement. This Agreement will bind and inure to the benefit of each party’s permitted successors and assigns.
**15.8 No Subcontractors.** Company may not use a third party to perform or fulfill any of Company’s obligations or duties under this Agreement, unless approved in advance by X in writing, which approval may be provided by email.
**15.9 No Partnership.** This Agreement does not create or imply any partnership, agency or joint venture. No waiver by either party of any covenant or right under this Agreement will be effective unless memorialized in a writing duly authorized by such party.
**15.10 No Third-Party Beneficiaries.** There shall be no third-party beneficiaries to this Agreement.
**15.11 Severability.** If any part of this Agreement is determined to be invalid or unenforceable by a court of competent jurisdiction, that provision will be enforced to the maximum extent permissible and the remaining provisions of this Agreement will remain in full force and effect.
**15.12 Waiver.** The waiver by either party of a breach of any provision of this Agreement by the other party shall not operate or be construed as a waiver of any other or subsequent breach by that party. No waiver by X of any covenant or right under this Agreement will be effective unless memorialized in a writing duly authorized by X.
**15.13 Class Action Waiver.** To the extent permitted by law, you also waive the right to participate as a plaintiff or class member in any purported class action, collective action or representative action proceeding.
**15.14 Governing Law and Jurisdiction.** If X Corp. is the contracting entity hereunder, the terms of the Agreement and any dispute relating thereto or between Company and X will be governed by the laws of the State of Texas, without regard to conflict/choice of law principles. The United Nations Convention on Contracts for the International Sale of Goods does not apply to the Agreement. If a dispute, claim or controversy arising out of or relating to this Agreement or the breach, termination, enforcement, interpretation or validity thereof, including the determination of the scope or applicability of this agreement to arbitrate arises, Company agrees to provide X with notice of the dispute, and to provide a ten (10) business day resolution period in which X and Company may attempt to work out the dispute informally. If, after the ten (10) business day resolution period, X and Company cannot resolve the dispute, Company agrees to bring any dispute or claim arising out of this Agreement in the U.S. District Court for the Northern District of Texas or state courts located in Tarrant County, Texas, United States, and you consent to personal jurisdiction in those forums and waive any objection as to inconvenient forum. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute we have against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
If you are a federal, state, or local government entity in the United States acting in your official capacity and legally unable to accept the controlling law, jurisdiction or venue clauses above, then those clauses do not apply to you. For such U.S. federal government entities, this Agreement and any action related thereto will be governed by the laws of the United States of America (without reference to conflict of laws) and, in the absence of federal law and to the extent permitted under federal law, the laws of the State of Texas (excluding choice of law).
If X Internet Unlimited Company is the contracting entity hereunder, the terms of the Agreement and any dispute relating thereto or between Company and X will be governed by the laws of Ireland, without regard to conflict/choice of law principles. The parties agree that neither the United Nations Convention on Contracts for the International Sale of Goods, nor the Uniform Computer Information Transaction Act (UCITA) shall apply to this Agreement, regardless of the states in which the parties do business or are incorporated. Any dispute, claim or controversy arising out of or relating to this Agreement or the breach, termination, enforcement, interpretation or validity thereof will be brought exclusively before a competent court in Ireland without regard to conflict of law provisions and will be governed by Irish law, notwithstanding any agreement between you and us to the contrary. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute we have against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
YOU HAVE ONE YEAR TO BRING A CLAIM AGAINST X. You must bring any claim against X arising out of or related to this Agreement within one (1) year after the date of the occurrence of the event or facts giving rise to the dispute, unless applicable law provides that the normal statute of limitations for that claim may not be shortened by agreement. If you do not bring a claim within this period, you forever waive the right to pursue any claim or cause of action, of any kind or character, based on such events or facts, and such claims or causes of action are permanently banned, and X will have no liability with respect to such claim
**15.15 Injunctive Relief.** Each party agrees that money damages would be an inadequate remedy in the event of a breach or threatened breach of the provisions in this Agreement protecting X’s intellectual property (including, without limitation, the X Materials) and/or X’s Confidential Information, and that, in the event of such a breach or threat, X, in addition to any other remedies to which X is entitled, is entitled to such preliminary or injunctive relief (including an order prohibiting the other party from taking actions in breach of such provisions), without the need for posting bond, and specific performance as may be appropriate to preserve all of X’s rights.
**15.16 Updates.** X may update the terms of this Agreement and any policies referenced herein from time-to-time, at its sole discretion, and will provide email notice to Company or posting notice to the URL identified below. Such notice will indicate the effective date of any such updates. The terms of this Agreement will be available for Company to view at any time at [https://docs.x.com/developer-terms/ads-api-agreement](/developer-terms/ads-api-agreement). Company’s continued use of any Individual Product(s) after the effective date provided in the applicable notice will indicate Company’s acceptance of such updates.
**15.17 Entire Agreement.** This Agreement (including the Exhibits attached hereto) constitutes the entire agreement between the parties relating to this subject matter hereof and supersedes and replaces all prior or contemporaneous proposals, understandings, communications and agreements, oral or written, concerning such subject matter. Any amendments to this Agreement shall be made in writing and signed by a representative of the respective parties authorized to bind the parties.
## Exhibit A: Individual Product Terms/X Ads API
Capitalized terms not defined in these Individual Product Terms have the meaning set forth in the main body of the Agreement. To the extent that Company participates in the “X Ads API Program,” the following terms and conditions of this Exhibit A (including Exhibit A-1 and Exhibit A-2) will apply:
### 1. X Ads API Introduction; Access.
**1.1 Introduction.** The X advertising application programming interface (API), and the accompanying documentation, code and related materials (collectively, the “**X Ads API**”) that provides Company with “read/write” access that allows Company to engage in Campaign Management of X Ads and/or with “read” access to certain reporting of Data about the performance of X Ads Campaigns.
**1.2 API Access.** X will (in its sole and absolute discretion) decide if and whether to grant Company “read” or “read/write” X Ads API access. X may implement a review process for granting X Ads API access, but is not required to do so.
### 2. Ads API License.
On condition that X decides to provide Company X Ads API access, and subject to Company’s continuing compliance with terms and conditions of the Agreement, X grants Company a limited, non-exclusive, non-transferable, non-sublicensable, revocable license during the Term to: (a) use the X Ads API to implement the Company Service for the purpose of providing a Client’s End Users with access to Data related to such Client’s X Ads Campaigns (and, if Company has “read/write” API access, to enable Campaign Management of X Ads through the Company Service); (b) display the Data in aggregated format solely within the Company Service in accordance with the Analytics Data Display Requirements (defined below in Section 3 of this Exhibit A) to a Client’s End Users solely for the purpose of optimizing such Client’s X Ads Campaigns; (c) modify the Data only as necessary to format it for, and display it, within the Company Service; (d) enable the Company Service to export Data only in a format that X has approved in writing and that complies with the Analytics Data Display Requirements and via an export mechanism that is approved by X in writing; and (e) use and display the X Marks that X makes available for use in connection with the X Ads API and/or Data solely to attribute X as the source of the Data or as otherwise expressly permitted under the Agreement (in each instance, in accordance with the X Trademark Guidelines).
### 3. Display Requirements, Integration and Other Requirements.
Company’s implementation and use of the X Ads API and Data must at all times comply with: (a) the product requirements attached hereto as Exhibit A-1 (“**Product Requirements**”); (b) the display requirements attached hereto as Exhibit A-2 (“**Analytics Data Display Requirements**”); (c) all technical documentation for the X Ads API that has been, or will be, provided to Company by X (including, without limitation, any endpoint specifications or requirements); (d) any onboarding processes specified by X related to the X Ads API and Data; (e) the Our Policies; and (f) any other guidelines and policies applicable to the X Ads API and Data that may be provided to Company by X.
### 4. Compliance.
Company will abide by all instructions provided or communicated to Company by X, including, without limitation, the limitations on access, calls and use of the X Ads API and any additional limitations or restrictions related to tokens, rate limits, keys, passwords or other login credentials to the X Ads API. Any such instructions are determined by X in its sole and absolute discretion. Company shall comply with any X request to inspect and access the Company Service, including, without limitation, providing X with any Company Service code related to the implementation of the X Ads API, to ensure that the integration of the X Ads API into, and display of the Data within, the Company Service complies with the Product Requirements and Analytics Data Display Requirements, X quality controls and/or other terms and conditions of this Agreement. X may monitor Company’s use of the X Ads API to improve the X Services.
### 5. Control of Allocation of X Ads Inventory.
For clarity, and without limiting the generality of any other term or condition of this Agreement, nothing in this Agreement is meant to represent or imply that Company or the Company Service will have access, via the X Ads API, to any particular inventory or category of X Ads, and X may (in its sole and absolute discretion) elect from time to time, to limit, without restriction, the allocation of X Ads inventory to which Company or the Company Service has access (e.g., without limitation, due to X’s strategic decisions concerning sales channels, direct vs. non-direct client relationships, agency relationships, etc.).
### 6. Control of X Ads Features, API Calls and Functionality.
For clarity, and without limiting the generality of any other term or condition of this Agreement, nothing in this Agreement is meant to represent or imply that Company or the Company Service will have access, via the X Ads API, to any particular X Ads feature, API call or functionality, and X may (in its sole and absolute discretion) elect from time to time, to limit, without restriction, those X Ads features, API calls and/or functionalities to which Company or the Company Service has access (for any or no reason).
### 7. Geography Data.
Company will not (and will not allow others to) use or access the X Ads API to aggregate, cache or store place or other geographic location information contained in any Data or otherwise.
### 8. Removals.
When requested by X, through the X Ads API or otherwise, Company will promptly: (a) delete Data from the Company Service that X reports as deleted or expired; (b) change Company’s treatment of Data that X reports is subject to changed sharing options; and (c) modify Data on the Company Service that X reports has been modified. Company is responsible for the quality of X Ads transmitted to the X Service by the Company Service. X reserves the right to revoke access to the X Ads API and/or, if applicable, remove any specific X Ads from the X Service for any objectionable use by Company or Clients.
### 9. Updates.
Company acknowledges that X may update or modify the X Ads API, from time to time, and in X’s sole and absolute discretion (in each instance, an “**Update**”). Unless otherwise mutually agreed by X and Company in advance in writing (email to suffice), Company is required to implement and use the most current version of the X Ads API and to make any changes to the Company Service, at Company’s sole cost and expense, that are required as a result of such Update no later than thirty (30) days from the date that X notifies Company of the Update. Company will implement all tools (if any) provided by X to enable Updates, as applicable. Updates may adversely affect the manner in which the Company Service accesses or communicates with the X Ads API or displays Data. Company’s continued access or use of the X Ads API following any such Update will constitute binding acceptance of the Update.
### 10. Support.
Company is responsible for providing all support and technical assistance to Clients and their End Users regarding the use of the Company Service (including any issues related to any Ads Product). X is not obligated to provide support or technical assistance directly to Company or any Clients or any of their End Users, and Company will not represent to any Clients or any of their End Users that X is available to provide such support.
## Exhibit A-1: Product Requirements
The Company Service should enable marketers to more efficiently optimize X Ads campaigns, take advantage of X’s real-time conversation, and develop X Ads that improve the user experience.
Accordingly, the Company Service, at all times, will meet the following requirements:
### 1. Product Pricing. No Monetization.
Paid access to the Company Service must be priced on a fixed or variable percentage of spend fee structure. Company will not charge Clients a premium for access to X Ads and/or Data through the Company Service in excess of Company’s standard rates for the Company Service.
### 2. Transparency.
**2.1 Spend.**
2.1.1 Any pricing reports delivered by Company to Clients and their End Users must clearly state and itemize (i) the X Ads spend in X’s native metrics (e.g., as applicable, CPE/CPF) and (ii) the fees charged for use of the Company Service. In addition, Company must always include CPE or CPF metrics (or other applicable X native metrics) adjacent to last-click attribution metrics (e.g., CPC) or other reporting metrics (e.g. CPM).
2.1.2 Company Service will include a self-serve reporting dashboard that will include the capability for Company to report on all metrics provided via the X Ads API.
**2.2 Data.** Company will: (i) use commercially reasonable efforts to maintain up-to-date Data within the Company Service in connection with the X Integration (defined below in Section 6.3 of this Exhibit A-1) in accordance with the then-current Analytics Data Display Requirements; and (ii) clearly disclose to Clients and their End Users any material delay inherent in any information regarding Client’s X Ads Campaigns and/or related analytics data.
### 3. Accounts.
Each End User must be given a separate account to access the Company Service, including a unique user name and password.
### 4. Company Service.
Each customized version of the Company Service for a specific Client (including, without limitation, a white-labeled version of Company Service for a specific Client) must be approved by X in advance and in writing (email to suffice for such purposes).
### 5. Clients and Account Management.
**5.1** A Client must be given the ability to quickly and easily disassociate its X Ads Campaigns from the Company Service and regain exclusive, direct control of its X Ads account(s).
**5.2** Only a Client and its End Users may be allowed to view such Client’s account data or features via the Company Service.
### 6. Other Requirements.
**6.1** Any Company Service functionality that replicates a X feature will utilize X’s naming nomenclature and feature names, subject to any applicable X Trademark Guidelines.
**6.2** Unless otherwise mutually agreed by the parties in advance and in writing, Company will not provide Clients and their End Users or any other third party with access to Data except for the aggregated derivations of such material embodied in the user interface of the Company Service.
**6.3** Company may not commercialize, market or provide access to any X Materials to any third parties (including any Clients or their End Users) until the implementation of the X Ads API and integration and display of any Data within Company Service (collectively, the “**X Integration**”) has been approved in advance by X via the process described in this Section. Company will give X access to the Company Service so that X can review the X Integration. X will inform Company in writing (email being sufficient) if the X Integration is approved or rejected (in X’s sole discretion). Throughout the Term, Company will submit to X any changes to the Company Service that affect the X Integration, which X shall have the right to approve or reject in writing (email being sufficient), in X’s sole discretion.
## Exhibit A-2: Analytics Data Display Requirements
These Analytics Data Display Requirements govern how Company can display Data within the Company Service. Company agrees to abide by these Analytics Data Display Requirements at all times.
### Defined Metrics
All campaigns shown in the Company Service that display Data must include the specific X-defined metrics associated with various campaign objectives (each, a “**Campaign Objective**”), which metrics must be calculated by Company based on the endpoints and formulas located at: [https://docs.x.com/x-ads-api/analytics#metrics-by-objective](https://docs.x.com/x-ads-api/analytics#metrics-by-objective) (or any other successor URL that X may elect from time to time).
### Display Guidelines
**1.** The applicable defined metrics for a given Campaign Objective (as described above in the Defined Metrics section of this Exhibit A-2) must be shown every time a campaign is displayed within the Company Service.
**2.** If the Company Service displays any organic post analytics data, Company must comply with the X Developer Agreement & Policy located at: [https://docs.x.com/developer-terms/agreement](/developer-terms/agreement) as it relates to Company’s implementation, use and display of the organic post analytics data.
**3.** If the Company Service displays metrics about campaigns run on third party networks or by third party publishers (i.e., “cross-channel metrics”) side-by-side with Data, then the following requirements and restrictions apply:
**3.1** Any cross-channel metrics displayed alongside the Data in the Company Service can only include the same category of campaign objective metrics as the applicable X-defined Campaign Objective metrics for such campaign (as described above in the Defined Metrics section of this Exhibit A-2).
By way of example only - If an advertiser is running an app install campaign on a third-party network, only cross-channel metrics that are of the same category as the applicable X-defined metrics for the app install Campaign Objective can be shown alongside the Data.
**3.2** Aggregating data to display cross-channel metrics is not permitted unless the aggregated metrics can be referenced (across all third-party networks/publishers) against a category of metrics associated with a campaign objective that is the same to the applicable X-defined Campaign Objective metrics (as described above in the Defined Metrics section of this Exhibit A-2). By way of example only - Aggregating total engagements for network A, network B, and network C would not be permitted if engagement rates across all channels are not calculated using the same formulas.
**4.** If the Company Service displays any category of metrics sourced from third parties other than X (“**third-party-sourced metrics**”), then the following requirements and restrictions apply:
**4.1** The same requirements and restrictions that apply to displaying cross-channel metrics set forth above in Section 3 apply to the display of any third-party-sourced metrics.
**4.2.** Any third-party-sourced metrics that are displayed alongside Data for a campaign in the Company Service must be the same category of campaign objective metrics as the applicable X-defined Campaign Objective metrics for such campaign (as described above in the Defined Metrics section of this Exhibit A-2). By way of example only:
* If Company displays link click and click-rate metrics from a third-party source, Company will display X’s click and click-rate metrics alongside the third-party-sourced link click and click rate metrics.
* If Company or any of its Clients uses a third-party tracking solution to track website clicks from Promoted posts and such data is displayed in the Company Service, Company must show link clicks, click rate, cost per link click and CPA from X (if available) alongside such third-party-sourced data.
**4.3** Notwithstanding Section 4.2 of this Exhibit A-2, if the third-party-sourced metrics are from a third-party tracking solution provided by a X Conversion Tracking Partner (as defined below), then X requires that only the Data delivered through the X Ads API (and not any corresponding data delivered by the X Conversion Tracking Partner) is displayed in the Company Service, unless otherwise agreed by X in writing in advance (in each instance). For the avoidance of doubt, Company will not display any data sourced from a X Conversion Tracking Partner alongside, or in place of, any Data delivered through the X Ads API. As used in this Exhibit A-2, “**X Conversion Tracking Partner**” means an authorized X conversion tracking partner (as designated by X, in its sole and absolute discretion).
## Exhibit B: Individual Product Terms/Custom Audiences
Capitalized terms not defined in these Individual Product Terms have the meaning set forth in the main body of the Agreement. To the extent that Company uses or accesses the X Custom Audiences Program the following terms and conditions of this Exhibit B will apply:
### 1. Custom Audiences.
**1.1 Introduction.** The X Custom Audiences Program allows for the import and creation of specific segments of users (each a “**Custom Audience**”) for the targeting of advertising Campaigns on the X Service. The parties acknowledge that in order to utilize X Custom Audiences Program, Company, its Client, or a third party service provider approved by X (“**Data Partner**”) is required to provide X with a hashed set of users or devices (which may include email, cookies, device IDs, tracking pixels, etc.) in order for X to complete a match with X users and create Custom Audiences. The Custom Audiences created on behalf of a specific client(s) will be stored in each such Client’s X Ads account for use by Company or Client to target, or retarget, as applicable, advertising on the X Service.
**1.2 Data Usage and Opt-Out.** With respect to any data used in connection with the Custom Audiences Program, in addition to the obligations set out in the Data Protection Addendum found at [https://privacy.x.com/en/for-our-partners/global-dpa](https://privacy.x.com/en/for-our-partners/global-dpa), Company agrees and, if applicable, will ensure that its Data Partner(s) agree that (i) Company or such Data Partner (as applicable) have secured all necessary rights, consents, waivers, licenses for use of such data, and (ii) that Company or such Data Partner (as applicable) have provided any users from whom the data is collected with legally-sufficient notice that fully discloses the collection, use, and sharing of the data Company provides to X for purposes of serving ads targeting to users’ interests, and legally sufficient instructions on how users can opt out of X’s interest-based advertising through the methods described here ([https://help.x.com/safety-and-security/privacy-controls-for-tailored-ads](https://help.x.com/safety-and-security/privacy-controls-for-tailored-ads)). Data Company uses in connection with the Custom Audiences Program and/or to create a Custom Audience will not include any data from any user who has opted out of having his/her data used by Company, its Data Partner, or any third party on Company’s behalf. If Company receives a user opt-out after such user was included in an audience provided to X, Company must promptly, but no less frequently than once every twenty-four (24) hours, remove such user(s) from any Custom Audience in which such user was included. Company will provide the data in a format selected by X and acceptable to Data Partner (if/as applicable). In addition to the terms and conditions of this Agreement, Company’s use of X Custom Audiences program will be subject to the terms of the [X Master Services Agreement](https://legal.x.com/ads-terms.html) and Custom Audiences Program T\&Cs and applicable policies, including X’s Policies for Conversion Tracking and Custom Audiences, at [https://legal.x.com/ads-terms.html](https://legal.x.com/ads-terms.html) and [https://business.x.com/en/help/ads-policies/campaign-considerations/policies-for-conversion-tracking-and-custom-audiences](https://business.x.com/en/help/ads-policies/campaign-considerations/policies-for-conversion-tracking-and-custom-audiences).
**1.3 Additional Program Requirements.** Company’s access to, and use of, the X Custom Audience Program is additionally subject to its compliance with the technical instructions and program policies provided by X to Company (the “**Program Integration Spec**”). Company and X will mutually agree on a process for Company to import or upload Custom Audiences to X.
### 2. Shareable Audiences.
Notwithstanding anything to the contrary set forth in Section 1.1 hereinabove, as a service to Company, at Company’s request and in Company’s sole discretion, X may allow Company to “share” Custom Audiences created for Company amongst grouped X advertiser accounts and/or X @handles and/or otherwise with third parties on the X Service. As used herein, “sharing” an audience means that Company would instruct X to, without limitation, enable grouped X Advertiser Accounts and/or X @handles and/or third parties to access, use, and target advertising Campaigns against the “shared” Custom Audience. Company represents and warrants that it has all necessary rights and authority to share any such audience data in accordance with the instructions given to X by Company. If Company is providing the audience data, and/or managing the Custom Audiences on behalf of a third party (including, without limitation, a Client), Company represents and warrants that Company has the authority as agent for such party to use any such data on the third party’s behalf, to grant X the rights described herein, and to bind such third party to the terms of this Agreement. Notwithstanding the foregoing, nothing in this Section requires X to make the functionality that enables “sharing” Custom Audiences described herein (or any portion thereof) available at any time to Company or any other third party (including, without limitation, any Client).
## Exhibit C: Individual Product Terms/X Marketing Partner (TMP) Program
Capitalized terms not defined in these Individual Product Terms have the meaning set forth in the main body of the Agreement. To the extent that Company participates in the “X Marketing Partner program” (the "**TMP**"), the following terms and conditions of this Exhibit C (including Exhibit C-1) will apply:
### 1. X Marketing Partner Program.
If X approves Company’s application for “Advanced” classification status, and Company maintains such classification status throughout the Term, X may, at any time, choose, in X’s sole and absolute discretion, to qualify Company as part of the TMP (or any other successor program name that X may select from time to time). For clarity, X is not required to select Company to participate in the TMP, regardless of whether Company has achieved or maintains “Advanced” classification status. Furthermore, X may, at any time, choose, in X’s sole and absolute discretion, to terminate or suspend Company’s participation in the TMP for any reason upon notice to Company, in which case, Company’s eligibility to receive any benefits associated with participating in the TMP will immediately cease (without any additional notice from X of such election). In addition to the X Trademark Guidelines that govern Company’s use of any X Marks, Company must also comply with the terms and conditions set forth in Exhibit C-1 that govern use of Badges (as defined in Exhibit C-1) provided by X in connection with participation in the TMP. All Badges (as defined in Exhibit C-1) are deemed X Marks under the Agreement.
### 2. No Use of Badges Outside of the TMP.
For the avoidance of doubt, if Company is not currently qualified by X (in its sole and absolute discretion) as a member of the TMP, (i) Company is not eligible to receive any benefits associated with participating in the TMP, including, without limitation, use of any Badges (as defined in Exhibit C-1) and (ii) Company is prohibited from suggesting it participates in, or has any affiliation with, the TMP.
## Exhibit C-1: X Marketing Partner Program Terms
The X Marketing Partner Program Terms set forth below, including, without limitation, any linked terms and conditions appearing or referenced below, which are hereby incorporated by reference (collectively, “**TMP Partner Terms**”), govern participation in the “X Marketing Partner” program. To the extent that Company is qualified by X, in its sole and absolute discretion, to participate in the “X Marketing Partner” program, Company agrees to abide by the terms and conditions of the TMP Partner Terms at all times during Company’s participation in the “X Marketing Partner” program. These TMP Partner Terms are subject to, and governed by, the Agreement. Any capitalized terms used in this Exhibit C-1 and not otherwise defined in the TMP Partner Terms shall have the meanings ascribed to them in the Agreement.
### 1. TMP Program.
Upon X’s notification to Company that X has qualified Company as a “X Marketing Partner,” Partner will be a member of the “X Marketing Partner” program, as described at [https://business.x.com/en/advertising/partners](https://business.x.com/en/advertising/partners) and will be given access to the TMP badge(s) and any other associated marks that X makes available in connection with the TMP (collectively, the “**Badges**”), use of which is subject to the terms and conditions of this Agreement.
### 2. License from X.
Subject to the terms and conditions of these TMP Partner Terms, and conditioned upon Company’s continuing compliance with this Agreement, X hereby grants Company, and Company accepts, a non-exclusive, royalty free, non-transferrable, non-sub-licensable, revocable license to copy and display the Badges solely with, and to promote, Company’s qualification as a “X Marketing Partner” in the TMP.
### 3. Restrictions.
Strict compliance with this Agreement is required at all times, and any use of the Badges in violation of this Agreement will automatically terminate any license related to Company’s use of the Badges.
**3.1** Company may not alter the Badges in any manner, including, but not limited to, changing the proportion, color or font of the Badges, or adding or removing any elements to or from the Badges.
**3.2** Company may not use the Badges in any manner that implies a false sense of sponsorship or endorsement by X.
**3.3** Company may not use the Badges to disparage X, its products or services, or in a manner which, in X’s sole discretion, may diminish or tarnish X’s goodwill in the Badges.
**3.4** Company may not use the Badges to refer to any other product or service other than X’s or Company’s products and/or services related to Company’s participation in the TMP.
**3.5** The Badges must appear by themselves, with reasonable spacing between each side of the marks, and other visual, graphic or textual elements.
**3.6** The Badges should not be presented or placed in any way that interferes with the readability or display of the entirety of the Badges.
**3.7** Company must link all Badges to [https://business.x.com/en/advertising/partners](https://business.x.com/en/advertising/partners) (or any other successor URL that X may elect from time to time) or otherwise display the following attribution on any materials that display the Badges: “The ‘X Marketing Partner’ Program badge, X and the X logo are trademarks of X Corp. or its affiliates.”
### 4. Program Requirements.
Use of the Badges are further subject to, and governed by, at all times, without limitation, the [X Trademark Guidelines](https://about.x.com/who-we-are/brand-toolkit) and any other requirements communicated by X to Company in connection with participation in the TMP (collectively, the “**TMP Program Requirements**”). Company agrees to the TMP Program Requirements, which are hereby incorporated by reference and are available in hardcopy upon request to X. The TMP Program Requirements do not expand or extend the license to the Badges granted herein. Company may use the Badges solely for the purpose expressly authorized by X, and Company’s use must comply with the most up-to-date version of (i) these TMP Partner Terms, and (ii) the TMP Program Requirements. To the extent that there is any conflict or inconsistency between these TMP Partner Terms and the TMP Program Requirements, these TMP Partner Terms shall control.
### 5. License to X.
Company hereby grants X a fully paid up, non-exclusive, worldwide, sub-licensable license to: (i) use and display Company’s trademarks for use in connection with the TMP, (ii) use Company’s product(s) and/or service(s) related to the TMP for X’s non-commercial, internal evaluation, testing and auditing, (iii) develop and publish case studies or other materials that allow X to highlight Company’s qualification as a “X Marketing Partner” in the TMP (including, without limitation, Company’s product(s) and/or service(s) related to the TMP), and (iv) produce marketing materials in connection with the TMP related to Company’s qualification as a “X Marketing Partner” in the TMP (including, without limitation, Company’s product(s) and/or service(s) related to the TMP).
### 6. Program Qualification.
**6.1 Program Qualification.** X reserves the right, from time to time, to review Company’s membership in the TMP, and, in X’s sole and absolute discretion, to re-qualify or de-qualify Company from any given competency and/or the TMP as a whole.
**6.2 Changes to Company’s Products or Services.** In the event that Company plans to make any material change to Company’s product(s) and/or service(s) related to the TMP, Company will provide X with at least thirty (30) calendar days to review Company’s updated products or services prior to release of such change to determine whether they continue to qualify for the TMP. Updated products or services must be re-qualified by X before any further use of the Badges. X will use commercially reasonable efforts to respond to Company’s request for qualification in new competencies. If Company merges, is acquired or otherwise undergoes a change of control, in whole or in part, by any third party, whether voluntarily or involuntarily, and/or by operation of law (including, without limitation, in connection with a merger, acquisition, or sale of assets, whether the assigning party is the surviving or disappearing entity), Company must submit all of Company’s products and/or services related to the TMP to X for re-qualification before any further use of the Badges.
### 7. Suspension and Termination.
X may immediately terminate or suspend these TMP Partner Terms, any rights granted to Company herein, and/or Company’s participation in the TMP, at its sole discretion at any time, for any reason by providing notice to Company. Company may terminate Company’s participation in the TMP by providing ninety (90) calendar days’ notice to X. Upon termination of these TMP Terms and/or termination of Company’s participation in the TMP, all licenses granted herein immediately expire, and Company must cease use of all Badges. Neither party will be liable to the other for any damages resulting solely from termination of these TMP Partner Terms as permitted under this Agreement.
### 8. Modifications.
X reserves the rights, exercisable at its sole discretion, to modify the terms and conditions of these TMP Partner Terms and/or the Badges at any time and to take appropriate action against any unauthorized or non-conforming use of the Badges. If Company has any questions about usage of the Badges, please contact [trademarks@x.com](mailto:trademarks@x.com) for assistance, or write to us at: X Corp., Attention: Legal Department, 865 FM 1209, Building 2, Bastrop, TX 78602, USA.
# X Developer Agreement
Source: https://docs.x.com/developer-terms/agreement
The X Developer Agreement sets the legal terms for using the X API and developer platform, covering licensing, restrictions, and compliance obligations.
Last Updated: April 27, 2026
By clicking “Accept & Subscribe”, continuing to pay the recurring subscription fee for Paid Services, or by otherwise accessing or using any Licensed Material, you agree to the terms of our Agreement. Subscriptions auto-renew until canceled, as described below. A verified phone number is required to subscribe. If you've subscribed through another platform, manage your subscription through that platform.
This X Developer Agreement (“**Agreement**”) is a binding legal agreement between you (referred to in this Agreement as “**you**”) and X and governs your access to and use of the Licensed Material (defined below), including any Paid Services (defined below).
By accessing or using any Licensed Material (defined below), or clicking on a button to accept the terms of this Agreement or recurring subscription payment for Paid Services, you agree to be bound by the terms of this Agreement. If you do not understand the terms herein or do not accept any part of them, then you may not use or access any Licensed Material. You may not use the Licensed Material or accept this Agreement if you are not of legal age to form a binding contract with X or if you are barred from using or receiving the Licensed Material under applicable law. To purchase and use a Paid Service you must: (i) be at least 18 years old or the age of majority as determined by the laws of the jurisdiction in which you live or (ii) have the express consent of your parent or guardian to purchase and use that Paid Service. If you are a parent or legal guardian and you allow your child (or a child that you are a guardian of) to purchase or use a Paid Service, you agree that the terms of this Agreement apply to you, you will abide by this Agreement, and you are responsible for the child’s activity on the Paid Services and for ensuring that the child also abides by the terms of this Agreement. In any case, as stated in the Who May Use the Services section of the [**X Terms of Service**](https://x.com/tos), you must be at least 13 years old to use the "Services" as defined in the X Terms of Service. If you are accepting this Agreement or using the Licensed Material on behalf of a company, organization, government, or other legal entity, you represent and warrant that you have the authority to bind such company, organization, government, or other legal entity to this Agreement, in which case the words “you” and “your” as used in this Agreement shall refer to such entity. If you do not agree to the terms of this Agreement, you may not (and you may not allow any of your personnel to) access or use the Licensed Material.
**I. Definitions.**
In this Agreement, the following definitions apply:
1. “**Developer Site**” means X’s developer site located at [**https://developer.x.com/**](https://developer.x.com/)
2. “**Direct Message**” means a private message that is sent on X Applications by one user to one or more other specific user(s) using X’s direct messaging function.
3. “**Intellectual Property Rights**” means all copyrights, moral rights, patent rights, trademarks, and any other intellectual property or similar rights (registered or unregistered) throughout the world.
4. “**Licensed Material**” means, individually or collectively, the X API and X Content.
5. "**Paid Service(s)**” means features or functionality of the Licensed Material that you access in exchange for payment of a recurring fee, as applicable to the relevant features or functionality and this Agreement. Unless otherwise set forth in this Agreement, all references to “Licensed Material” are intended to include the Paid Service(s).
6. “**Payment Portal**” means the online portal made available to you to opt-in to your use of the Licensed Material, manage subscriptions for Paid Services, manage payment methods for Paid Services, and update account information.
7. “**Services**” means your services, websites, applications, and other offerings (including research) that display X Content or otherwise use the Licensed Material.
8. “**Post**” means a short-form text and multimedia-based message distributed via the X Applications.
9. “**X**” means (a) X Corp. (865 FM 1209, Building 2, Bastrop, TX 78602, USA) if your principal place of business is outside the European Union, EFTA States, and the United Kingdom; or (b) X Internet Unlimited Company (One Cumberland Place, Fenian Street, Dublin 2, D02 AX07, Ireland) if your principal place of business is in the European Union, EFTA States, or the United Kingdom.
10. “**X API**” means X Application Programming Interfaces (each, an **“API”**), Software Development Kits (each, an **“SDK”**), and the related tools, documentation, data, technology, code, and other materials provided by X through the Developer Site.
11. “**X Applications**” means X’s real-time information service, commonly referred to as “X,” which includes those services currently provided by X at its websites and X-owned, operated, or controlled mobile applications, social plug-ins, and application programming interfaces.
12. “**X Content**” means Posts, the unique identification number generated for each Post, X end user profile information, and any other data and information made available to you through the X API or by any other means authorized by X, and any copies and derivative works thereof.
13. “**X Marks**” means the X name, trademarks, and logos that X makes available to you, including via the Developer Site, solely for use in accordance with this Agreement.
14. “**Users**” means visitors, users, or customers of your Services.
**II. X API and X Content.**
**A. License from X.** Subject to your compliance with the terms of this Agreement and the applicable Incorporated Developer Terms (as defined below), X hereby grants you a non-exclusive, royalty free, non-transferable, non-sublicensable, and revocable license to solely:
1. Use the X API to integrate X Content into your Services or conduct analysis of the X Content, as explicitly approved by X;
2. Copy a reasonable amount of and display the X Content on and through your Services to Users, as permitted by this Agreement;
3. Modify X Content only to format it for display on your Services; and
4. Use and display X Marks to attribute X Applications as the source of the X Content, as set forth in this Agreement.
**B. License to X.** You hereby grant X a non-exclusive, royalty free, non-transferable, and non-sublicensable revocable license to access, index, and cache by any means, including web spiders and/or crawlers, any webpage or applications on which you display X Content using [**embedded Posts**](https://developer.x.com/docs/twitter-for-websites/embedded-tweets/overview) or [**embedded timelines**](https://developer.x.com/docs/twitter-for-websites/timelines/overview).
**C. Incorporated Terms.** Your access to and use of the Licensed Material is also subject to, and you shall comply with, the following additional terms and policies (collectively, “**Incorporated Developer Terms**”):
1. the [**X Developer Policy**](/developer-terms/policy);
2. the [**API Restricted Use Rules**](/developer-terms/restricted-use-cases);
3. the [**X Rules**](https://help.x.com/rules-and-policies/x-rules);
4. as it relates to your display of any of the X Content, the [**Display Requirements**](https://developer.x.com/developer-terms/display-requirements.html);
5. as it relates to your use and display of the X Marks, the [**X Brand Guidelines**](https://about.x.com/who-we-are/brand-toolkit); and
6. as it relates to taking automated actions on your account, the [**Automation Rules**](https://help.x.com/rules-and-policies/x-automation).
**III. Restrictions on Use.**
**A. Reverse Engineering and other Restrictions.** You shall not and you shall not attempt to (or allow others to): (a) reverse engineer, decompile, disassemble, or translate the X API or otherwise attempt to derive source code, trade secrets, or know-how in or underlying any X API or any portion thereof; (b) interfere with, modify, disrupt, or disable features or functionality of the X API or monitoring mechanisms of the X API; (c) use or access the Licensed Material to create or attempt to create a substitute or similar service or product to the X Applications; (d) sell, rent, lease, sublicense, distribute, redistribute, syndicate, create derivative works of, assign, or otherwise transfer or provide access to, in whole or in part, the Licensed Material to any third party except as expressly permitted in this Agreement; (e) provide use of the X API on a service bureau, rental or managed services basis, or permit other individuals or entities to create links to the X API or "frame" or "mirror" the X API on any other server, or wireless or Internet-based device, or otherwise make available to a third party any token, key, password, or other login credentials to the X API; (f) use the Licensed Material for any illegal, unauthorized, or other improper purpose; (g) use the Licensed Material to derive or obtain non-public information of individual X users; (h) interfere with or disrupt the integrity or performance of the X Applications, X API, or X Content contained therein; (i) remove or alter any proprietary notices or marks on the X Content; (j) attempt to gain unauthorized access to the X Applications, X API, X Content, or related systems or networks; (k) use the X API or X Content to fine-tune or train a foundation or frontier model; or (l) use X Content, by itself or bundled with third party data, or derivative analysis therefrom, to target or serve users with advertising outside of the X Applications.
**B. Commercial Use Restrictions.** If your Services are designated as ‘non-commercial,’ you shall not make Commercial Use (as defined below) of the Licensed Material. Commercial Use restrictions may not apply to officially registered non-profits or NGOs. “**Commercial Use**” means any use of the Licensed Material or access to the X API: (a) by or for a business (i.e. an entity whose primary purpose is to earn revenue through a product or service), or (b) as part of a product or service that is monetized (e.g., website advertising, licensing fees, in-app promotions, and sponsorships).
**C. No Monitoring or Measuring.** Notwithstanding anything to the contrary, you may use the following information only for non-commercial, internal purposes (e.g., to improve the functionality of the Services): (a) aggregate X Applications user metrics, such as number of active users or accounts on X Applications; (b) the responsiveness of X Applications; and (c) results, usage statistics, data, or other information (in the aggregate or otherwise) derived from analyzing, using, or regarding the performance of the X API. All such information is Confidential Information (as defined below).
**D. Rate Limits.** You will not attempt to exceed or circumvent limitations on access, calls, and use of the X API ("**Rate Limits**") or otherwise use the X API in a manner that exceeds reasonable request volume, constitutes excessive or abusive usage, or otherwise does not comply with this Agreement. If you exceed or X reasonably believes that you have attempted to circumvent Rate Limits, controls to limit use of the X APIs, or the terms of this Agreement, then your ability to use the Licensed Material may be temporarily suspended or permanently blocked. X may monitor your use of the X API to improve the Licensed Material and X Applications and to ensure your compliance with this Agreement and the Incorporated Developer Terms.
**E. Location Data.** You shall not, and you shall not allow others to, aggregate, cache, or store location data and other geographic information contained in the X Content except in conjunction with the X Content to which it is attached. You may only use location data and geographic information to identify the location tagged by the X Content.
**F. Use of X Marks.** You shall not include any of the X Marks in your registered corporate name(s), your logos, or your service or product names. You shall not create any derivative works of the X Marks or use the X Marks in a manner that creates or reasonably implies an endorsement, sponsorship, or association with X. All use of the X Marks and all goodwill arising out of the use will inure to X's benefit. You will not remove or alter any proprietary notices or X Marks on the Licensed Material.
**G. Security.** You will maintain the security of the X API and will not make available to any third party any token, key, password, or other login credentials to the X API. You will use industry standard security measures to prevent unauthorized access or use of any of the features and functionality of the X API, including access by viruses, worms, or any other harmful code or material. You shall keep X Content confidential and secure from unauthorized access by using industry-standard organizational and technical safeguards for such data, and with no less care than you use in connection with securing similar data you store. You will immediately notify X, consult and cooperate with investigations, assist with any required notices, and provide any information reasonably requested by X if you know of or suspect any breach of security or potential vulnerability related to the Licensed Material. You will promptly remedy such breach or potential vulnerability resulting from your access to the Licensed Material.
**H. Digital Services Act**. Notwithstanding anything to the contrary in this Agreement, to the extent you are provided access to the Licensed Material pursuant to the procedures described in Article 40 of the Digital Services Act (Regulation (EU) 2022/2065) (“DSA”), your access and use of the Licensed Material is limited solely to performing research that contributes to the detection, identification, and understanding of systemic risks in the European Union and only to the extent necessary for X to comply with its obligations under the DSA. Any such use of the Licensed Material is non-commercial as described in Section III(B) of this Agreement. You may not disclose, reproduce, license, or otherwise distribute the Licensed Material (including any derivatives thereof) that you retrieve through the X API to any person or entity outside the persons specified within your approved application unless (i) the information is disclosed to the Digital Services Coordinator or other party specifically permitted by the DSA pursuant to the “vetted researcher” status and procedures described in Article 40, or (ii) disclosure is required by law.
**I. Tokens.** X may limit the number of tokens that it provides to you, including but not limited to tokens that enable access and use of functionality or features on X Applications.
**J. Access Tiers.** X provides different tiers of access (as described at [developer.x.com](http://developer.x.com)) to the Licensed Material, and you shall subscribe to the tier that best fits your use case. X may, at any time, review your use of its Licensed Materials and require a change in the access tier to which you are subscribed, including but not limited to, application for Enterprise access (as described at [developer.x.com](http://developer.x.com)).
**K. Prohibition on I-Framing:** You shall not, under any circumstances, embed, display, or otherwise incorporate any Licensed Material, X Content, X API, or elements of the X Applications within an iframe, inline frame, or any similar embedding mechanism on your Services or any other platform. This prohibition is absolute and includes, but is not limited to, attempts to frame X Content for display, integration, or redistribution purposes. Violation of this clause may result in immediate termination of your Developer Agreement and your access to the Licensed Material (e.g., X API, X Data License, Developer Console) as outlined in Section VII.I.
**L. Self-Serve Use.** The Pay-Per-Use, Basic, and Pro plans (as described at [developer.x.com](https://developer.x.com)) are designed for hobbyists, commercial prototyping, initial development, early-stage X product integrations, and supporting applications with a limited number of end-users. If you use the X API beyond this scope, then you must apply (or already subscribe to) an Enterprise plan (as described at [developer.x.com](https://developer.x.com)).
**M. Commercial Use:** If you use the X API beyond the scope of hobbyist projects, commercial prototyping, initial development, early-stage X product integrations, or for applications with a limited number of end-users, then you must apply (or already subscribe to) an Enterprise plan (as described at developer.x.com).
**IV. Updates and Removals.**
**A. Updates.** X may update, modify or discontinue any features or function of the Licensed Material, in whole or in part, from time to time (in each instance, an “**Update**”). You shall implement and use the most current version of the Licensed Material and make any changes to your Services that are required as a result of the Update, at your sole expense. Updates may adversely affect the way your Services access or communicate with the X API or display X Content. X will not be liable for damages of any sort that result from any Update.
**B. Removals.** If X Content is deleted, gains protected status, or is otherwise suspended, withheld, modified, or removed from the X Applications (including removal of location information), you will make all reasonable efforts to delete or modify that X Content (as applicable) as soon as possible, and in any case within twenty four (24) hours after a written request to do so by X or by an X user with regard to its X Content unless prohibited by law or regulation and with the express written permission of X.
**V. Ownership, Betas, and Feedback.**
**A. Ownership.** Except to the extent expressly stated otherwise in this Agreement, neither party will acquire any right, title, or interest in any Intellectual Property Rights owned or licensed by the other party. The Licensed Material is licensed, not sold, and X (or its licensors or X Application users, as applicable) retains and reserves all rights, including all Intellectual Property Rights, not expressly granted in this Agreement. You shall not do anything inconsistent with X’s ownership, including without limitation, challenging X’s ownership of the X Marks, challenging the validity of the licenses granted in this Agreement, or otherwise copying or exploiting the X Marks except as specifically authorized in this Agreement. If you acquire any rights in the X Marks or any confusingly similar marks, by operation of law or otherwise, you will, at no expense to X, immediately assign those rights to X.
**B. Betas.** X may provide you with early access to non-generally available alphas, betas, research studies, pilots, marketing services, or other programs from time to time (each, a “**Beta**”). Betas will be considered Confidential Information. Your participation in any Beta is at your own risk, may be subject to additional requirements, and may assist X in research, analyzing, and validating existing or prospective programs, products and/or tools.
**C. Feedback.** X will be free to use any feedback, comments, or suggestions you provide X related to X, the Licensed Material, Betas, or any other of X’s products or services (“**Feedback**”) in any way without any compensation or obligation to you or any third party and Feedback will be deemed Confidential Information. You hereby irrevocably assign to X all right, title, and interest to Feedback.
**VI. Confidentiality.**
You may be given access to non-public information, software, and specifications relating to the Licensed Material (“**Confidential Information**”). You may use Confidential Information only as necessary in exercising your rights under this Agreement. You shall not disclose Confidential Information to any third party without X’s prior written consent. You shall protect Confidential Information from unauthorized use, access, or disclosure in the same manner that you would use to protect your own confidential information of a similar nature and in no event with less than a reasonable degree of care.
**VII. Term; Subscription Fees; Payment; Suspension, and Termination.**
**A. Term.** The term of this Agreement will start on the date (i) you accept the terms herein or (ii) start accessing or using any of the Licensed Material, whichever is earlier, and will continue until you stop accessing and using the Licensed Material unless terminated earlier as described below.
**B. Subscription Terms.** Paid Services provided as part of the Licensed Material are made available as a recurring subscription service that provides access to certain features, benefits, or services, as described on the Developer Site and the Payment Portal. If you purchase a Paid Service, you do so by paying a subscription fee in advance on a monthly basis in accordance with the payment terms set forth below. When you subscribe to access the Paid Service(s) via the Payment Portal, you expressly agree that you are authorizing recurring payments and that payments will be made by the payment method you have selected until the applicable Paid Service is canceled by you or by X or this Agreement is otherwise terminated. Your subscription to the Paid Service will automatically renew monthly until canceled in accordance with this Agreement. Your payment information will be automatically processed by the Payment Processor (as defined below) at the start of each subscription period applicable to the Paid Service(s). If your payment information is declined, your subscription may be canceled until you provide new payment information for the applicable Paid Service(s). If you provide new payment information and your payment account is successfully charged, your new subscription period will be based on the original renewal date and not the date the successful charge took place. Prices for Paid Services are subject to change from time to time. X will provide reasonable advance notice of any material change to the price of Paid Services, which notice may be provided via the Developer Site. For subscription fees, price changes will take effect at the start of the next subscription period following the date of the price change. If you do not agree with a price change, you have the right to reject the change by canceling your subscription to the applicable Paid Service(s) prior to the price change going into effect.
**C. Payment Terms.** X may offer payment options that vary by Paid Service, device, operating system, geographic location, or other factors, which may be updated from time to time. These payment options may include web payments using a third party payment processor (“**Payment Processor**”). When you access a Paid Service, you agree: (i) to pay the price listed for the Paid Service, along with any additional amounts relating to applicable taxes, surcharges, credit card fees, bank fees, foreign transaction fees, foreign exchange fees, and currency fluctuations, on a recurring basis during the applicable subscription period; and (ii) to abide by any applicable terms of service, privacy policies, or other legal agreements or restrictions (including additional age restrictions) imposed by the Payment Processor in connection with your use of a given payment method. The subscription fee will automatically be applied at the start of the renewal period for the applicable subscription period unless you cancel the Paid Service(s) on the Developer Site. It is your responsibility to make sure your banking, credit card, debit card, and/or other payment information is up to date, complete, and accurate at all times. If you make a payment for a Paid Service through a Payment Processor, X may receive information about your transaction such as when it was made, when a subscription is set to expire or auto-renew, what platform you made the purchase on, and other information. X will not be liable for any errors made or delays by the Payment Processor, your bank, your credit card company, or any payment network. All payments to X are non-refundable except as otherwise expressly provided in this Agreement or as required by law.
**D. Taxes and fees.** All fees exclude any and all taxes and similar fees now in force, enacted, or imposed in the future on the transaction, delivery of the Licensed Material, or the delivery of the X Content including any sales, use or value added taxes, goods and services tax, consumption tax, customs duties, tariffs, or similar charges. These taxes may include but are not limited to, VAT, GST, sales tax, withholding tax, and any other applicable taxes but exclude taxes solely based on X’s net income. You are responsible for the payment of all such taxes, duties, and charges and any related penalties and interest arising from the payment of such amounts. In addition, a surcharge may be charged to recover costs associated with Digital Services Tax ("DST") or similar jurisdiction-specific taxes or regulatory fees incurred by X in certain jurisdictions. This surcharge will appear as a separate line item on your invoice, where applicable, and will be calculated as a percentage of applicable charges as determined by X in its sole discretion. X may adjust this surcharge at any time, without prior notice, in response to increased tax or fee rates or related administrative costs. Depending on your location, X may be responsible for collecting and reporting information related to transaction taxes arising from your purchase of Paid Services. You grant X permission to provide your account and personal information to relevant tax authorities to fulfill our tax collection and reporting obligations.
**E. Canceling Your Subscription for Paid Services.** Your subscription for Paid Services will automatically renew monthly unless you cancel your subscription at least 24 hours before the end of your current subscription period. There are no refunds or credits for any partial subscription periods, including in a situation where certain features, benefits, and/or services are modified or discontinued. SUBSCRIPTION PLANS ARE PREPAID, NON-REFUNDABLE (UNLESS REQUIRED BY LAW), AND AUTOMATICALLY RENEW AT THE END OF EACH SUBSCRIPTION PERIOD UNLESS THE SUBSCRIPTION IS CANCELED FOLLOWING THE CANCELLATION PROCEDURES HEREIN. You may cancel your subscription for Paid Services at any time via the Developer Site and you will no longer have access to the Paid Services (or any features or functionality thereof) at the end of your then-current subscription term. When you cancel the Paid Services, your subscription will remain active from the time you cancel until the end of your current subscription period. You will not receive a refund or credit for any remaining days in your current subscription period unless required by law. All payments for Paid Services are final and not refundable or exchangeable except as required by applicable law. X makes no guarantee as to the nature, quality, or value of a Paid Service or the availability or supply thereof. Refunds or credits are not provided for any unused or partially used Paid Service (for example, a partially used subscription period). **All transactions are final** unless you have a right to withdraw pursuant to law, such as provided below.
1. **Withdrawal Right & Refunds for Users Living in EU or UK.** When you purchase any Paid Services on subscription, you expressly agree to do so on a subscription basis and that the subscription will commence immediately on your date of purchase. If you are a consumer in an EU Member State or the UK, you agree you have fourteen (14) days after your purchase to withdraw from your contract for purchase for any reason.
2. **No Withdrawal Right for Users Living in Taiwan.** When you purchase Paid Services, you do so on a subscription basis, the subscription will commence immediately on your date of purchase, and the Paid Service is fully performed once started. If you are a consumer in Taiwan, you agree that you can cancel your subscription for any Paid Services in accordance with Section VII.E above, but that there is otherwise no right to rescind your subscription and no refund will be issued.
**F. Paid Services Are Non-Transferable between X Accounts.** Each purchase of a Paid Service applies to a single X account, meaning that your purchase will apply solely to the account you were using when you purchased the Paid Service and will not apply to other accounts that you may have access to or control over. If you have or control multiple accounts and you want access to Paid Services on each account, you must purchase the Paid Service on each account individually. You may not allow others to use your X account to access any Licensed Material that such person did not order. You may not purchase a Paid Service or use any Licensed Material if you are a person with whom U.S. persons are not permitted to have dealings pursuant to economic sanctions, including, without limitation, sanctions administered by the United States Department of the Treasury's Office of Foreign Assets Control or any other applicable sanctions authority ("**Prohibited Person**"). This includes, without limitation, persons located in, a citizen of, or ordinarily resident in the following countries and regions: Cuba, Iran, the Crimea Region of Ukraine, North Korea and Syria. You represent and warrant that you are not a Prohibited Person.
**G. Restrictions and Obligations.** You may only purchase and use a Paid Service or use the Licensed Material if you are legally allowed to use the Licensed Material in your country and you live in a country supported by X for the applicable Paid Service or Licensed Material. X may, in its discretion, restrict the ability to access the Licensed Material or purchase a Paid Service in certain countries. X reserves the right to modify the list of supported countries from time to time. X reserves the right to refuse Paid Services transactions or to cancel or discontinue the sale or use of a Paid Service or the use of any Licensed Material in its sole discretion.
**H. Suspension.** X may suspend your use of and access to the Licensed Material immediately without notice (a) if X reasonably believes that (i) your use of the Licensed Material would cause damage to, or an inordinate burden upon, the Licensed Material, (ii) you have violated this Agreement, (iii) you create risk or possible legal exposure for X, (iv) X’s provision of the Licensed Material to you is no longer commercially viable; (b) for prolonged inactivity; (c) if X is requested or directed to do so by any competent court of law, regulatory authority, or law enforcement agency; or (d) for failure to pay for the Paid Services. X will not be liable for damages of any sort that result from any such suspension.
**I. Termination.** X may terminate this Agreement for any reason at X’s sole discretion. Except where such early termination is the result of your breach of this Agreement, such early termination by X shall be effective at the end of the then-current subscription period. If you violate the terms of this Agreement, X may terminate this Agreement for cause immediately upon notice to you and you will not receive a prorated refund for any Paid Services. You may cancel your subscription for the Paid Services or your use of the Licensed Material on the Developer Site. Upon termination of this Agreement: (a) all licenses granted in this Agreement immediately expire and you must cease use of any Licensed Material; and (b) you shall permanently delete all Licensed Material in all forms and types of media, and copies thereof, in your possession. Upon the request of X for any reason, you will promptly (and in any event within ten (10) business days of such request) provide evidence (e.g., screenshots of deletion confirmation) of compliance with the provisions of the aforementioned subpart (b) of this Section. The parties to this Agreement will not be liable to each other for any damages resulting solely from termination of this Agreement as permitted under this Agreement.
**VIII. Compliance Audit.**
X or a mutually agreed upon third party agent subject to obligations of confidentiality will be entitled to inspect and audit any records related to the performance of this Agreement in your control or possession upon reasonable notice to you, and at a reasonable time during normal business hours, for the purpose of verifying compliance with this Agreement and the fees payable to X for the two (2) year period preceding the audit. X may exercise its audit right no more than once every twelve (12) months unless it has reasonable cause for noncompliance, and such audit shall not unreasonably interfere with your business activities. You will provide your full cooperation and assistance with such audit and provide access to all Licensed Material in your possession, applicable agreements, and records. Without limiting the generality of the foregoing, as part of the audit, X may request, and you agree to provide, a written report, signed by an authorized representative, listing your then-current deployment of the Licensed Material. You will pay X within thirty (30) business days after the completion of the audit the amount of any underpayment revealed by any such audit. In addition, if any such audit reveals an underpayment by you of five percent (5%) or more, then you will also reimburse X for the reasonable costs and expenses of such audit. The requirements of this Section will survive for one (1) year following the termination of this Agreement.
**IX. Disclaimer.**
TO THE MAXIMUM EXTENT PERMISSIBLE BY APPLICABLE LAW, THE LICENSED MATERIAL IS PROVIDED TO YOU “AS IS”, “WHERE IS”, WITH ALL FAULTS, AND X DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTIES OR CONDITIONS ARISING OUT OF THIS AGREEMENT, COURSE OF DEALING OR USAGE OF TRADE. X DOES NOT WARRANT THAT THE LICENSED MATERIAL OR ANY OTHER X PRODUCT OR SERVICE PROVIDED HEREUNDER WILL MEET ANY OF YOUR REQUIREMENTS OR THAT USE OF SUCH LICENSED MATERIAL OR OTHER PRODUCTS OR SERVICES WILL BE ERROR-FREE, UNINTERRUPTED, VIRUS-FREE, OR SECURE. YOU ARE RESPONSIBLE FOR YOUR USE OF THE LICENSED MATERIAL AND ANY CONTENT YOU PROVIDE. THIS DISCLAIMER OF WARRANTY MAY NOT BE VALID IN SOME JURISDICTIONS AND YOU MAY HAVE WARRANTY RIGHTS UNDER LAW WHICH MAY NOT BE WAIVED OR DISCLAIMED.
**FURTHER YOU UNDERSTAND AND AGREE THAT THE PAID SERVICES ARE PROVIDED TO YOU ON AN “AS IS” AND “AS AVAILABLE” BASIS.**
**X. Indemnification.**
You shall defend X against any and all proceedings, demands, claims, and suits (including without limitation product liability claims), and indemnify X from any and all liabilities, damages, and costs (including without limitation reasonable attorneys' fees) to the extent arising out of (a) your use of the Licensed Material in any manner that is inconsistent with this Agreement or (b) the performance, promotion, sale, or distribution of your Services. If X seeks indemnification or defense from you under this Section, X will promptly notify you in writing of the claim(s) brought against X for which it seeks indemnification or defense. X may assume full control of the defense of claims with legal counsel of its choice. You shall not enter into any third-party agreement that would affect the rights of X, constitute an admission of fault by X, or bind X in any manner without the prior written consent of X. If X assumes control of the defense of such claim, X shall not settle any such claim requiring payment from you without your prior written approval.
**XI. Limitation of Liability.**
IN NO EVENT WILL X BE LIABLE TO YOU OR ANY USERS FOR ANY INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL DAMAGES OR ANY LOSS OF OR DAMAGE TO USE, DATA, BUSINESS, GOODWILL OR PROFITS ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT. IN ANY CASE, X'S AGGREGATE LIABILITY FOR ANY AND ALL CLAIMS UNDER THIS AGREEMENT WILL NOT EXCEED FIFTY DOLLARS (\$50.00). THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SHALL APPLY REGARDLESS OF WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT, STRICT LIABILITY OR OTHERWISE, AND WHETHER OR NOT X HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. IF APPLICABLE LAW PROHIBITS ANY LIMITATION ON LIABILITY HEREIN, THE PARTIES AGREE THAT THE LIMITATION WILL BE DEEMED TO HAVE BEEN MODIFIED TO CONFORM TO APPLICABLE LAW. THE PARTIES AGREE THAT THE LIMITATIONS ON LIABILITIES SET FORTH HEREIN ARE AGREED ALLOCATIONS OF RISK AND SUCH LIMITATIONS WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
**XII. Agreement Updates.**
X may update or amend this Agreement or any of the Incorporated Developer Terms from time to time. You will check the Developer Site regularly for updates. X will alert you of material revisions to these terms by posting the updated terms on these sites, via a service notification, or by other suitable means (e.g., via email to an email address associated with your account). The changes will not be retroactive and the most current version of this Agreement, available at the Developer Site, will govern your access to and use of the Licensed Material and any corresponding transactions. Your continued access or use of the Licensed Material will constitute binding acceptance of such updates and modifications.
**XIII. Dispute Resolution and Class Action Waiver.**
**A. THIS SECTION APPLIES TO YOU ONLY IF YOU LIVE OUTSIDE THE EUROPEAN UNION, EFTA STATES, OR THE UNITED KINGDOM, INCLUDING IF YOU LIVE IN THE UNITED STATES. PLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT.**
1. **Choice of Law and Forum Selection.** The laws of the State of Texas, excluding its choice of law provisions, will govern this Agreement and any dispute that arises between you and X, notwithstanding any other agreement between the parties to the contrary. All disputes related to this Agreement, including any disputes, claims, or controversies arising out of or relating to this Agreement, the marketing of the Licensed Material, and/or your participation in the Licensed Material will be brought exclusively in the U.S. District Court for the Northern District of Texas or state courts located in Tarrant County, Texas, United States, and you consent to personal jurisdiction in those forums and waive any objection as to inconvenient forum. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute it has against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
If you are a federal, state, or local government entity in the United States using the Licensed Material in your official capacity and legally unable to accept the controlling law, jurisdiction, or venue clauses above, then those clauses do not apply to you. For such U.S. federal government entities, this Agreement and any action related thereto will be governed by the laws of the United States of America (without reference to conflict of laws) and, in the absence of federal law and to the extent permitted under federal law, the laws of the State of Texas (excluding choice of law).
2. **YOU HAVE ONE YEAR TO BRING A CLAIM AGAINST X.** You must bring any claim against X arising out of or related to this Agreement within one (1) year after the date of the occurrence of the event or facts giving rise to the dispute unless applicable law provides that the normal statute of limitations for that claim may not be shortened by agreement. If you do not bring a claim within this period, you forever waive the right to pursue any claim or cause of action, of any kind or character, based on such events or facts, and such claims or causes of action are permanently banned and X will have no liability with respect to such claim.
3. **Class Action Waiver.** To the extent permitted by law, you also waive the right to participate as a plaintiff or class member in any purported class action, collective action, or representative action proceeding.
4. **Changes to this Section.** This Dispute Resolution Section survives the end of the relationship between you and X, including cancellation of or unsubscribing from any services or communications provided by X.
5. **Injunctive Relief.** Notwithstanding the foregoing, you agree that money damages would be an inadequate remedy for X in the event of a breach or threatened breach of this Agreement protecting X's intellectual property or Confidential Information, and that in the event of such a breach or threat, X, in addition to any other remedies to which it is entitled, is entitled to preliminary or injunctive relief (including an order prohibiting you from taking actions in breach of such provisions), without the need for posting bond, and specific performance as may be appropriate. The parties agree that neither the United Nations Convention on Contracts for the International Sale of Goods nor the Uniform Computer Information Transaction Act shall apply to this Agreement, regardless of the states in which the parties do business or are incorporated. No waiver by X of any covenant or right under this Agreement will be effective unless memorialized in a writing authorized by X.
**B. THIS SECTION APPLIES TO YOU ONLY IF YOU LIVE IN THE EUROPEAN UNION, EFTA STATES, OR THE UNITED KINGDOM. PLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT.**
1. **Choice of Law and Forum Selection.** To the extent permitted by law, all disputes related to this Agreement, including any disputes, claims, or controversies arising out of or relating to this Agreement, the marketing of the Licensed Material, and/or your participation in the Licensed Material, will be brought exclusively before a competent court in Ireland without regard to conflict of law provisions and will be governed by Irish law, notwithstanding any agreement between the parties to the contrary. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute it has against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
2. **YOU HAVE ONE YEAR TO BRING A CLAIM AGAINST X.** You must bring any claim against X arising out of or related to this Agreement within one (1) year after the date of the occurrence of the event or facts giving rise to the dispute unless applicable law provides that the normal statute of limitations for that claim may not be shortened by agreement. If you do not bring a claim within this period, you forever waive the right to pursue any claim or cause of action, of any kind or character, based on such events or facts, and such claims or causes of action are permanently banned, and X will have no liability with respect to such claim.
3. **Class Action Waiver.** To the extent permitted by law, you also waive the right to participate as a plaintiff or class member in any purported class action, collective action, or representative action proceeding.
4. **Changes to this Section.** This Dispute Resolution section survives the end of the relationship between you and X, including cancellation of or unsubscribing from any services or communications provided by X.
5. **Injunctive Relief.** Notwithstanding the foregoing, you agree that money damages would be an inadequate remedy for X in the event of a breach or threatened breach of this Agreement protecting X's intellectual property or Confidential Information, and that in the event of such a breach or threat, X, in addition to any other remedies to which it is entitled (including money damages), is entitled to such preliminary or injunctive relief (including an order prohibiting you from taking actions in breach of such provisions), without the need for posting bond, and specific performance as may be appropriate. The parties agree that neither the United Nations Convention on Contracts for the International Sale of Goods nor the Uniform Computer Information Transaction Act shall apply to this Agreement regardless of the states in which the parties do business or are incorporated. No waiver by X of any covenant or right under this Agreement will be effective unless memorialized in a writing authorized by X.
**XIV. Miscellaneous.**
**A. Assignment.** You shall not assign any of the rights or obligations granted hereunder, in whole or in part, whether voluntarily or by operation of law, contract, merger (whether you are the surviving or disappearing entity), stock or asset sale, consolidation, dissolution, through government action, or otherwise, except with the prior written consent of X. X is authorized to sign modifications and consents for X Internet Unlimited Company, an Irish company responsible for the information of X users who live outside the United States. Any attempted assignment in violation of this Section will be null and void and X may terminate this Agreement.
**B. User Protection.** Unless explicitly approved by X in writing, you shall not use, or knowingly display, distribute, or otherwise make X Content, or information derived from X Content, available for purpose of: (a) conducting or providing surveillance or gathering intelligence, including but not limited to investigating or tracking X users or X Content; (b) conducting or providing analysis or research for any unlawful or discriminatory purpose or in a manner that would be inconsistent with X users' reasonable expectations of privacy; (c) monitoring sensitive events (including but not limited to protests, rallies, or community organizing meetings); or (d) targeting, segmenting, or profiling individuals based on sensitive personal information, including their health (e.g., pregnancy), negative financial status or condition, political affiliation or beliefs, racial or ethnic origin, religious or philosophical affiliation or beliefs, sex life or sexual orientation, trade union membership, X Content relating to any alleged or actual commission of a crime, or any other sensitive categories of personal information prohibited by law.
**C. Government Use.** If you display, distribute, or otherwise make available any X Content to Users that are, or that act on behalf of, any government-related entity (each a “**Government End User**”); (a) you must apply for (or already subscribe to) an Enterprise plan (as described at [developer.x.com](https://developer.x.com)); (b) you shall identify all such Government End Users when submitting your use case for review to X; and (c) you shall thereafter notify X in writing of any new Government End Users or any new use cases with existing Government End Users before the Services display, distribute, or otherwise make available any X Content to a Government End User or for any new use case. X may prohibit you from making X Content available to any Government End User. You shall not use, or knowingly display, distribute, or otherwise make X Content, or information derived from X Content, available to any Government End User whose primary function or mission includes conducting surveillance or gathering intelligence. If law enforcement requests information about X or its users for purposes of an ongoing investigation, you may refer them to X’s Guidelines for Law Enforcement located at [**https://help.x.com/rules-and-policies/x-law-enforcement-support**](https://help.x.com/rules-and-policies/x-law-enforcement-support). The X API and X Content are "commercial items" as that term is defined at 48 C.F.R. 2.101, consisting of "commercial computer software" and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212. Any use, modification, derivative, reproduction, release, performance, display, disclosure, or distribution of the X API or X Content by any government entity is prohibited except as expressly permitted by the terms of this Agreement. Additionally, any use by U.S. government entities must be in accordance with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4. If you use the X API or X Content in your official capacity as an employee or representative of a U.S. state or local government entity and you are legally unable to accept the indemnity, jurisdiction, venue, or other clauses herein, then those clauses do not apply to such entity to the extent required by law. Contractor/manufacturer is X Corp., 865 FM 1209, Building 2, Bastrop, TX 78602, USA.
**D. Compliance with Laws; Export and Import.** Each party will comply with all applicable foreign, federal, state, and local laws, rules and regulations, including without limitation all laws relating to bribery and/or corruption. The Licensed Material is subject to U.S. export laws and may be subject to import and use laws of the country where it is delivered or used. You shall abide by these laws. Under these laws, the Licensed Material may not be sold, leased, downloaded, moved, exported, re-exported, or transferred across borders without a license, or approval from the relevant government authority, to any country or to any foreign national restricted by these laws, including countries embargoed by the U.S. Government (currently Cuba, Iran, North Korea, Northern Sudan and Syria), to any restricted or denied end-user, including but not limited to any person or entity prohibited by the U.S. Office of Foreign Assets Control, or for any restricted end-use. You shall maintain all rights and licenses that are required for your Services.
**E. Data Protection Addendum.** Each party shall comply with the X Controller-to-Controller Data Protection Addendum located at [**https://gdpr.x.com/en/controller-to-controller-transfers.html**](https://gdpr.x.com/en/controller-to-controller-transfers.html), which may be updated by X from time to time.
**F. Survival.** Sections III (Restrictions on Use), V (Ownership and Feedback), VI (Confidentiality), VII(I) (Termination), VIII (Compliance Audit), IX (Warranty Disclaimer), X (Indemnification), XI (Limitation of Liability), XIII (Dispute Resolution and Class Action Waiver); and XIV (Miscellaneous) of this Agreement will survive the termination of this Agreement.
**G. Entire Agreement.** This Agreement constitutes the entire understanding of the parties regarding the subject matter of this Agreement and supersedes all other agreements between the parties related to the subject matter, whether written or oral. If any provision of this Agreement is held by a court of law to be unenforceable, the remaining provisions of the Agreement will remain in effect. No waiver under this Agreement will be effective unless it is in writing and signed by the party granting the waiver. A waiver granted on one occasion will not operate as a waiver on other occasions. This Agreement does not create or imply any partnership, agency or joint venture.
# Display requirements: Posts
Source: https://docs.x.com/developer-terms/display-requirements
Display requirements for showing X Posts in your app, including branding, attribution, anatomy of a Post, interactivity, and metadata to render.
## General principles and Post anatomy
Posts are one of our most visible brand elements, so it’s important that they are presented correctly. You should comply with the display requirements below when you display posts, timelines, and other X content.
If you follow these guidelines merely to display a post, you may not need to contact X for any additional display or trademark permissions. However, you may still want to submit your proposed use and context for X review. (Note that, in some cases, permission from the original content creator may still be necessary, as X does not provide permission to use third party/user content.)
The following general principles apply to all display mediums. Please note, medium-specific requirements do apply, and are outlined in the sections below.
The image below shows all the main components of a post.
### Do
* Display real, unmodified posts from real accounts.
* Follow X’s [Terms of Service](https://x.com/tos?lang=en), the [X Brand Assets and Guidelines](https://about.x.com/en_us/company/brand-resources.html), and (if applicable) the [Developer Agreement and Developer Policy](/developer-terms/agreement).
* Display the X logo.
### Don't
* Use X content to promote any product or service (e.g., by displaying X content in advertising or otherwise displaying X content to imply endorsement of any product or service) without explicit permission from the user.
* Use X content to imply sponsorship by, endorsement from, or a false association with X.
* Include buttons or icons from other social platforms.
* Modify post text.
* Use mock ups of posts that don’t exist on the platform.
***
## Online display / Mobile, web, and beyond
We’re committed to bringing the ease and power of X to everyone. To ensure every post is displayed optimally, we strongly encourage using [embedded posts and/or embedded timelines](https://publish.x.com). When you use these products to publish X content, posts and timelines are automatically rendered correctly, including advanced features like photos, video playback, edited posts, and fetching of up-to-date X data without OAuth. If it is not possible for you to use our embedding features, you must follow the requirements below when displaying posts and timelines online.
### Post author
* The post author’s profile picture, @username, and display name must always be displayed and link to the user’s X profile.
* The post author’s @username must always be displayed with the “@” symbol.
* The post author’s avatar must be positioned to the left of the author’s name and @username—except for posts in languages that read right to left, in which case the author’s avatar must be positioned to the right of the author’s display name and @username.
### Post text
* The post text must be displayed on a line below the author’s display name and @username, and may not be altered or modified.
* On touch devices, the white space around the post text and post author must link to the post’s permalink.
* Post entities within the post text must be properly linked to their appropriate home on X. For example:
* User @mentions must link to the mentioned user’s profile.
* Hashtags must link to a X search with the hashtag as the query.
* Links in post text must be displayed using the display\_url field in the URL entities API response, and link to the original t.co url field.
### Timestamp
* The post timestamp must be displayed and link to the post’s permalink.
### Post Actions
* All post Action icons (including reply, repost, and like) must always be visible for the user to interact with the post. These actions must be implemented using [Web Intents](/x-for-websites/web-intents/overview) or with the authenticated X API. In lieu of post Actions, “View on X” may be shown next to the timestamp, linking the user to the post permalink.
* No other social or third party actions may be attached to a post. (e.g., subscribe, comment, like).
* If the post being displayed is a repost, the display name of the user who reposted it and the repost icon must be displayed above or under the post text. e.g., “reposted by Jane Doe”. The display name must link to the profile of the user who reposted it.
* Follow [guidelines for displaying replies](/developer-terms/reply-requirements).
### Post edits
* X allows people to edit their posts up to 5 times during the first 30 minutes after posting the original post. When using [embedded posts](/x-for-websites/embedded-posts/overview), the display will appear slightly different depending on whether the post was edited before or after it was embedded.
* When a post is embedded first, and then edited, you must display those edits as they occur on the X platform:
* If you are displaying a previous version of an edited post, you must note below the timestamp that there is a new version of the post, and to the right of that note, provide a link which expands the post’s edit history.
* You must then display the full edit history of the post.
When a post has been edited first, and then embedded, you must note in the timestamp that the post was edited, and the timestamp must also link to the live post on X.
### Branding
* The official X logo must always be reasonably visible and displayed on the upper-right corner of an individual post or directly attached to the timeline (e.g., top of the timeline). The logo should be the same height “x” as in the image. See X’s [brand resources page](https://about.x.com/en_us/company/brand-resources.html) for brand guidelines and assets.
### Mobile deep linking
* Deep links from native mobile apps must direct to the native X application. If the native X application is not installed on the device, the link must direct to X.com via a web browser.
### Timelines
* All timelines must allow users to view the details of an individual post (e.g., by linking the post timestamp or by linking the entire post area).
If you plan any advertising near posts, please ensure it complies with the [Developer Policy](/developer-terms/policy).
If for any reason you cannot comply with one or more of these rules, please contact us directly via our [Policy Support form](https://help.x.com/forms/platform) before displaying X content. For questions or further information about use of the X name and trademarks, please contact [trademarks@x.com](mailto:trademarks@x.com).
***
## Broadcast display / 15 minutes of fame
We welcome and encourage the use of X in broadcast media. Our requirements ensure that X users receive proper attribution for their content, and help provide the best experience for your audience.
### Do
* Show the user’s full name, @username, post text, and profile picture.
* Include the X logo in close proximity to the posts for as long as they appear in your broadcast. Make sure that the X logo is sized similarly to the size in the above image, relative to the content.
* Use the full text of the post.
* When displaying images, the post text must also be included along with the user’s display name, @username, and the X logo.
### Don't
* Display X content in advertising or to imply endorsement of any product or service without explicit permission from the user.
* Delete, obscure, or alter the post content or identification of the user (with the exception of removing hyperlinks).
* Exclude the timestamp.
* Do not use X marks, in whole or in part, in the title of your production without first reviewing their use with X by contacting us at [trademarks@X.com](mailto:trademarks@X.com).
***
## Verbal or voice over
### Posts
When reading posts on air with no graphic display of the post, you do not need to display the X logo but you do need to verbally attribute it to X. Read the post as originally written, without edits.
### Usernames
Make sure to include a reference to X when mentioning X usernames. For example, “Follow us on X, at-username” or “You can follow Lady Gaga on X, at-ladygaga”
### Hashtags
Make sure to include a reference to X when mentioning X hashtags. For example, “Use the hashtag ‘election2016’ on X” or “The hashtag for this broadcast on X is bbcaq”.
# Geo guidelines
Source: https://docs.x.com/developer-terms/geo-guidelines
Guidelines for handling geotagged Posts and location data from the X API, including geo features, place objects, and user privacy considerations.
Last Update: October 22, 2014.
## Introduction
Posting With Location is the geotagging feature in the X API. This feature helps to provide a more meaningful experience for users by making posts more contextual. For instance, “Fireworks!” is much more relevant when associated with a location: “Fireworks!” from the SoMa Neighborhood in San Francisco, California. We look forward to working with the developer ecosystem to create great experiences around this functionality!
## User privacy and user control of their location information
To ensure a good and safe experience, developers should be sensitive to user privacy when dealing with their location as well as provide baseline consistency in the “Posting with Location” experience. Here are some key things to keep in mind that help protect user privacy and ensure users understand the impact of their actions:
## General guidelines
* Users must opt-in to use the Posting With Location feature (turn location “on”).
* Users must give explicit permission for their exact location to be displayed with their posts. If the location feature on your client is “sticky” — i.e. once location is turned on it always accompanies a post — you may wish to display only place names (place\_ids) and allow users to further opt in to exact latitude and longitude on a per-post basis or as a specific alternative setting.
* When you access your users’ location data to post a post, that information should not be stored by you apart from the post without the user’s explicit permission.
* It must be clear to users what level of location information, if any, will be displayed in association with their post. One way you can do this is by showing a map of how this information will be displayed before the post is published. If exact latitude and longitude is part of the information (or the only information) published by the user on the client, it should be clear to the user that their exact coordinates will be published.
* Users should be able to turn on and off their location each time they compose a post.
* You must follow the terms of X’s [Developer Policy](/developer-terms/policy.html) – including the requirement that you may not aggregate, cache, or store location data and other geographic information from the X API, except as part of a post, and may not use such location data or geographic information on a standalone basis.
## Specific examples
Example 1: *No addition of explicit latitude and longitude (this is the current X Web Client UI)*
1. Show a link to “Add your location” when a user composes a post;
2. In the background, use the X [reverse\_geocode](https://developer.x.com/en/docs/geo/places-near-location/api-reference/get-geo-reverse_geocode.html) API call and pass the latitude, longitude, accuracy of your fix, and the user’s preferred granularity (which, by default, is “neighborhood”);
3. Display the name for the default place (X will attempt to order these in a way that makes sense - the ordering is such that a X client can just display the list without a need for modification);
4. Allow the user to select a different location from the list (e.g. change from “SoMa, San Francisco” to “South Beach, San Francisco”).
5. Important: Be transparent with the user if you will be displaying exact location information. Make sure the user knows if exact location information will be displayed.
6. Allow the user the choice to turn on or off location with every post compose.
Example 2: *Existing geotagging implementations*
A number of X client apps have the original geotagging feature (which only broadcast lat/lons without providing place\_IDs) implemented. The default behavior of the API mimics this behavior – i.e. as a developer you do not need to make any changes to your existing app in order to maintain the behavior that exists today. Indeed, if you simply pass a lat/lon coordinate in to X, X will automatically reverse geocode that latitude and longitude and display the place\_ID in addition to lat/lon for areas where we have data available.
Ensure that it is transparent to your users that their exact coordinates are being used and displayed on X. A best practice for existing apps would be to allow users to turn on or off their location on a per-post basis. You can also enable your users to share only place\_IDs instead of exact coordinates as a default, “sticky” setting.
## X storage of user location data
X will store data passed by the client as follows:
* X will save all the data that a user chooses to publicly display to his/her followers. This is similar to how X stores the time stamp that says when the post was made, meaning if a user posts with their exact coordinates, X will store this exact location along with the post for as long as the post exists. Users can clear location data from their posts by clicking the “clear my location history” button on the Settings page as described [here](https://support.twitter.com/articles/122236-how-to-tweet-with-your-location).
## Summary
The addition of location to a post adds an enormous amount of context and value from a user perspective. However, implementations of location in your client should be careful to take privacy and user transparency as a key consideration in designing a location-focused product.
If you have any questions or comments about privacy, location, and other geo features, please [contact us.](https://support.twitter.com/forms/platform)
# X Developer Policy
Source: https://docs.x.com/developer-terms/policy
The X Developer Policy outlines acceptable use of the X API, including rules around content, automation, privacy, security, and prohibited behaviors.
## X + Developers
X loves developers. We’re delighted and amazed by the tools and services this community creates by harnessing the power of X data. As part of our commitment to this community, we aim to provide data access that is open and fair for developers, safe for people on X, and beneficial for the X platform as a whole. To further these goals we’ve crafted the Developer Policy as a guide to help people understand our rules and expectations about appropriate API and X Content usage.
This Developer Policy (“**Policy**”) provides rules and guidelines for developers who interact with X’s ecosystem of applications, services, website, web pages and content. It is part of your contract with X governing access to and use of the X API and X Content (either as part of the Developer Agreement or other written agreement with X). Policy violations are considered violations of your agreement. This Policy may be changed from time to time without notice. Capitalized terms used in this Policy, which are not defined in this Policy, will have the respective meanings ascribed to them in the [Developer Agreement](/developer-terms/agreement) or the Master License Agreement.
## Using this policy
We’ve structured this policy to make it as easy to follow as possible. Please keep information from the following policy sections top of mind as you use the X API and X Content:
1. **Follow the Platform Usage Guidelines** - Getting approved to access the X API and X Content is just the first step. Our Platform Usage Guidelines should be your first stop anytime you have questions about how to ensure policy compliance for your planned use of the X platform.
2. **Set Yourself Up for Success** - You are responsible for complying with all X policies. It’s important that you review and understand this Policy, as well as the policies we link to in this document, before you access the X API and X Content. The time spent reviewing our policies may save you hours of rework down the road.
3. **Privacy and Control are Essential** - Protecting and defending the privacy of people on X is built into the core DNA of our company. As such, we prohibit the use of X data in any way that would be inconsistent with people’s reasonable expectations of privacy. By building on the X API or accessing X Content, you have a special role to play in safeguarding this commitment, most importantly by respecting people’s privacy and providing them with transparency and control over how their data is used.
We’ve provided a lot more detail on what each of these three key sections mean below. Please review them carefully to ensure that your usage of the X API and X Content is consistent with our policies.
If we believe you are in violation of this Policy (or any other X policy), we may suspend or permanently revoke your access to the X API and X Content.
Finally, please note that X may monitor your use of the X API to improve the X Applications, to examine any commercial use, and to ensure your compliance with your approved use case and this Policy.
Thanks for reading, and thank you for building with us! We look forward to seeing what you create!
## Platform usage guidelines
Have you taken care to review X’s policies and set up your API access the right way? Does your service follow X’s privacy and control guidelines? If you can answer yes to these two questions, then you are ready to start using the X API and X Content. X’s Platform Usage Guidelines provide the assistance needed to ensure that your use of X Content is compliant from day 1 throughout the lifecycle of your service. We suggest reviewing these rules on a regular basis to make sure that your integration is operating in a way that is safe and beneficial to people on X and the X platform as a whole.
## Spam, bots, and automation
**The use of the X API and developer products to create spam, or engage in any form of platform manipulation, is prohibited.** You should review the X Rules on [platform manipulation and spam](https://help.x.com/rules-and-policies/platform-manipulation), and ensure that your service does not, and does not enable people to, violate our policies.
[**Services that perform write actions, including posting Posts, following accounts, or sending Direct Messages, must follow the Automation Rules.**](https://help.x.com/rules-and-policies/x-automation) In particular, you should:
* Always get explicit consent before sending people [automated replies or Direct Messages](https://twittercommunity.com/t/policy-clarification-automated-replies-and-mentions/94444)
* Immediately respect requests to opt-out of being contacted by you
* Never perform bulk, aggressive, or spammy actions, including [bulk following](https://twittercommunity.com/t/policy-clarification-aggressive-following-and-inorganic-following-behavior/92769)
* Never post identical or substantially similar content across [multiple accounts](https://blog.twitter.com/developer/en_us/topics/tips/2018/automation-and-the-use-of-multiple-accounts.html)
**If you’re operating an API-based bot account you must clearly indicate what the account is and who is responsible for it.** You should never mislead or confuse people about whether your account is or is not a bot. A good way to do this is by including a statement that the account is a bot in the profile bio.
## X performance benchmarking
**You may not use the X API to measure the availability, performance, functionality, or usage of X for benchmarking, competitive, or commercial purposes.** For example, you should never use the X API to:
* Calculate aggregate X metrics, such as the total number of Monthly Actives (MAs) or Daily Actives (DAs)
* Calculate aggregate X Post metrics, such as the total number of Posts posted per day, or the number of account engagements
* Measure or analyze the responsiveness of X
* Measure or analyze spam or security on X, except as permitted below
**We support research that helps improve conversational health on X.** You may not publicly disclose any research or findings concerning, or develop, create, or offer services using, the X API or X Content that measure, analyze, or attempt to identify behaviors or content which violate X policies without express written permission from X.
**DSA Researchers:** If you need to contact X relating to access under Art. 40 of the Digital Services Act, please contact [**EU-Questions@X.com**](mailto:EU-Questions@X.com). If you wish to apply for researcher access, please submit an [application](https://forms.gle/btDwenPF7M3hgSvw7).
## Public display of Posts
**You must maintain the integrity of all X Content that you display publicly or to people who use your service.** If you don’t use [X for Websites](https://developer.x.com/docs/twitter-for-websites/overview) to display content, then you must use the X API to retrieve the most current version available for display. If displayed content ceases to be available through the X API, then you must remove it from your service as soon as reasonably possible, or within 24 hours after the receipt of a removal request from X, or the applicable X account owner, or as otherwise required by applicable law.
**There are specific rules you must follow if you display X Content offline.** Follow the [guidelines](https://developer.x.com/developer-terms/display-requirements) for using Posts in broadcast if you display Posts offline.
**If you embed or display Posts, you must contact us about your X API access if your site exceeds 10 million daily impressions.** X reserves the right to require additional terms as a condition to your use of the X API. Additional restrictions on X for Websites developer use include:
* **Embedded Posts and/or embedded timelines**
* You must provide people with legally sufficient notice that fully discloses X’s collection and use of data about browsing activities on your website, including for interest-based advertising and personalization. You must also obtain legally sufficient consent from people for such collection and use
* You must provide legally sufficient instructions on how people can opt out of X’s interest-based advertising and personalization as described [here](https://help.x.com/x-for-websites-ads-info-and-privacy)
* **X for Websites widgets**
* You must ensure that people are provided with clear and comprehensive information about, and consent to, the storing and accessing of cookies or other information on their devices as described in X’s [cookie use](https://help.x.com/rules-and-policies/x-cookies), where providing such information and obtaining such consent is required by law
* **Services targeted to children under 13**
* Services targeted to children under 13 must opt out of tailoring X in any embedded Post and/or embedded timelines by setting the opt-out parameter to be ‘true’ as described [here](https://developer.x.com/docs/twitter-for-websites/privacy)
## Content redistribution
**The best place to get X Content is directly from X. Consequently, we restrict the redistribution of X Content to third parties.** If you provide X Content to third parties, including downloadable datasets or via an API, you may only distribute Post IDs, Direct Message IDs, and/or User IDs (except as described below).
In total, you may not distribute more than 1,500,000 Post IDs to any entity (inclusive of multiple individuals associated with a single entity) within any 30 day period unless you have received written permission from X. In addition, developers may provide up to 500 public Posts Objects and/or User Objects to each person who uses your service on a daily basis if this is done via non-automated means (e.g., download of spreadsheets or PDFs).
Academic researchers are permitted to distribute Post IDs and/or User IDs solely for the purposes of non-commercial research on behalf of an academic institution, and that has been approved by X in writing, or peer review or validation of such research. Only as many Post IDs or User IDs that is necessary for such research, and has been approved by X may be used.
Any X Content provided to third parties remains subject to this Policy, and those third parties must agree to the X [Terms of Service](https://x.com/tos), [Privacy Policy](https://x.com/privacy), [Developer Agreement](/developer-terms/agreement), and [Developer Policy](/developer-terms/policy) before receiving such downloads. You may not enable any entity to circumvent any other limitations or restrictions on the distribution of X Content as contained in this [Policy](/developer-terms/policy), the [Developer Agreement](/developer-terms/agreement), or any other agreement with X.
**Note:** This Section does not apply to researchers with X API access via Art. 40 of the EU Digital Services Act (2022) (“**DSA**”), who are instead subject to the procedures and restrictions set forth in the DSA and the Developer Agreement.
## Pay to engage
**Your service shouldn’t compensate people to take actions on X, as that results in inauthentic engagement that degrades the health of the platform.** As you use the X API you may not sell or receive monetary or virtual compensation for any X actions. This includes, but is not limited to, Posts, follows, unfollows, reposts, likes, comments, and replies.
## Service authenticity
**You must clearly identify your service so that people can understand its source and purpose.** Don’t use names, logos, or URLs that mask your service’s identity and features, or that falsely imply an affiliation with X or third parties. Note that creating applications for the purpose of selling names, or to prevent others from using names, is prohibited.
**You may not use any URL (including shortened URLs) for your service that directs people to:**
* A site that is unrelated to your service
* A spam or malware site
* A site that encourages people to violate X policy
## X name, logo, and likeness
**You may only use and display the X name and logo to identify X as the source of X Content.** You should never use the X name and logo, the X Official Partner Program badge, or any other similar marks or names in a manner that creates a false sense of endorsement, sponsorship, or association with X. The X [Brand Resources](https://about.x.com/who-we-are/brand-toolkit) contain detailed information to help you use the X brand in the right way.
**You may only use the X Verified Account badge and any other enhanced account categorization as it is reported to you by X through the API.** This helps people know that the content your service displays is equivalent to that shown on X.
## Advertising on X
**There are restrictions regarding how and where you are allowed to advertise around X Content.** To start, your advertisements can’t resemble or reasonably be confused by people as a Post. Other rules on advertising include:
* **There must be a clear separation between X Content and your advertisements.** You may not place any advertisements within the X timeline other than X Ads.
* **X reserves the right to serve advertising via the X API.** If you decide to serve X Ads once we start delivering them via the API, we will share a portion of advertising revenue with you in accordance with the relevant terms and conditions.
* **You may not use X Content, or information obtained from the X API to target people with advertising outside of the X platform.**
The following additional rules apply for any use of the X services or features listed below:
## X Login
**You must present people with easy to find options to log into and out of X, for example via the OAuth protocol.** The *Sign in with X* option must be displayed at least as prominently as any other sign-up or sign-in feature on your service. You must also provide people without a X account the opportunity to create one via X.
***Once someone on your service authenticates via Sign in with X you must clearly display their X identity.*** X identity includes the person’s current X @handle, avatar, and X logo. Any display of someone’s X followers on your service must clearly show that the relationship is associated with X.
X reserves the right to monitor the total number of unique users who have authenticated or logged in via Sign In with X (or other X authentication methods) to your products, services, or those made available by or for you or your affiliates and, in the event that total number greatly exceeds the normal levels of other developers subscribed to a similar tier of service, you must apply (or already subscribe) to an Enterprise plan upon written notice from X.
You agree that X may, from time to time, review your *Sign in with X* option and, in its sole discretion, remove this X feature from your service.
## X Cards
**To ensure a quality experience you must develop your Card to render across all platforms where Cards are displayed.** Additional rules that you must follow when using Cards include:
* You must mark your Post as ‘true’ for sensitive media if you plan to display such media within a Card
* You must use HTTPS for hosting all assets within your Card. Your Card should never generate active mixed content browser warnings
* Audio and video content should include stop or pause controls, and default to ‘sound off’ for videos that automatically play content
**You may not exceed or circumvent X’s limitations placed on any Cards, including the Card’s intended use.** Additional restrictions on Cards use include:
* You may not place third-party sponsored content within Cards without X’s approval
* You may not attach monetary incentives (including virtual currency) within your Card or on X from your Card
* You may not include content or actions within your Card that are misleading or not contextually relevant, such as URLs and media.
* You may only attach an App Card to a Post when someone is explicitly promoting or referring to the app in the Post.
## Set yourself up for success
You can avoid many potential pitfalls while using the X API by ensuring that your service has been built the right way from day 1. This section of the Developer Policy contains rules that all developers must follow before using the X API or X Content.
The Free, Basic, and Pro plans (as described at [developer.x.com](http://developer.x.com)) are designed for hobbyists, commercial prototyping, early-stage X product integrations, and supporting applications with limited end-users. If you use the X API and X Content beyond this scope, then you must apply (or already subscribe to) an Enterprise plan (as described at [developer.x.com](http://developer.x.com)).
**We review all proposed uses of the X developer platform to verify policy compliance — so you’re required to disclose (and update, as applicable) your planned use of the X API and X Content in order to be granted and to maintain access.** All new developers must [apply for a developer account](https://developer.x.com/portal/petition/essential/basic-info) to access the X API. Current developers without an approved developer account must apply for one as directed to do so by X. As part of this process, you’ll need to provide us with a written description of your intended uses of the X API and X Content.
Your use case description is binding on you, and any substantive deviation from it may constitute a violation of our rules and result in enforcement action. You must notify us of any substantive modification to your use case and receive approval before you may begin using X Content for that new purpose. Failure to do so may result in suspension and termination of your API and data access.
**By building on the X API or accessing X Content, you must comply with ALL X policies.** These include this [Developer Policy](/developer-terms/policy), the [Automation Rules](https://help.x.com/rules-and-policies/x-automation), the [Display Requirements](https://developer.x.com/developer-terms/display-requirements.html), the [API Restricted Uses Rules](/developer-terms/restricted-use-cases), the [X Rules](https://help.x.com/rules-and-policies/x-rules), and the [X Brand Resources](https://about.x.com/who-we-are/brand-toolkit), as well as any other agreements you enter into with X relating to your use of the X API or X Content, including but not limited to the [Developer Agreement](/developer-terms/agreement) or a Master Licensing Agreement or Order (as applicable). You must also comply with any modifications to these policies and any new policies launched by X. It is your responsibility to monitor the use of your service and to design your service to prevent violations of X policy by people who use it. Failure to do so may result in suspension or termination of your API and X Content access.
**You may not register multiple applications for a single use case or substantially similar or overlapping use cases.** In this context, a “use case” is a consistent set of analyses, displays, or actions performed via an application. "White label" versions of a tool or service are not permissible. If you plan to “white label” versions of your application, you must notify and receive separate approval from us.
*As a single exception to these rules,* you may create and use a maximum of 3 applications for development, staging, and production instances of the same service. These apps must be registered to a single account, and should be clearly identified (in the name and description) as dev, staging, and prod instances of a single service. **You may not use development or staging applications for production purposes.**
**You must keep all API keys or other access credentials private.** You may not use, and may not encourage or facilitate others to use, API keys or other access credentials owned by others.
**Your license agreement with X limits your use of the X API and X Content. Among other things, the X API has rate limits which help to ensure fair data usage and to combat spam on the platform.** You may not exceed or circumvent rate limits, or any other limitations or restrictions described in this Policy or your agreement with X, listed on the [Developer Site](https://developer.x.com/), or communicated to you by X.
**You may not remove or alter any proprietary notices or marks on X Content received via the X API.** This helps to make sure that people know where X Content is coming from, and who it belongs to.
**For data integrity and platform health reasons, you may not interfere with, intercept, disrupt, or disable any features of the X API or the X service.** In other words, use the APIs as intended and documented on [developer.x.com](https://developer.x.com/). Refer to our [HackerOne guidelines](https://hackerone.com/x) for more details about acceptable use.
## Privacy and control are essential
X takes privacy seriously, and we expect everyone using X Content and the X API to do the same. Any use of the X developer platform, X API, or X Content in a manner that is inconsistent with people’s reasonable expectations of privacy may be subject to enforcement action, which can include suspension and termination of API and X Content access.
Your commitment to privacy and control must extend to all uses of X Content and all aspects of the service that you build using our API. To that end, the people using your service must understand and consent to how you use their data, and how you access X on their behalf. This can be accomplished through providing people with a clear, comprehensive, and transparent privacy policy, as well as ensuring that you get express and informed consent from each person using your service before taking any action on their behalf. **Please note that a person authenticating into your service does not by itself constitute consent.**
## Consent & permissions
**In particular, you must get express and informed consent from people before doing any of the following:**
* Taking *any* actions on their behalf. This includes (but is not limited to):
* Posting content to X
* Following/unfollowing accounts
* Modifying profile or account information
* Adding hashtags or any other content to Posts
* Republishing content accessed by means other than via the X API or other X tools
* Using someone’s X Content to promote a product or service
* Storing non-public content such as Direct Messages (DMs), or any other private or confidential information
* Sharing or publishing protected content, or any other private or confidential information
**If your service allows people to post content to X you must do the following before publishing:**
* Show exactly what will be published
* Make it clear to people using your service what geo information (if any) will be added to the content
**If your service allows people to post content to both your service and X, you must do the following before publishing:**
* Obtain permission to post the content
* Explain where you will post the content
**You must respect the protected and blocked status of all X Content. You may not serve content obtained using one person’s authentication token to a different person who is not authorized to view that content.**
* **Protected accounts:** A [protected account](https://help.x.com/safety-and-security/public-and-protected-posts)’s content is only available to people who have been approved by the owner to follow that account. So, if you run a service that accesses protected accounts, you may only do so to serve such content to the specific people with permission to view that content.
* **Blocked accounts:** People on X are able to [block](https://help.x.com/using-x/blocking-and-unblocking-accounts) access to their accounts for any reason they choose. Commingling information obtained from tokens (or any other API-based action) to bypass this choice is not permitted.
**As Direct Messages (DMs) are non-public in nature, services that provide DM features must take extra steps to safeguard personal privacy. You may not serve DM content to people who are not authorized to view that content. If your service provides DM functionality you must also:**
* Notify people if you send read receipt events for DMs. You can do this by providing a notice directly in your service, or by displaying read receipts from other participants in a conversation.
* Get consent before configuring media to be sent in a DM as "shared" (i.e. reusable across multiple DMs). If you do allow media in a DM to be “shared,” you must provide a clear notice that this content will be accessible to anyone with the media’s URL.
## Content compliance
**If you store X Content offline, you must keep it up to date with the current state of that content on X.** Specifically, you must delete or modify any content you have if it is deleted or modified on X. This must be done as soon as reasonably possible, or within 24 hours after receiving a request to do so by X or the applicable X account owner, or as otherwise required by your agreement with X or applicable law. This must be done unless otherwise prohibited by law, and only then with the express written permission of X.
Modified content can take various forms. This includes (but is not limited to):
* Content that has been made private or gained protected status
* Content that has been suspended from the platform
* Content that has had geotags removed from it
* Content that has been withheld or removed from X
## Off-X matching
**We limit the circumstances under which you may match a person on X to information obtained or stored off-X.** Off-X matching involves associating X Content, including a X @handle or user ID, with a person, household, device, browser, or other off-X identifier. You may only do this if you have express opt-in consent from the person before making the association, or as described below.
In situations in which you don’t have a person’s express, opt-in consent to link their X identity to an off-X identifier, we require that any connection you draw be based only on information that someone would reasonably expect to be used for that purpose. In addition, absent a person’s express opt-in consent you may only attempt to match your records about someone to a X identity based on:
* **Information provided directly to you by the person.** Note that records about individuals with whom you have no prior relationship, including data about individuals obtained from third parties, do not meet this standard; and/or
* **Public data.** “Public data” in this context refers to:
* Information about a person that you obtained from a public, generally-available resource (such as a directory of members of a professional association)
* Information on X about a person that is publicly available, including:
* Posts
* Profile information, including an account bio and publicly-stated location
* Display name and @handle
## Your privacy policy
**You must display your service’s privacy policy to people before they are permitted to download, install, or sign up to your service.** It must disclose at least the following information:
* The information that you collect from people who use your service
* How you use and share that information (including with X)
* How people can contact you with inquiries and requests regarding their information
Your privacy policy must be consistent with all applicable laws, and be no less protective of people than [X’s Privacy Policy](https://x.com/privacy) and the [privacy policy of our other services and corporate affiliates](https://help.x.com/rules-and-policies/x-services-and-corporate-affiliates). You must cease your access to the X API and the use of all X Content if you are unable to comply with your and/or X’s Privacy Policy.
## Using geo-data
**Use of geo data comes with additional restrictions due to the sensitive nature of this information.** If your service adds location information to Posts, you must disclose to people:
* When you add location information
* Whether you add location information as a geotag or annotations data
* Whether your location information is listed as a place, or as geographic coordinates
If your application allows people to post with their location you must comply with X’s [geo guidelines](/developer-terms/geo-guidelines) in full.
**Any use of location data or geographic information on a standalone basis is prohibited.** You may not (and may not permit others to) store, aggregate, or cache location data and other geographic information contained in X Content, except as part of a Post. For example, you may not separate location data or geographic information out from Posts to show where individuals have been over time. Heat maps and related tools that show aggregated geo activity (e.g., the number of people in a city using a hashtag) are permitted.
## X passwords
**You may not store X passwords, or request that people provide their X password, account credentials, or developer application information (including consumer key) to you directly.** We suggest the use of [Sign-in with X](/fundamentals/authentication/guides/log-in-with-x) as the authentication tool to link your service and people on X.
# X Developer PPU Agreement
Source: https://docs.x.com/developer-terms/ppu-agreement
The X Developer Pay-Per-Use Agreement covers terms for purchasing and using credits on paid X API services, including billing and usage rules.
By clicking “Pay,” and purchasing credits for use on Paid Services, or by otherwise accessing or using any Licensed Material, you agree to the terms of our Agreement. Credits do not expire unless otherwise specified, and are not transferable or refundable except as required by law. A verified phone number is required to purchase Credits.
This X Developer PPU Agreement (“**Agreement**”) is a binding legal agreement between you (referred to in this Agreement as “**you**”) and X and governs your access to and use of the Licensed Material (defined below), including any Paid Services (defined below).
By accessing or using any Licensed Material (defined below), or clicking on a button to accept the terms of this Agreement or purchase credits for Paid Services, you agree to be bound by the terms of this Agreement. If you do not understand the terms herein or do not accept any part of them, then you may not use or access any Licensed Material. You may not use the Licensed Material or accept this Agreement if you are not of legal age to form a binding contract with X or if you are barred from using or receiving the Licensed Material under applicable law. To purchase and use a Paid Service you must: (i) be at least 18 years old or the age of majority as determined by the laws of the jurisdiction in which you live or (ii) have the express consent of your parent or guardian to purchase and use that Paid Service. If you are a parent or legal guardian and you allow your child (or a child that you are a guardian of) to purchase or use a Paid Service, you agree that the terms of this Agreement apply to you, you will abide by this Agreement, and you are responsible for the child’s activity on the Paid Services and for ensuring that the child also abides by the terms of this Agreement. In any case, as stated in the Who May Use the Services section of the [**X Terms of Service**](https://x.com/tos), you must be at least 13 years old to use the "Services" as defined in the X Terms of Service. If you are accepting this Agreement or using the Licensed Material on behalf of a company, organization, government, or other legal entity, you represent and warrant that you have the authority to bind such company, organization, government, or other legal entity to this Agreement, in which case the words “you” and “your” as used in this Agreement shall refer to such entity. If you do not agree to the terms of this Agreement, you may not (and you may not allow any of your personnel to) access or use the Licensed Material.
I. **Definitions**.
In this Agreement, the following definitions apply:
1. **“Credits”** means virtual units purchased by you to enable usage of Paid Services, with each API call or action deducting a specific number of Credits based on the Pricing Schedule. Credits are not refundable except as required by law, non-transferable, and do not expire unless otherwise specified.
2\. **“Developer Site”** means X’s developer site located at [**https://developer.x.com**](https://developer.x.com/)
3\. **“Direct Message”** means a private message that is sent on X Applications by one user to one or more other specific user(s) using X’s direct messaging function.
4\. **“Intellectual Property Rights”** means all copyrights, moral rights, patent rights, trademarks, and any other intellectual property or similar rights (registered or unregistered) throughout the world.
5\. **“Licensed Material”** means, individually or collectively, the X API and X Content.
6\. **"Paid Service(s)”** means features or functionality of the Licensed Material that you access in exchange for deduction of credits purchased from X and deducted from your account based on your usage of calls and features as detailed on our pricing page. Unless otherwise set forth in this Agreement, all references to “Licensed Material” are intended to include the Paid Service(s).
7\. **“Payment Portal”** means the online portal made available to you to opt-in to your use of the Licensed Material, manage credit purchases for Paid Services, manage payment methods for Paid Services, enable “Auto-Recharge” (see Section VII.F) and update account information.
8\. “**Services”** means your services, websites, applications, and other offerings (including research) that display X Content or otherwise use the Licensed Material.
9\. **“Post”** means a short-form text and multimedia-based message distributed via the X Applications.
10\. **“Pricing Schedule”** means the current list of prices per API call or action, available at [https://developer.x.com/#pricing](https://developer.x.com/#pricing).
11\. **“X”** means (a) X Corp. (865 FM 1209, Building 2, Bastrop, TX 78602, USA) if your principal place of business is outside the European Union, EFTA States, and the United Kingdom; or (b) X Internet Unlimited Company (One Cumberland Place, Fenian Street, Dublin 2, D02 AX07, Ireland) if your principal place of business is in the European Union, EFTA States, or the United Kingdom.
12\. **“X API”** means X Application Programming Interfaces (each, an “API”), Software Development Kits (each, an “SDK”), and the related tools, documentation, data, technology, code, and other materials provided by X through the Developer Site.
13\. **“X Applications”** means X’s real-time information service, commonly referred to as “X,” which includes those services currently provided by X at its websites and X-owned, operated, or controlled mobile applications, social plug-ins, and application programming interfaces.
14\. **“X Content”** means Posts, the unique identification number generated for each Post, X end user profile information, and any other data and information made available to you through the X API or by any other means authorized by X, and any copies and derivative works thereof.
15\. **“X Marks”** means the X name, trademarks, and logos that X makes available to you, including via the Developer Site, solely for use in accordance with this Agreement.
16\. **“Users”** means visitors, users, or customers of your Services.
**II. X API and X Content.**
**A. License from X.** Subject to your compliance with the terms of this Agreement and the applicable Incorporated Developer Terms (as defined below), X hereby grants you a non-exclusive, royalty free, non-transferable, non-sublicensable, and revocable license to solely:
1\. Use the X API to integrate X Content into your Services or conduct analysis of the X Content, as explicitly approved by X;
2\. Copy a reasonable amount of and display the X Content on and through your Services to Users, as permitted by this Agreement;
3\. Modify X Content only to format it for display on your Services; and
4\. Use and display X Marks to attribute X Applications as the source of the X Content, as set forth in this Agreement.
**B. License to X.** You hereby grant X a non-exclusive, royalty free, non-transferable, and non-sublicensable revocable license to access, index, and cache by any means, including web spiders and/or crawlers, any webpage or applications on which you display X Content using [**embedded Posts** or **embedded timelines**](https://publish.x.com).
**C. Incorporated Terms.** Your access to and use of the Licensed Material is also subject to, and you shall comply with, the following additional terms and policies (collectively, “**Incorporated Developer Terms**”):
1\. the [**X Developer Policy**](https://docs.x.com/developer-terms/policy);
2\. the [**API Restricted Use Rules**](https://docs.x.com/developer-terms/restricted-use-cases);
3\. the [**X Rules**](https://help.x.com/rules-and-policies/x-rules);
4\. as it relates to your display of any of the X Content, the [**Display Requirements**](https://docs.x.com/developer-terms/display-requirements);
5\. as it relates to your use and display of the X Marks, the [**X Brand Guidelines**](https://about.x.com/who-we-are/brand-toolkit); and
6\. as it relates to taking automated actions on your account, the [**Automation Rules**](https://help.x.com/rules-and-policies/x-automation).
**III. Restrictions on Use.**
**A. Reverse Engineering and other Restrictions.** You shall not and you shall not attempt to (or allow others to): (a) reverse engineer, decompile, disassemble, or translate the X API or otherwise attempt to derive source code, trade secrets, or know-how in or underlying any X API or any portion thereof; (b) interfere with, modify, disrupt, or disable features or functionality of the X API or monitoring mechanisms of the X API; (c) use or access the Licensed Material to create or attempt to create a substitute or similar service or product to the X Applications; (d) sell, rent, lease, sublicense, distribute, redistribute, syndicate, create derivative works of, assign, or otherwise transfer or provide access to, in whole or in part, the Licensed Material to any third party except as expressly permitted in this Agreement; (e) provide use of the X API on a service bureau, rental or managed services basis, or permit other individuals or entities to create links to the X API or "frame" or "mirror" the X API on any other server, or wireless or Internet-based device, or otherwise make available to a third party any token, key, password, or other login credentials to the X API; (f) use the Licensed Material for any illegal, unauthorized, or other improper purpose; (g) use the Licensed Material to derive or obtain non-public information of individual X users; (h) interfere with or disrupt the integrity or performance of the X Applications, X API, or X Content contained therein; (i) remove or alter any proprietary notices or marks on the X Content; (j) attempt to gain unauthorized access to the X Applications, X API, X Content, or related systems or networks; (k) use the X API or X Content to fine-tune or train a foundation or frontier model; or (l) use X Content, by itself or bundled with third party data, or derivative analysis therefrom, to target or serve users with advertising outside of the X Applications.
**B. Commercial Use Restrictions.** If your Services are designated as ‘non-commercial,’ you shall not make Commercial Use (as defined below) of the Licensed Material. Commercial Use restrictions may not apply to officially registered non-profits or NGOs. “Commercial Use” means any use of the Licensed Material or access to the X API: (a) by or for a business (i.e. an entity whose primary purpose is to earn revenue through a product or service), or (b) as part of a product or service that is monetized (e.g., website advertising, licensing fees, in-app promotions, and sponsorships).
**C. No Monitoring or Measuring.** Notwithstanding anything to the contrary, you may use the following information only for non-commercial, internal purposes (e.g., to improve the functionality of the Services): (a) aggregate X Applications user metrics, such as number of active users or accounts on X Applications; (b) the responsiveness of X Applications; and (c) results, usage statistics, data, or other information (in the aggregate or otherwise) derived from analyzing, using, or regarding the performance of the X API. All such information is Confidential Information (as defined below).
**D. Rate Limits.** You will not attempt to exceed or circumvent limitations on access, calls or use of the X API ("Rate Limits"), or otherwise use the X API in a manner that exceeds reasonable request volume, constitutes excessive or abusive usage or does not otherwise comply with this Agreement. API calls and requests will deduct credits from your balance as specified in the Pricing Schedule available at [https://developer.x.com/#pricing](https://developer.x.com/#pricing). If your credit balance is insufficient for a call, requests will be denied until your credit balance is sufficient to allow deduction for that request. If you exceed or X reasonably believes that you have attempted to circumvent Rate Limits, controls to limit use of the X APIs, or are otherwise using Licensed Material in breach of this Agreement, then your ability to use the Licensed Material may be temporarily suspended or permanently blocked. X may monitor your use of the X API to improve the Licensed Material and X Applications and to ensure your compliance with this Agreement and the Incorporated Developer Terms. You agree to comply with X’s requests for additional information in connection with your usage. X may review your use of Licensed Material at any time. X’s granting of access to the X API or allowing use of Licensed Material shall be deemed to be approval of your use or a waiver or limitation on its right to required use that is compliant with this Agreement and X’s policies. No payments made are refundable, however, X may, in its discretion, permit unused Credits to be used for use that is compliant with this Agreement.
**E. Location Data.** You shall not, and you shall not allow others to, aggregate, cache, or store location data and other geographic information contained in the X Content except in conjunction with the X Content to which it is attached. You may only use location data and geographic information to identify the location tagged by the X Content.
**F. Use of X Marks.** You shall not include any of the X Marks in your registered corporate name(s), your logos, or your service or product names. You shall not create any derivative works of the X Marks or use the X Marks in a manner that creates or reasonably implies an endorsement, sponsorship, or association with X. All use of the X Marks and all goodwill arising out of the use will inure to X's benefit. You will not remove or alter any proprietary notices or X Marks on the Licensed Material.
**G. Security.** You will maintain the security of the X API and will not make available to any third party any token, key, password, or other login credentials to the X API. You will use industry standard security measures to prevent unauthorized access or use of any of the features and functionality of the X API, including access by viruses, worms, or any other harmful code or material. You shall keep X Content confidential and secure from unauthorized access by using industry-standard organizational and technical safeguards for such data, and with no less care than you use in connection with securing similar data you store. You will immediately notify X, consult and cooperate with investigations, assist with any required notices, and provide any information reasonably requested by X if you know of or suspect any breach of security or potential vulnerability related to the Licensed Material. You will promptly remedy such breach or potential vulnerability resulting from your access to the Licensed Material.
**H. Digital Services Act.** Notwithstanding anything to the contrary in this Agreement, to the extent you are provided access to the Licensed Material pursuant to the procedures described in Article 40 of the Digital Services Act (Regulation (EU) 2022/2065) (“DSA”), your access and use of the Licensed Material is limited solely to performing research that contributes to the detection, identification, and understanding of systemic risks in the European Union and only to the extent necessary for X to comply with its obligations under the DSA. Any such use of the Licensed Material is non-commercial as described in Section III(B) of this Agreement. You may not disclose, reproduce, license, or otherwise distribute the Licensed Material (including any derivatives thereof) that you retrieve through the X API to any person or entity outside the persons specified within your approved application unless (i) the information is disclosed to the Digital Services Coordinator or other party specifically permitted by the DSA pursuant to the “vetted researcher” status and procedures described in Article 40, or (ii) disclosure is required by law.
**I. Tokens.** X may limit the number of tokens that it provides to you, including but not limited to tokens that enable access and use of functionality or features on X Applications.
**J. Usage Levels Under Agreement.** X may, at any time, review your use of its Licensed Materials under this Agreement, and suspend or terminate your use and require you to file an application for Enterprise access (as described at [**https://docs.x.com/enterprise-api/introduction**](https://docs.x.com/enterprise-api/introduction)) in order for X to consider your proposed continued use of Licensed Materials.
**K. Prohibition on I-Framing:** You shall not, under any circumstances, embed, display, or otherwise incorporate any Licensed Material, X Content, X API, or elements of the X Applications within an iframe, inline frame, or any similar embedding mechanism on your Services or any other platform. This prohibition is absolute and includes, but is not limited to, attempts to frame X Content for display, integration, or redistribution purposes. Violation of this clause may result in immediate termination of your Developer Agreement and your access to the Licensed Material (e.g., X API, X Data License, Developer Console) as outlined in Section VII.I.
**L. Self-Serve Use.** The Pay-Per-Use, Basic, and Pro plans (as described at [developer.x.com](https://developer.x.com)) are designed for hobbyists, commercial prototyping, initial development, early-stage X product integrations, and supporting applications with a limited number of end-users. If you use the X API beyond this scope, then you must apply (or already subscribe to) an Enterprise plan (as described at [developer.x.com](https://developer.x.com)).
**M. Commercial Use:** If you use the X API beyond the scope of hobbyist projects, commercial prototyping, initial development, early-stage X product integrations, or for applications with a limited number of end-users, then you must apply (or already subscribe to) an Enterprise plan (as described at developer.x.com).
**IV. Updates and Removals.**
**A. Updates.** X may update, modify or discontinue any features or function of the Licensed Material, in whole or in part, from time to time (in each instance, an “Update”). You shall implement and use the most current version of the Licensed Material and make any changes to your Services that are required as a result of the Update, at your sole expense. Updates may adversely affect the way your Services access or communicate with the X API or display X Content. X will not be liable for damages of any sort that result from any Update.
**B. Removals.** If X Content is deleted, gains protected status, or is otherwise suspended, withheld, modified, or removed from the X Applications (including removal of location information), you will make all reasonable efforts to delete or modify that X Content (as applicable) as soon as possible, and in any case within twenty four (24) hours after a written request to do so by X or by an X user with regard to its X Content unless prohibited by law or regulation and with the express written permission of X.
**V. Ownership, Betas, and Feedback.**
**A. Ownership.** Except to the extent expressly stated otherwise in this Agreement, neither party will acquire any right, title, or interest in any Intellectual Property Rights owned or licensed by the other party. The Licensed Material is licensed, not sold, and X (or its licensors or X Application users, as applicable) retains and reserves all rights, including all Intellectual Property Rights, not expressly granted in this Agreement. You shall not do anything inconsistent with X’s ownership, including without limitation, challenging X’s ownership of the X Marks, challenging the validity of the licenses granted in this Agreement, or otherwise copying or exploiting the X Marks except as specifically authorized in this Agreement. If you acquire any rights in the X Marks or any confusingly similar marks, by operation of law or otherwise, you will, at no expense to X, immediately assign those rights to X.
**B. Betas.** X may provide you with early access to non-generally available alphas, betas, research studies, pilots, marketing services, or other programs from time to time (each, a “Beta”). Betas will be considered Confidential Information. Your participation in any Beta is at your own risk, may be subject to additional requirements, and may assist X in research, analyzing, and validating existing or prospective programs, products and/or tools.
**C. Feedback.** X will be free to use any feedback, comments, or suggestions you provide X related to X, the Licensed Material, Betas, or any other of X’s products or services (“Feedback”) in any way without any compensation or obligation to you or any third party and Feedback will be deemed Confidential Information. You hereby irrevocably assign to X all right, title, and interest to Feedback.
**VI. Confidentiality.**
You may be given access to non-public information, software, and specifications relating to the Licensed Material (“Confidential Information”). You may use Confidential Information only as necessary in exercising your rights under this Agreement. You shall not disclose Confidential Information to any third party without X’s prior written consent. You shall protect Confidential Information from unauthorized use, access, or disclosure in the same manner that you would use to protect your own confidential information of a similar nature and in no event with less than a reasonable degree of care.
**VII. Term; Credit Purchase Terms; Credit Deduction; Suspension, and Termination.**
**A. Term.** The term of this Agreement will start on the date (i) you accept the terms herein or (ii) start accessing or using any of the Licensed Material, whichever is earlier, and will continue until you stop accessing and using the Licensed Material unless terminated earlier as described below.
**B. Credit Purchase Terms.** Paid Services provided as part of the Licensed Material are made available through the purchase of Credits that are deducted based on your use of features, benefits, or services, including X API usage, as described on the [https://developer.x.com/#pricing](https://developer.x.com/#pricing), Developer Site and the Payment Portal. If you purchase a Paid Service, you do so by first purchasing Credits in advance by paying the applicable fee upfront via the Payment Portal. Your credit balance will be updated after purchase and deducted as you use Paid Services. You must purchase additional credits as needed to enable access to Paid Services. Credit purchases are non-recurring unless you enable optional “Auto-Recharge” features detailed in Section VII.D. When you purchase credits via the Payment Portal, you expressly agree to the terms herein and authorize the charge. X may provide notifications for low balances. Prices for credits and deduction rates are subject to change from time to time as set forth in the Pricing Schedule. X will provide reasonable advance notice of any material change to prices, which notice may be provided via the Developer Site or Payment Portal. Price changes will apply to future purchases and deductions. If you do not agree with a price change, you may cease purchasing credits and using Paid Services. Credits do not expire unless otherwise specified, and are not transferable or refundable except as required by law.
**C. Credit Deduction:** Access to Paid Services requires sufficient credits in your account. Each API call or request or use of other feature or service specified in the Pricing Schedule will deduct credits from your balance based on the rates specified in the Pricing Schedule. Deduction rates may vary, and the Pricing Schedule is subject to change. X aims to deduct credits at the time of each call or request or use of other feature or service specified in the Pricing Schedule, and to deny Paid Services for which you have an insufficient balance. In that case, you will need to purchase additional credits to enable the Paid Service. You may not maintain a negative credit balance. It is your responsibility to monitor your credit balance to help maintain access to Paid Services.
**D. Usage Disputes**: If you believe there has been an error in credit deductions, you must notify X within thirty (30) days of the disputed deduction via [billing support](https://docs.x.com/forms/billing-support). X will investigate and, if an error is confirmed, adjust your credit balance accordingly. Adjustments are at X’s sole discretion and subject to this Agreement.
**E. Payment Terms.** X may offer payment options that vary by Paid Service, device, operating system, geographic location, or other factors, which may be updated from time to time. These payment options may include web payments using a third party payment processor (“Payment Processor”). When you access a Paid Service, you agree: (i) to pay the price listed for Credits, along with any additional amounts relating to applicable taxes, surcharges, credit card fees, bank fees, foreign transaction fees, foreign exchange fees, and currency fluctuations; and (ii) to abide by any applicable terms of service, privacy policies, or other legal agreements or restrictions (including additional age restrictions) imposed by the Payment Processor in connection with your use of a given payment method. The fee will be charged at the time of Credit purchase. It is your responsibility to monitor your Credit balance and make sure your banking, credit card, debit card, and/or other payment information is up to date, complete, and accurate at all times. If you make a payment for a Paid Service through a Payment Processor, X may receive information about your transaction such as when it was made, what platform you made the purchase on, and other information. X will not be liable for any errors made or delays by the Payment Processor, your bank, your credit card company, or any payment network. All payments to X are non-refundable except as otherwise expressly provided in this Agreement or as required by law.
**F. Optional Auto-Recharge Feature.** You may opt in to an “auto-recharge” feature via the Developer Console, authorizing X to automatically charge your saved payment method a user-selected amount when your credit balance falls below the threshold set in the auto-recharge tool, with charges including the applicable taxes and fees for that amount as per Section VII.E; you may modify or disable this feature at any time through the Payment Portal, and by enabling it, you consent to X, via its third-party Payment Processor, charging the selected amount each time the threshold is met, though failed charges (e.g., due to an invalid payment method) will prevent credit additions. Enabling auto-recharge does not guarantee uninterrupted access to Paid Services. You remain responsible for monitoring your credit balance, regardless of notifications X may provide for low balances or auto-recharge events, and auto-recharge charges are non-refundable except as required by law.
**D. Taxes and fees.** All fees exclude any and all taxes and similar fees now in force, enacted, or imposed in the future on the transaction, delivery of the Licensed Material, or the delivery of the X Content including any sales, use or value added taxes, goods and services tax, consumption tax, customs duties, tariffs, or similar charges. These taxes may include but are not limited to, VAT, GST, sales tax, withholding tax, and any other applicable taxes but exclude taxes solely based on X’s net income. You are responsible for the payment of all such taxes, duties, and charges and any related penalties and interest arising from the payment of such amounts. In addition, a surcharge may be charged to recover costs associated with Digital Services Tax ("DST") or similar jurisdiction-specific taxes or regulatory fees incurred by X in certain jurisdictions. This surcharge will appear as a separate line item on your invoice, where applicable, and will be calculated as a percentage of applicable charges as determined by X in its sole discretion. X may adjust this surcharge at any time, without prior notice, in response to increased tax or fee rates or related administrative costs. Depending on your location, X may be responsible for collecting and reporting information related to transaction taxes arising from your purchase of Paid Services. You grant X permission to provide your account and personal information to relevant tax authorities to fulfill our tax collection and reporting obligations.
**E. Refunds and Cessation of Paid Services.** You may cease using Paid Services at any time by not making further API calls. Unused credits are non-refundable and non-transferable, with no refunds for purchased or used credits, unless required by law. CREDIT PURCHASES ARE PREPAID, NON-REFUNDABLE (UNLESS REQUIRED BY LAW). You may request a refund for unused credits only in accordance with applicable law (e.g., withdrawal rights below). All transactions are final unless you have a right to withdraw pursuant to law, such as provided below.
**1. Withdrawal Right & Refunds for Users Living in EU or UK.** You have a legal right to withdraw from your credit purchase without giving any reason within 14 days from the date of purchase (“Withdrawal Period”). To exercise this right, you must inform X of your decision to withdraw before the Withdrawal Period expires by submitting a clear statement of withdrawal to [billing support](https://docs.x.com/forms/billing-support). If you withdraw within the Withdrawal Period and have not used any credits, X will refund the full amount paid for the credit purchase, including any applicable taxes or fees, within fourteen (14) days of receiving your withdrawal notice, using the same payment method used for the purchase, unless you expressly agree otherwise.
However, you expressly acknowledge and agree that if you use any credits during the Withdrawal Period (e.g., by making API calls or requests), you waive your right to withdraw, as the Paid Services will have begun with your prior express consent and acknowledgment that your withdrawal right is lost upon such use. If you use only a portion of your purchased credits during the Withdrawal Period and then exercise your withdrawal right, X will refund the amount corresponding to the unused credits, calculated based on the Pricing Schedule available at [https://developer.x.com/#pricing](https://developer.x.com/#pricing).
**2. No Withdrawal Right for Users Living in Taiwan.** If you are a consumer residing in Taiwan, you may be entitled to a seven (7) day withdrawal period for credit purchases under the Consumer Protection Act, unless you have used any credits, in which case the right to withdraw is lost. To exercise this right, you must notify X within seven (7) days from the date of purchase at [billing support](https://docs.x.com/forms/billing-support). Refunds for unused credits will be processed in accordance with applicable law.
**F. Credits Are Non-Transferable between X Accounts.** Each purchase of Credits applies to a single X account, meaning that your purchase will apply solely to the account you were using when you purchased the Credits and will not apply to other accounts that you may have access to or control over. If you have or control multiple accounts and you want access to Paid Services on each account, you must purchase the needed Credits on each account individually. You may not allow others to use your X account to access any Licensed Material that such person did not order. You may not purchase Credits or use any Licensed Material if you are a person with whom U.S. persons are not permitted to have dealings pursuant to economic sanctions, including, without limitation, sanctions administered by the United States Department of the Treasury's Office of Foreign Assets Control or any other applicable sanctions authority ("Prohibited Person"). This includes, without limitation, persons located in, a citizen of, or ordinarily resident in the following countries and regions: Cuba, Iran, the Crimea Region of Ukraine, North Korea and Syria. You represent and warrant that you are not a Prohibited Person.
**G. Restrictions and Obligations.** You may only purchase and use Credits and use the Licensed Material if you are legally allowed to use the Licensed Material in your country and you live in a country supported by X for the applicable Credit purchase, Paid Service or Licensed Material. X may, in its discretion, restrict the ability to access the Licensed Material or purchase Credits in certain countries. X reserves the right to modify the list of supported countries from time to time. X reserves the right to refuse sale of Credits or access to Paid Services or to cancel or discontinue the sale or use of a Paid Service or the use of any Licensed Material in its sole discretion.
**H. Suspension.** X may suspend your use of and access to the Licensed Material immediately without notice (a) if X reasonably believes that (i) your use of the Licensed Material would cause damage to, or an inordinate burden upon, the Licensed Material, (ii) you have violated this Agreement, (iii) you create risk or possible legal exposure for X, (iv) X’s provision of the Licensed Material to you is no longer commercially viable; (b) for prolonged inactivity; (c) if X is requested or directed to do so by any competent court of law, regulatory authority, or law enforcement agency; or (d) for failure to pay for the Paid Services. X will not be liable for damages of any sort that result from any such suspension.
**I. Termination.** X may terminate this Agreement for any reason at X’s sole discretion. Such early termination by X shall be effective immediately. If you violate the terms of this Agreement, X may terminate this Agreement for cause immediately upon notice to you and you will not receive a refund for any Credits. You may cancel your access to Paid Services or your use of the Licensed Material on the Developer Site. You will not be entitled to a refund of any Credits, and you will not be entitled to use of any unused Credits. Upon termination of this Agreement: (a) all licenses granted in this Agreement immediately expire and you must cease use of any Licensed Material; and (b) you shall permanently delete all Licensed Material in all forms and types of media, and copies thereof, in your possession. Upon the request of X for any reason, you will promptly (and in any event within ten (10) business days of such request) provide evidence (e.g., screenshots of deletion confirmation) of compliance with the provisions of the aforementioned subpart (b) of this Section. The parties to this Agreement will not be liable to each other for any damages resulting solely from termination of this Agreement as permitted under this Agreement.
**VIII. Compliance Audit.**
X or a mutually agreed upon third party agent subject to obligations of confidentiality will be entitled to inspect and audit any records related to the performance of this Agreement in your control or possession upon reasonable notice to you, and at a reasonable time during normal business hours, for the purpose of verifying compliance with this Agreement and the fees payable to X for the two (2) year period preceding the audit. X may exercise its audit right no more than once every twelve (12) months unless it has reasonable cause for noncompliance, and such audit shall not unreasonably interfere with your business activities. You will provide your full cooperation and assistance with such audit and provide access to all Licensed Material in your possession, applicable agreements, and records. Without limiting the generality of the foregoing, as part of the audit, X may request, and you agree to provide, a written report, signed by an authorized representative, listing your then-current deployment of the Licensed Material. You will pay X within thirty (30) business days after the completion of the audit the amount of any underpayment revealed by any such audit. In addition, if any such audit reveals an underpayment by you of five percent (5%) or more, then you will also reimburse X for the reasonable costs and expenses of such audit. The requirements of this Section will survive for one (1) year following the termination of this Agreement.
**IX. Disclaimer.**
TO THE MAXIMUM EXTENT PERMISSIBLE BY APPLICABLE LAW, THE LICENSED MATERIAL IS PROVIDED TO YOU “AS IS”, “WHERE IS”, WITH ALL FAULTS, AND X DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, AND ANY WARRANTIES OR CONDITIONS ARISING OUT OF THIS AGREEMENT, COURSE OF DEALING OR USAGE OF TRADE. X DOES NOT WARRANT THAT THE LICENSED MATERIAL OR ANY OTHER X PRODUCT OR SERVICE PROVIDED HEREUNDER WILL MEET ANY OF YOUR REQUIREMENTS OR THAT USE OF SUCH LICENSED MATERIAL OR OTHER PRODUCTS OR SERVICES WILL BE ERROR-FREE, UNINTERRUPTED, VIRUS-FREE, OR SECURE. YOU ARE RESPONSIBLE FOR YOUR USE OF THE LICENSED MATERIAL AND ANY CONTENT YOU PROVIDE. THIS DISCLAIMER OF WARRANTY MAY NOT BE VALID IN SOME JURISDICTIONS AND YOU MAY HAVE WARRANTY RIGHTS UNDER LAW WHICH MAY NOT BE WAIVED OR DISCLAIMED.
**FURTHER YOU UNDERSTAND AND AGREE THAT THE PAID SERVICES ARE PROVIDED TO YOU ON AN “AS IS” AND “AS AVAILABLE” BASIS.**
**X. Indemnification.**
You shall defend X against any and all proceedings, demands, claims, and suits (including without limitation product liability claims), and indemnify X from any and all liabilities, damages, and costs (including without limitation reasonable attorneys' fees) to the extent arising out of (a) your use of the Licensed Material in any manner that is inconsistent with this Agreement or (b) the performance, promotion, sale, or distribution of your Services. If X seeks indemnification or defense from you under this Section, X will promptly notify you in writing of the claim(s) brought against X for which it seeks indemnification or defense. X may assume full control of the defense of claims with legal counsel of its choice. You shall not enter into any third-party agreement that would affect the rights of X, constitute an admission of fault by X, or bind X in any manner without the prior written consent of X. If X assumes control of the defense of such claim, X shall not settle any such claim requiring payment from you without your prior written approval.
**XI. Limitation of Liability.**
IN NO EVENT WILL X BE LIABLE TO YOU OR ANY USERS FOR ANY INDIRECT, SPECIAL, INCIDENTAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL DAMAGES OR ANY LOSS OF OR DAMAGE TO USE, DATA, BUSINESS, GOODWILL OR PROFITS ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT. IN ANY CASE, X'S AGGREGATE LIABILITY FOR ANY AND ALL CLAIMS UNDER THIS AGREEMENT WILL NOT EXCEED FIFTY DOLLARS (\$50.00). THE FOREGOING LIMITATIONS, EXCLUSIONS AND DISCLAIMERS SHALL APPLY REGARDLESS OF WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON CONTRACT, WARRANTY, TORT, STRICT LIABILITY OR OTHERWISE, AND WHETHER OR NOT X HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. IF APPLICABLE LAW PROHIBITS ANY LIMITATION ON LIABILITY HEREIN, THE PARTIES AGREE THAT THE LIMITATION WILL BE DEEMED TO HAVE BEEN MODIFIED TO CONFORM TO APPLICABLE LAW. THE PARTIES AGREE THAT THE LIMITATIONS ON LIABILITIES SET FORTH HEREIN ARE AGREED ALLOCATIONS OF RISK AND SUCH LIMITATIONS WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.
**XII. Agreement Updates.**
X may update or amend this Agreement or any of the Incorporated Developer Terms from time to time. You will check the Developer Site regularly for updates. X will alert you of material revisions to these terms by posting the updated terms on these sites, via a service notification, or by other suitable means (e.g., via email to an email address associated with your account). The changes will not be retroactive and the most current version of this Agreement, available at the Developer Site, will govern your access to and use of the Licensed Material and any corresponding transactions. Your continued access or use of the Licensed Material will constitute binding acceptance of such updates and modifications.
**XIII. Dispute Resolution and Class Action Waiver.**
**A. THIS SECTION APPLIES TO YOU ONLY IF YOU LIVE OUTSIDE THE EUROPEAN UNION, EFTA STATES, OR THE UNITED KINGDOM, INCLUDING IF YOU LIVE IN THE UNITED STATES. PLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT.**
**1. Choice of Law and Forum Selection.** The laws of the State of Texas, excluding its choice of law provisions, will govern this Agreement and any dispute that arises between you and X, notwithstanding any other agreement between the parties to the contrary. All disputes related to this Agreement, including any disputes, claims, or controversies arising out of or relating to this Agreement, the marketing of the Licensed Material, and/or your participation in the Licensed Material will be brought exclusively in the U.S. District Court for the Northern District of Texas or state courts located in Tarrant County, Texas, United States, and you consent to personal jurisdiction in those forums and waive any objection as to inconvenient forum. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute it has against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
If you are a federal, state, or local government entity in the United States using the Licensed Material in your official capacity and legally unable to accept the controlling law, jurisdiction, or venue clauses above, then those clauses do not apply to you. For such U.S. federal government entities, this Agreement and any action related thereto will be governed by the laws of the United States of America (without reference to conflict of laws) and, in the absence of federal law and to the extent permitted under federal law, the laws of the State of Texas (excluding choice of law).
**2. YOU HAVE ONE YEAR TO BRING A CLAIM AGAINST X.** You must bring any claim against X arising out of or related to this Agreement within one (1) year after the date of the occurrence of the event or facts giving rise to the dispute unless applicable law provides that the normal statute of limitations for that claim may not be shortened by agreement. If you do not bring a claim within this period, you forever waive the right to pursue any claim or cause of action, of any kind or character, based on such events or facts, and such claims or causes of action are permanently banned and X will have no liability with respect to such claim.
**3. Class Action Waiver.** To the extent permitted by law, you also waive the right to participate as a plaintiff or class member in any purported class action, collective action, or representative action proceeding.
**4. Changes to this Section.** This Dispute Resolution Section survives the end of the relationship between you and X, including cancellation of or unsubscribing from any services or communications provided by X.
**5. Injunctive Relief.** Notwithstanding the foregoing, you agree that money damages would be an inadequate remedy for X in the event of a breach or threatened breach of this Agreement protecting X's intellectual property or Confidential Information, and that in the event of such a breach or threat, X, in addition to any other remedies to which it is entitled, is entitled to preliminary or injunctive relief (including an order prohibiting you from taking actions in breach of such provisions), without the need for posting bond, and specific performance as may be appropriate. The parties agree that neither the United Nations Convention on Contracts for the International Sale of Goods nor the Uniform Computer Information Transaction Act shall apply to this Agreement, regardless of the states in which the parties do business or are incorporated. No waiver by X of any covenant or right under this Agreement will be effective unless memorialized in a writing authorized by X.
**B. THIS SECTION APPLIES TO YOU ONLY IF YOU LIVE IN THE EUROPEAN UNION, EFTA STATES, OR THE UNITED KINGDOM. PLEASE READ THIS SECTION CAREFULLY – IT MAY SIGNIFICANTLY AFFECT YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT.**
**1. Choice of Law and Forum Selection.** To the extent permitted by law, all disputes related to this Agreement, including any disputes, claims, or controversies arising out of or relating to this Agreement, the marketing of the Licensed Material, and/or your participation in the Licensed Material, will be brought exclusively before a competent court in Ireland without regard to conflict of law provisions and will be governed by Irish law, notwithstanding any agreement between the parties to the contrary. Without prejudice to the foregoing, you agree that, in its sole discretion, X may bring any claim, cause of action, or dispute it has against you in any competent court in the country in which you reside that has jurisdiction and venue over the claim.
**2. YOU HAVE ONE YEAR TO BRING A CLAIM AGAINST X.** You must bring any claim against X arising out of or related to this Agreement within one (1) year after the date of the occurrence of the event or facts giving rise to the dispute unless applicable law provides that the normal statute of limitations for that claim may not be shortened by agreement. If you do not bring a claim within this period, you forever waive the right to pursue any claim or cause of action, of any kind or character, based on such events or facts, and such claims or causes of action are permanently banned, and X will have no liability with respect to such claim.
**3. Class Action Waiver.** To the extent permitted by law, you also waive the right to participate as a plaintiff or class member in any purported class action, collective action, or representative action proceeding.
**4. Changes to this Section.** This Dispute Resolution section survives the end of the relationship between you and X, including cancellation of or unsubscribing from any services or communications provided by X.
**5. Injunctive Relief.** Notwithstanding the foregoing, you agree that money damages would be an inadequate remedy for X in the event of a breach or threatened breach of this Agreement protecting X's intellectual property or Confidential Information, and that in the event of such a breach or threat, X, in addition to any other remedies to which it is entitled (including money damages), is entitled to such preliminary or injunctive relief (including an order prohibiting you from taking actions in breach of such provisions), without the need for posting bond, and specific performance as may be appropriate. The parties agree that neither the United Nations Convention on Contracts for the International Sale of Goods nor the Uniform Computer Information Transaction Act shall apply to this Agreement regardless of the states in which the parties do business or are incorporated. No waiver by X of any covenant or right under this Agreement will be effective unless memorialized in a writing authorized by X.
**XIV. Miscellaneous.**
**A. Assignment.** You shall not assign any of the rights or obligations granted hereunder, in whole or in part, whether voluntarily or by operation of law, contract, merger (whether you are the surviving or disappearing entity), stock or asset sale, consolidation, dissolution, through government action, or otherwise, except with the prior written consent of X. X is authorized to sign modifications and consents for X Internet Unlimited Company, an Irish company responsible for the information of X users who live outside the United States. Any attempted assignment in violation of this Section will be null and void and X may terminate this Agreement.
**B. User Protection.** Unless explicitly approved by X in writing, you shall not use, or knowingly display, distribute, or otherwise make X Content, or information derived from X Content, available for purpose of: (a) conducting or providing surveillance or gathering intelligence, including but not limited to investigating or tracking X users or X Content; (b) conducting or providing analysis or research for any unlawful or discriminatory purpose or in a manner that would be inconsistent with X users' reasonable expectations of privacy; (c) monitoring sensitive events (including but not limited to protests, rallies, or community organizing meetings); or (d) targeting, segmenting, or profiling individuals based on sensitive personal information, including their health (e.g., pregnancy), negative financial status or condition, political affiliation or beliefs, racial or ethnic origin, religious or philosophical affiliation or beliefs, sex life or sexual orientation, trade union membership, X Content relating to any alleged or actual commission of a crime, or any other sensitive categories of personal information prohibited by law.
**C. Government Use**. If you display, distribute, or otherwise make available any X Content to Users that are, or that act on behalf of, any government-related entity (each a “**Government End User**”); (a) you must apply for (or already subscribe to) an Enterprise plan (as described at [**https://docs.x.com/enterprise-api/introduction**](https://docs.x.com/enterprise-api/introduction)); (b) you shall identify all such Government End Users when submitting your use case for review to X; and (c) you shall thereafter notify X in writing of any new Government End Users or any new use cases with existing Government End Users before the Services display, distribute, or otherwise make available any X Content to a Government End User or for any new use case. X may prohibit you from making X Content available to any Government End User. You shall not use, or knowingly display, distribute, or otherwise make X Content, or information derived from X Content, available to any Government End User whose primary function or mission includes conducting surveillance or gathering intelligence. If law enforcement requests information about X or its users for purposes of an ongoing investigation, you may refer them to X’s Guidelines for Law Enforcement located at [**https://help.x.com/rules-and-policies/x-law-enforcement-support**](https://help.x.com/rules-and-policies/x-law-enforcement-support). The X API and X Content are "commercial items" as that term is defined at 48 C.F.R. 2.101, consisting of "commercial computer software" and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212. Any use, modification, derivative, reproduction, release, performance, display, disclosure, or distribution of the X API or X Content by any government entity is prohibited except as expressly permitted by the terms of this Agreement. Additionally, any use by U.S. government entities must be in accordance with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4. If you use the X API or X Content in your official capacity as an employee or representative of a U.S. state or local government entity and you are legally unable to accept the indemnity, jurisdiction, venue, or other clauses herein, then those clauses do not apply to such entity to the extent required by law. Contractor/manufacturer is X Corp., 865 FM 1209, Building 2, Bastrop, TX 78602, USA.
**D. Compliance with Laws; Export and Import.** Each party will comply with all applicable foreign, federal, state, and local laws, rules and regulations, including without limitation all laws relating to bribery and/or corruption. The Licensed Material is subject to U.S. export laws and may be subject to import and use laws of the country where it is delivered or used. You shall abide by these laws. Under these laws, the Licensed Material may not be sold, leased, downloaded, moved, exported, re-exported, or transferred across borders without a license, or approval from the relevant government authority, to any country or to any foreign national restricted by these laws, including countries embargoed by the U.S. Government (currently Cuba, Iran, North Korea, Northern Sudan and Syria), to any restricted or denied end-user, including but not limited to any person or entity prohibited by the U.S. Office of Foreign Assets Control, or for any restricted end-use. You shall maintain all rights and licenses that are required for your Services.
**E. Data Protection Addendum.** Each party shall comply with the X Controller-to-Controller Data Protection Addendum located at [**https://gdpr.x.com/controller-to-controller-transfers.html**](https://gdpr.x.com/en/controller-to-controller-transfers.html), which may be updated by X from time to time.
**F. Survival.** Sections III (Restrictions on Use), V (Ownership and Feedback), VI (Confidentiality), VII(I) (Termination), VIII (Compliance Audit), IX (Warranty Disclaimer), X (Indemnification), XI (Limitation of Liability), XIII (Dispute Resolution and Class Action Waiver); and XIV (Miscellaneous) of this Agreement will survive the termination of this Agreement.
**G. Entire Agreement.** This Agreement constitutes the entire understanding of the parties regarding the subject matter of this Agreement and supersedes all other agreements between the parties related to the subject matter, whether written or oral. If any provision of this Agreement is held by a court of law to be unenforceable, the remaining provisions of the Agreement will remain in effect. No waiver under this Agreement will be effective unless it is in writing and signed by the party granting the waiver. A waiver granted on one occasion will not operate as a waiver on other occasions. This Agreement does not create or imply any partnership, agency or joint venture.
[**DEVELOPER POLICY AND TERMS**](https://docs.x.com/developer-terms)
FOLLOW [**@XDEVELOPERS**](https://x.com/XDevelopers)
[**Subscribe to developer news**](https://developer.x.com/twitterdev-news-subscription)
# Display requirements: Replies
Source: https://docs.x.com/developer-terms/reply-requirements
Display requirements for showing replies to Posts in apps that use the X API, including thread structure, attribution, and reply context rules.
## Reply
Please follow the following guidelines for displaying replies.
### For a default reply:
### For a reply with social context:
### For a Quote:
# Restricted uses of the X API
Source: https://docs.x.com/developer-terms/restricted-use-cases
Details on restricted use cases for the X API, including off-platform tracking, government surveillance, sensitive data handling, and prohibited tools.
Use of our developer platform requires that you review and agree to our [Developer Agreement and Policy](/developer-terms/agreement), as well as our related policies, including the [Display Requirements](https://docs.x.com/developer-terms/display-requirements) and [Automation Rules](https://help.x.com/en/rules-and-policies/twitter-automation). Among other things, our agreements and policies provide guidance about several restricted use cases. We’ve provided additional information about some of these restrictions below.
## Automation, spam, and auto-responses
The use of X's APIs and developer products to create spam, or engage in spammy behavior, is prohibited. You should review the [X Rules](https://t.co/rules) on spam, and ensure that your application does not, and does not enable users to, violate our policies.
If your application will be used to perform write actions on the X service, including posting Posts, following accounts, or sending Direct Messages, you should carefully review the [Automation Rules](https://support.x.com/articles/76915) to ensure your service complies with our guidelines. In particular, you should:
* Always get a user’s explicit consent before sending them [automated replies or messages](https://twittercommunity.com/t/policy-clarification-automated-replies-and-mentions/94444)
* Immediately respect user requests to opt-out of being contacted by you
* Never perform bulk, aggressive, or spammy actions, including [bulk following](https://twittercommunity.com/t/policy-clarification-aggressive-following-and-inorganic-following-behavior/92769)
* Never post identical or substantially similar content across [multiple accounts](https://blog.x.com/developer/en_us/topics/tips/2018/automation-and-the-use-of-multiple-accounts.html)
## Sensitive information
You should be careful about using X data to derive or infer potentially sensitive characteristics about X users. Never derive or infer, or store derived or inferred, information about a X user’s:
* Health (including pregnancy)
* Negative financial status or condition
* Political affiliation or beliefs
* Racial or ethnic origin
* Religious or philosophical affiliation or beliefs
* Sex life or sexual orientation
* Trade union membership
* Alleged or actual commission of a crime
Aggregate analysis of X content that does not store any personal data (for example, user IDs, usernames, and other identifiers) is permitted, provided that the analysis also complies with applicable laws and all parts of the Developer Agreement and Policy.
## Off-X matching
Off-X matching involves associating X content, including a X username or user ID, with a person, household, device, browser, or other off-X identifier. One example would be associating a X username with a business’s customer records (i.e. “John Doe” in your customer record is matched to @johndoe on X).
We want people to feel comfortable to create a separate and, if they choose, pseudonymous identity on X. If you intend to associate any information about a X user with an off-X identifier, we require that you get express, opt-in consent from the user before making the association. For example, you could get this consent if the user shares their X handle directly with you as part of a signup process for your service.
In situations in which you do not have a user’s express, opt-in consent to link their X identity to an off-X identifier, we require that any connection you draw be based only on information that a user would reasonably expect to be used for that purpose. If a user would be surprised to learn that you are using information they provided to link their X account to an identity off of X, don’t do it. In addition, absent a person’s express opt-in consent you may only attempt to match your records about someone to a X identity based on:
* **Information provided directly to you by the user.** Records about individuals with whom you have no prior relationship, including data about individuals obtained from third parties, do not meet this standard; and/or
* **Public data.** “Public data” in this context refers to:
* Information about a user which you obtained from a public, generally-available resource (such as a directory of members of a professional association)
* Information on X about a user which is publicly available, including:
* Posts
* Profile information, including a user’s bio and publicly-stated location
* Display name and username
## Redistribution of X content
If you need to share X content you obtained via the X APIs with another party, the best way to do so is by sharing Post IDs, Direct Message IDs, and/or User IDs, which the end user of the content can then rehydrate (i.e. request the full Post, User, or Direct Message content) using the X APIs. This helps ensure that end users of X content always get the most current information directly from us.
We permit limited redistribution of hydrated X content via non-automated means. If you choose to share hydrated X content with another party in this way, you may only share up to 50,000 hydrated public Post Objects and/or User Objects per recipient, per day, and should not make this data publicly available (for example, as an attachment to a blog post or in a public Github repository).
There are a few other points to keep in mind about redistributing X content:
* You may only distribute up to a total of 1,500,000 Post IDs to a single entity within a 30 day period unless you’ve received prior express written permission from X.
* Individuals redistributing Post IDs and/or User IDs on behalf of an academic institution for the sole purpose of non-commercial research are permitted to redistribute an unlimited number of Post IDs and/or User IDs.
* To request permission to share X content as outlined above, please use the API Policy support form.
To the extent you are permitted to distribute X content to a third party, note that this content remains subject to the Developer Agreement and Policy, and those third parties must agree to the X [Terms of Service](https://x.com/en/tos), [Privacy Policy](https://x.com/en/privacy), [Developer Agreement](/developer-terms/agreement), and [Developer Policy](/developer-terms/policy) before receiving X content.
## Multiple applications
You are not permitted to register multiple applications for a single use case, or substantially similar or overlapping use cases. Learn more about these policies [here](https://twittercommunity.com/t/policy-clarification-multiple-applications-for-the-same-use-case/92080).
In this context, we define “use case” as a consistent set of analyses, displays, or actions performed via an application. Providing the same service or application to different end users counts as a single use case: however, "white label" versions of a tool or service are not included. If you plan to "white label" versions of your application, you must notify and receive separate approval from us. These rules apply both to applications you register, and to applications registered by the end users of your tool or service; requiring your end users to register applications for the purpose of using your tool or service could result in enforcement actions against you, your applications, your customers, and/or the end users of your tool or service.
The only exception to this rule is to create development (“dev”), staging, and production (“prod”) instances of the same service. Ensure that these applications are clearly labeled (for instance, in the application name or description), and that you do not use development or staging applications for production purposes.
## Measuring the X service
Do not use the X APIs to measure the availability, performance, functionality, or usage of X for benchmarking or competitive purposes. For example, you should never use the X APIs to:
* Calculate aggregate X user metrics, such as the total number of active users or accounts
* Calculate aggregate X Post metrics, such as the total number of Posts per day, or the number of user engagements or account engagements
* Measure or analyze spam or security on X, except as permitted in the [X Rules](https://help.x.com/en/rules-and-policies/twitter-rules)
## Surveillance, privacy, and user protection
At X, protecting and defending the privacy of our users is built into the core DNA of our company — and our developer and data products reflect that commitment. We believe that X data can be a powerful force for good in the world — from saving lives during flooding in Jakarta to helping the USGS track earthquakes to working with the UN to achieve the Sustainable Development Goals. However, we prohibit the use of X data and the X APIs by any entity for surveillance purposes, or in any other way that would be inconsistent with our users' reasonable expectations of privacy. Period.
We describe prohibited uses of our data and developer products in the [Developer Agreement](/developer-terms/agreement), including prohibitions on investigating or tracking X users or their content, as well as tracking, alerting, or monitoring sensitive events (such as protests, rallies, or community organizing meetings).
Other categories of activities prohibited under these terms include (but are not limited to):
* Investigating or tracking sensitive groups and organizations, such as unions or activist groups
* Background checks or any form of extreme vetting
* Credit or insurance risk analyses
* Individual profiling or psychographic segmentation
* Facial recognition
These policies apply to all users of our APIs. Any misuse of the X APIs for these purposes will be subject to enforcement action, which can include suspension and termination of access.
For additional information for law enforcement authorities seeking information about X accounts, visit [https://t.co/le](https://t.co/le).
In addition, at this time, X prohibits any use of the X APIs and/or X Content to fine-tune or train a foundation or frontier model with the exception of [Grok](https://help.x.com/en/using-x/about-grok).
# About the Enterprise API — firehose, streams, and webhooks
Source: https://docs.x.com/enterprise-api/getting-started/about-x-api
Overview of the X Enterprise API, including full firehose access, volume and likes streams, account activity webhooks, custom rate limits, and support.
The Enterprise API provides the highest tier of access to X data. It includes everything available in the standard X API plus exclusive high-volume endpoints, semantic embedding operators for Filtered Stream, custom rate limits, and dedicated account management for organizations that need X data at scale.
***
## What you can do
Everything in the standard X API, plus:
| Capability | Description |
| :------------------------------- | :------------------------------------------------------------------------------------------------------------- |
| **Stream the full firehose** | Access 100% of public posts in real-time with volume streams |
| **Stream all likes** | Full and sampled likes streams in real-time |
| **Advanced filtered streaming** | Powerstream (low-latency keyword filtering) |
| **Semantic embedding operators** | Match posts by meaning (not just keywords) using `embedding:` on Filtered Stream (Enterprise + Embedding tier) |
| **Deep engagement analytics** | Post and media engagement metrics at scale |
| **Account activity events** | Real-time subscriptions for user events (posts, DMs, likes, follows) |
| **Webhook delivery** | Receive filtered stream data via webhooks |
| **Custom rate limits** | Elevated limits tailored to your throughput needs |
| **Dedicated support** | Named account manager and priority issue resolution |
***
## Enterprise-exclusive endpoints
These endpoints are only available with Enterprise access:
Full firehose and language-specific streams for complete real-time coverage.
Stream all likes or sampled likes across the platform.
High-performance filtered streaming with advanced operators.
Post and media analytics for deep engagement insights.
Real-time event subscriptions for user activity.
Filtered stream delivery via webhooks.
***
## All available resources
Enterprise access includes the full set of X API resources:
Search, retrieve, create, and delete posts. Access timelines, threads, and quote posts.
Look up profiles, manage relationships, and access follower data.
Discover live audio conversations and participants.
Send and receive private messages between users.
Create and manage curated lists of accounts.
Access trending topics by location.
***
## API highlights
Request only the data you need. Use `fields` parameters to select specific attributes and `expansions` to include related objects.
```bash theme={null}
curl "https://api.x.com/2/tweets/123?tweet.fields=created_at,public_metrics&expansions=author_id&user.fields=username" \
-H "Authorization: Bearer $TOKEN"
```
[Learn more about fields →](/x-api/fundamentals/fields)
Posts include semantic annotations identifying people, places, products, and topics. Filter streams and searches by topic.
[Learn more about annotations →](/x-api/fundamentals/post-annotations)
Enterprise customers get access to dedicated engagement metrics endpoints for both posts and media, providing deep analytics at scale beyond what standard public metrics offer.
[Learn more about metrics →](/x-api/fundamentals/metrics)
Reconstruct entire conversation threads using `conversation_id`. Track replies across the full thread.
[Learn more about conversation tracking →](/x-api/fundamentals/conversation-id)
Access the edit history of posts, including all previous versions and edit metadata.
[Learn more about edit posts →](/x-api/fundamentals/edit-posts)
***
## Pricing
Enterprise plans are custom-tailored to your organization's needs. Pricing is based on your data volume, endpoint usage, and support requirements.
| Feature | Details |
| :------------------------ | :-------------------------------------------------- |
| **Custom packages** | Tailored to your specific data and throughput needs |
| **Longer-term contracts** | Predictable pricing with committed usage agreements |
| **No post read cap** | Custom or unlimited post read volumes |
| **Dedicated support** | Included with all Enterprise plans |
[Contact sales for pricing](/forms/enterprise-api-interest)
***
## Next steps
Contact our sales team to discuss your needs.
Browse all available endpoints including Enterprise-exclusive ones.
# Getting enterprise access
Source: https://docs.x.com/enterprise-api/getting-started/getting-access
Apply for X Enterprise API access, work with your dedicated account team during onboarding, and get credentials configured for your data volume.
Enterprise access requires an application and onboarding process. Your dedicated account team will help you get set up with credentials and configure your access.
***
## Step 1: Apply for enterprise access
[Fill out the Enterprise interest form](/forms/enterprise-api-interest) with details about your organization and use case.
Our sales team will reach out to understand your data volume, endpoint requirements, and support needs.
Receive a tailored plan with pricing, rate limits, and access levels designed for your use case.
***
## Step 2: Get onboarded
Once your Enterprise plan is in place, your dedicated account manager will help you set up:
Set up your app in the [Developer Console](https://console.x.com) with Enterprise-level access.
Your account manager will help configure rate limits, endpoint access, and any custom settings.
Generate your API keys and tokens for authentication.
***
## Step 3: Save your credentials
You'll receive several credentials depending on your authentication needs:
| Credential | Purpose |
| :------------------------ | :----------------------------------------------------------------------- |
| **API Key & Secret** | Identify your app. Used to generate tokens and sign OAuth 1.0a requests. |
| **Bearer Token** | App-only authentication for reading public data. |
| **Access Token & Secret** | Make requests on behalf of your own account (OAuth 1.0a). |
| **Client ID & Secret** | OAuth 2.0 authentication for user-context requests. |
**Save immediately.** X only displays credentials once. Store them in a password manager or secure vault. If you lose them, regenerate them (which invalidates the old ones).
***
## Which credentials do you need?
Use the **Bearer Token** for simple, read-only access to public data.
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Best for: Searching posts, looking up users, reading trends.
Use **OAuth 2.0** (recommended) or **OAuth 1.0a** to act on behalf of users.
OAuth 2.0 offers fine-grained scopes—request only the permissions you need.
Best for: Posting, liking, following, accessing DMs.
[OAuth 2.0 guide →](/resources/fundamentals/authentication/oauth-2-0/overview)
Use your **Access Token & Secret** to make requests as your own account.
These tokens represent the account that owns the app.
Best for: Testing, personal bots, your own automation.
***
## Credential security best practices
Never hardcode credentials in your source code.
Add credential files to `.gitignore`.
Regenerate credentials periodically as a security measure.
Only request the OAuth permissions your app needs.
***
## Next steps
Call the API with your new credentials.
Understand OAuth 1.0a and OAuth 2.0.
# Important resources for Enterprise API customers
Source: https://docs.x.com/enterprise-api/getting-started/important-resources
Essential resources for X Enterprise API customers, including onboarding guides, account managers, support contacts, status pages, and SDKs.
Bookmark these essential resources for X API development.
***
## Documentation
Complete endpoint documentation with parameters and examples.
Object schemas for posts, users, media, and more.
OAuth 1.0a and OAuth 2.0 implementation guides.
Per-endpoint limits and best practices.
***
## Tools
| Tool | Description |
| :------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------ |
| [Developer Console](https://console.x.com) | Manage apps, credentials, and billing |
| [Postman Collection](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80) | Interactive API testing |
| [Python SDK](/xdks/python/overview) | Official Python library |
| [TypeScript SDK](/xdks/typescript/overview) | Official TypeScript library |
| [OpenAPI Spec](https://api.x.com/2/openapi.json) | Machine-readable API specification |
***
## Learning
Step-by-step guides for common use cases.
Example apps and code samples.
Ideas and inspiration for projects.
Upgrade from v1.1 to v2.
***
## Community and support
Ask questions and share solutions with the community.
FAQs, troubleshooting, and contact options.
Official updates and announcements.
API-specific news and tips.
***
## Stay updated
| Resource | What you'll get |
| :------------------------------------------------------------------- | :----------------------------------- |
| [Changelog](/changelog) | All platform changes and updates |
| [Newsletter](/newsletter) | Monthly roundup of news and features |
| [Forum Announcements](https://devcommunity.x.com/c/announcements/22) | Important platform notices |
| [API Status](https://developer.x.com/status) | Real-time service availability |
Follow [@XDevelopers](https://x.com/XDevelopers) and turn on notifications to catch breaking changes and new features.
***
## Quick reference
### Response structure
All v2 responses follow this structure:
```json theme={null}
{
"data": { ... }, // Primary object(s)
"includes": { ... }, // Expanded objects (if requested)
"meta": { ... }, // Pagination info
"errors": [ ... ] // Partial errors (if any)
}
```
### Common parameters
| Parameter | Use |
| :----------------- | :--------------------------- |
| `tweet.fields` | Request specific post fields |
| `user.fields` | Request specific user fields |
| `expansions` | Include related objects |
| `max_results` | Limit results per page |
| `pagination_token` | Get next/previous page |
### Authentication methods
| Method | Use case |
| :----------- | :-------------------------------------- |
| Bearer Token | Read-only public data |
| OAuth 2.0 | User actions with fine-grained scopes |
| OAuth 1.0a | User actions (legacy, full permissions) |
[Full authentication guide →](/resources/fundamentals/authentication/overview)
# Make your first Enterprise API request
Source: https://docs.x.com/enterprise-api/getting-started/make-your-first-request
Make your first X Enterprise API request, including authentication setup, endpoint selection, sample cURL commands, and response handling tips.
This guide walks you through making your first X API request. You'll need a [developer account with app credentials](/x-api/getting-started/getting-access) before starting.
***
## Quick start with cURL
The fastest way to test the API is with cURL. Let's look up a user:
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Replace `$BEARER_TOKEN` with your actual Bearer Token. You'll get a response like:
```json theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers"
}
}
```
***
## Step-by-step guide
In the [Developer Console](https://console.x.com), navigate to your app and copy the Bearer Token.
Start with one of these beginner-friendly endpoints:
| Endpoint | What it does |
| :------------------------------------------------ | :--------------------------------- |
| [User lookup](/x-api/users/lookup/introduction) | Get user profile by username or ID |
| [Post lookup](/x-api/posts/lookup/introduction) | Get post by ID |
| [Recent search](/x-api/posts/search/introduction) | Search posts from the last 7 days |
Use cURL, Postman, or your preferred HTTP client:
```bash theme={null}
# Look up a user by username
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Responses are JSON. The primary data is in the `data` field:
```json theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers"
}
}
```
***
## Request more data with fields
By default, endpoints return minimal fields. Use the `fields` parameter to request additional data:
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers?user.fields=created_at,description,public_metrics" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Response:
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers",
"created_at": "2013-12-14T04:35:55.000Z",
"description": "The voice of the X Developer Platform",
"public_metrics": {
"followers_count": 570842,
"following_count": 2048,
"tweet_count": 14052,
"listed_count": 1672
}
}
}
```
[Learn more about fields →](/x-api/fundamentals/fields)
***
## More examples
```bash theme={null}
curl "https://api.x.com/2/tweets/1460323737035677698?tweet.fields=created_at,public_metrics" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
```bash theme={null}
curl "https://api.x.com/2/tweets/search/recent?query=from:xdevelopers&tweet.fields=created_at" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
```bash theme={null}
curl "https://api.x.com/2/users/2244994945/tweets?max_results=5" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
***
## Using code instead of cURL
```python theme={null}
import requests
bearer_token = "YOUR_BEARER_TOKEN"
url = "https://api.x.com/2/users/by/username/xdevelopers"
headers = {"Authorization": f"Bearer {bearer_token}"}
response = requests.get(url, headers=headers)
print(response.json())
```
```javascript theme={null}
const bearerToken = "YOUR_BEARER_TOKEN";
const url = "https://api.x.com/2/users/by/username/xdevelopers";
fetch(url, {
headers: { Authorization: `Bearer ${bearerToken}` }
})
.then(res => res.json())
.then(data => console.log(data));
```
For production use, we recommend the official SDKs:
* [Python SDK](/xdks/python/overview)
* [TypeScript SDK](/xdks/typescript/overview)
They handle authentication, pagination, and rate limiting automatically.
***
## Tools for testing
Visual API testing with our collection.
Examples in multiple languages.
Full endpoint documentation.
***
## Troubleshooting
* Check that your Bearer Token is correct
* Ensure the token hasn't been regenerated
* Verify the `Authorization` header format: `Bearer YOUR_TOKEN`
* Your app may not have access to this endpoint
* Some endpoints require user-context authentication (OAuth 1.0a or 2.0)
* Check your app's permissions in the Developer Console
* You've hit a rate limit
* Check the `x-rate-limit-reset` header for when to retry
* Implement exponential backoff in your code
[Full error reference →](/x-api/fundamentals/response-codes-and-errors)
***
## Next steps
Understand OAuth for user-context requests.
Discover what you can build.
Faster development with official libraries.
Ideas for what to create.
# Enterprise API pricing and custom plans
Source: https://docs.x.com/enterprise-api/getting-started/pricing
Enterprise API plans are custom-tailored to your organization's data volume, endpoint usage, and support needs. Contact sales for high-volume pricing.
Enterprise plans are custom-tailored to your organization's needs. Work with a dedicated account team to build a package that matches your data volume, endpoint usage, and support requirements.
***
## How Enterprise pricing works
Pricing is tailored to your specific data volume, endpoint needs, and throughput requirements.
Predictable costs with longer-term agreements and committed usage levels.
Custom or unlimited post read volumes, far beyond the 3 million monthly cap on pay-per-use plans.
A named account manager and priority technical support are included with every Enterprise plan.
***
## What's included
Every Enterprise plan includes access to the full X API plus exclusive Enterprise endpoints:
| Feature | Details |
| :------------------------------- | :-------------------------------------------------------------------------------------------- |
| **All standard endpoints** | Everything available in the pay-per-use X API |
| **Volume streams** | Full firehose and language-specific streams |
| **Likes streams** | Full and sampled likes in real-time |
| **Powerstream** | Advanced filtered streaming |
| **Semantic embedding operators** | `embedding:` operator for semantic matching in Filtered Stream only (requires Embedding tier) |
| **Engagement metrics** | Post and media analytics endpoints |
| **Account Activity** | Real-time user event subscriptions |
| **Stream webhooks** | Filtered stream delivery via webhooks |
| **Custom rate limits** | Elevated limits tailored to your needs |
| **Dedicated support** | Named account manager and priority resolution |
***
## Enterprise vs. pay-per-use
| | Pay-per-use | Enterprise |
| :------------------------------- | :-------------------------- | :----------------------------------------------------------------------- |
| **Pricing model** | Credit-based, pay as you go | Custom contract |
| **Monthly post cap** | 3 million reads | Custom / unlimited |
| **Volume streams** | Not available | Full firehose and language streams |
| **Likes streams** | Not available | Full and sampled likes |
| **Semantic embedding operators** | Not available | `embedding:` operator for Filtered Stream only (requires Embedding tier) |
| **Engagement metrics** | Not available | Post and media analytics |
| **Rate limits** | Standard | Custom / elevated |
| **Support** | Community forum | Dedicated account manager |
| **Commitment** | None | Contract-based |
***
## Monitoring usage
Track your API usage programmatically with the [Usage endpoint](/x-api/usage/introduction):
```bash theme={null}
curl "https://api.x.com/2/usage/tweets" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
This returns daily Post consumption counts, helping you:
* Track consumption against your contract limits
* Generate usage reports for stakeholders
* Identify high-consumption endpoints
* Plan capacity with your account team
***
## Get started
[Apply for Enterprise access](/forms/enterprise-api-interest) and tell us about your use case and data needs.
Our sales team will work with you to build a package that fits your requirements and budget.
Your dedicated account manager will help you set up credentials, configure access, and start building.
***
## Next steps
Contact our sales team to get started.
Monitor usage programmatically.
# X Enterprise API introduction and product overview
Source: https://docs.x.com/enterprise-api/introduction
Enterprise-grade access to the X firehose, volume streams, full-archive search, and PowerTrack with dedicated technical support and custom pricing.
The X API Enterprise plan provides the highest level of access to X data. Get complete firehose coverage, volume streams, semantic embedding operators for Filtered Stream, dedicated account management, and custom rate limits designed for organizations that depend on X data at scale.
Apply for Enterprise access with a dedicated account team.
Explore all available endpoints, including Enterprise-exclusive ones.
Official Python and TypeScript libraries.
***
## Why Enterprise?
Enterprise access includes everything in the pay-per-use X API plus exclusive high-volume endpoints, dedicated support, and custom packages tailored to your needs.
Stream 100% of public posts in real-time. No sampling, no limits. Get every post as it happens.
Access full-volume and language-specific streams, including English, Japanese, Korean, and Portuguese firehoses.
Get a dedicated account manager, personalized technical support, and priority issue resolution.
Higher rate limits and custom-tailored packages to match your throughput requirements.
Access post and media analytics endpoints for deep engagement insights across large datasets.
Stay compliant with real-time compliance event streams for posts, users, and likes.
Match posts by conceptual meaning — not just keywords — using the `embedding:` operator in Filtered Stream (requires Embedding tier).
***
## Enterprise-exclusive endpoints
These endpoints are only available on Enterprise plans:
Full firehose, language-specific streams, and sampled streams.
Stream all likes or sampled likes in real-time.
High-performance filtered streaming with low latency (keyword operators).
Deep analytics for post and media engagement.
Subscribe to real-time user activity events including posts, DMs, likes, and follows.
Receive filtered stream data via webhooks instead of persistent connections.
***
## What you can build
Enterprise access powers the most demanding use cases on X.
Search, retrieve, and publish posts. Access timelines, threads, and quote posts.
Look up users, manage follows, blocks, and mutes.
Find live audio conversations and their participants.
Send and receive private messages.
Create and manage curated lists of accounts.
Access trending topics by location.
***
## Key features
### Complete real-time coverage
Stream 100% of public posts as they happen. No sampling, no gaps. Enterprise firehose access gives you the complete picture of public conversation on X.
Available streams:
* **All posts** - Every public post in real-time
* **English posts** - All English-language posts
* **Japanese posts** - All Japanese-language posts
* **Korean posts** - All Korean-language posts
* **Portuguese posts** - All Portuguese-language posts
* **Sampled streams** - 1% and 10% random samples
[Learn more about volume streams](/x-api/posts/volume-streams/introduction)
### Rich data objects
Access detailed, structured data for posts, users, media, and more:
* **Posts**: Full text, metrics, entities, annotations, conversation threads
* **Users**: Profiles, follower counts, verification status
* **Media**: Images, videos, GIFs with metadata
* **Polls**: Options and vote counts
Customize responses with [fields](/x-api/fundamentals/fields) and [expansions](/x-api/fundamentals/expansions) to get exactly the data you need.
### Filtered stream
Get posts delivered in real-time as they're published. Enterprise adds higher rule limits and the semantic `embedding:` operator (in Filtered Stream only) to match posts by meaning (not just keywords).
```bash theme={null}
# Add a rule
curl -X POST "https://api.x.com/2/tweets/search/stream/rules" \
-H "Authorization: Bearer $TOKEN" \
-d '{"add": [{"value": "from:xdevelopers"}]}'
# Connect to stream
curl "https://api.x.com/2/tweets/search/stream" \
-H "Authorization: Bearer $TOKEN"
```
[Learn more about filtered stream](/x-api/posts/filtered-stream/introduction)
### Full-archive search
Search the complete history of public posts back to 2006. Build queries with operators for users, keywords, dates, and more.
```bash theme={null}
curl "https://api.x.com/2/tweets/search/all?query=AI%20lang:en" \
-H "Authorization: Bearer $TOKEN"
```
### Engagement metrics
Access deep engagement analytics including impressions, likes, reposts, replies, video views, and media-level metrics.
[Learn more about search](/x-api/posts/search/introduction)
***
## Enterprise vs. pay-per-use
| Feature | Pay-per-use | Enterprise |
| :--------------------- | :---------------------- | :-------------------------------------------------------------------- |
| **Post search** | Recent and full-archive | Recent and full-archive |
| **Filtered stream** | Up to 1,000 rules | 5,000+ rules + semantic `embedding:` operators (Filtered Stream only) |
| **Volume streams** | - | Full firehose and language streams |
| **Likes streams** | - | Full and sampled likes |
| **Powerstream** | - | Advanced filtered streaming |
| **Engagement metrics** | - | Post and media analytics |
| **Account Activity** | - | Real-time user event subscriptions |
| **Monthly post cap** | 3 million reads | Custom / unlimited |
| **Rate limits** | Standard | Custom / elevated |
| **Support** | Community forum | Dedicated account manager |
***
## Get started
[Contact our sales team](/forms/enterprise-api-interest) to discuss your needs and get a custom package.
Your dedicated account manager will help you set up credentials and configure your access.
Use the same modern v2 API endpoints plus Enterprise-exclusive endpoints for your integration.
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
***
## Tools & libraries
Official Python library with async support.
Official TypeScript/JavaScript library.
Interactive API explorer.
[Browse all libraries](/tools-and-libraries)
***
## Support
Enterprise customers get a dedicated point of contact for technical and account support.
Get help from the community and X team.
# Enterprise data customers
Source: https://docs.x.com/enterprise/customer-directory
Directory of enterprise customers using the X API for social listening, research, financial analysis, public safety, brand monitoring, and other use cases.
## Discover companies that use X data to help power innovation
Our enterprise data customers receive commercial-level access to APIs and dedicated account and developer support. Apply for enterprise API access to get the highest level of access and reliability.
[Apply for enterprise access →](/forms/enterprise-api-interest)
## X Official Partners
Work with a trusted X Official Partner to expand what's possible for your business. Each Official Partner has been selected for the program after an extensive evaluation, and represents excellence, value, and trust.
[Check our partners →](https://partners.x.com/en)
## Enterprise customers listing
# X Official Partner
Source: https://docs.x.com/enterprise/partner-directory
Directory of X Official Partners offering tools and services built on the X API, including analytics, content moderation, ad management, and more.
## Build your business with X Official Partners
###### Tap into the public conversation on X and turn insights into action with solutions from our partners.
## Work with a trusted X Official Partner to expand what's possible for your business
Our partners are vetted for excellence and can provide technology to help you:
* Understand consumer trends and preferences
* Collect and analyze product and service feedback
* Engage with customers and resolve issues
* Be alerted to breaking news and events
* Create, publish, and analyze content across social channels
* And more!
## Discover the right Official Partner for your business
### Official Partners represent excellence, value, and trust
Each Official Partner has been selected for the program after an extensive evaluation. Our partners are continuously reviewed by X, as this invitation-only program holds its members to the highest performance standards, in order to deliver great experiences for brands.
## See our partners' impressive work
# Ads API Access Form
Source: https://docs.x.com/forms/ads-api-access
Request access to the X Ads API by submitting your details, including intended use case and app information, for review and approval.
# Application for Trial Enterprise Access
Source: https://docs.x.com/forms/application-trial
Apply for trial access to the X Enterprise API. Submit company information, intended use cases, and contact details to request an evaluation environment.
# Billing support form
Source: https://docs.x.com/forms/billing-support
Contact X API billing support for help with invoices, payment methods, subscription changes, refunds, plan upgrades, and account-related billing issues.
Get billing support for Self-serve and Enterprise API subscriptions.
# Enterprise Access Form
Source: https://docs.x.com/forms/enterprise-api-interest
Request access to the X Enterprise API by submitting company details, intended use case, expected data volume, and contact information for review.
# Government End User Request Form
Source: https://docs.x.com/forms/government-end-user-request
Government and public sector form to request X API access, providing agency details, intended use case, and compliance information for review.
# Survey: Product Tracks & Commercial Use
Source: https://docs.x.com/forms/survey
Share feedback about your X API product track, commercial use case, integration plans, and developer experience to help guide future platform changes.
# Initial use case application for new X API customers
Source: https://docs.x.com/forms/use-case/initial
Initial application form for prospective customers to request access to X API enterprise products by describing the intended use case and integration plan.
# Use case modification request for X API customers
Source: https://docs.x.com/forms/use-case/modification
Form for existing X API enterprise customers to request modifications to a previously approved use case, including changes to data products or workflows.
# Public sector use case request for X API customers
Source: https://docs.x.com/forms/use-case/public-sector
Form for existing public-sector X API customers, including government agencies, to submit a request related to a contracted enterprise data use case.
# Upgrade your enterprise account and add data products
Source: https://docs.x.com/forms/use-case/upgrade
Form for existing X API enterprise customers to upgrade their account and add new data products such as Search, Filtered Stream, or Account Activity.
# OAuth API reference index
Source: https://docs.x.com/fundamentals/authentication/api-reference
Reference index of X authentication endpoints across OAuth 1.0a and OAuth 2.0, including request tokens, authorize, access tokens, and token revocation.
### OAuth 1.0a
| | |
| :-------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- |
| **Purpose** | Method |
| Step 1 of the 3-legged OAuth flow and Sign in with X Allows a Consumer application to obtain an OAuth Request Token to request user authorization. | [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token) |
| Step 2 of the 3-legged OAuth flow and Sign in with X Allows a Consumer application to use an OAuth Request Token to request user authorization. | [GET oauth/authenticate](/resources/fundamentals/authentication/api-reference#get-oauth-authenticate) |
| Step 2 of the 3-legged OAuth flow and Sign in with X Allows a Consumer application to use an OAuth Request Token to request user authorization. | [GET oauth/authorize](/resources/fundamentals/authentication/api-reference#get-oauth-authorize) |
| Step 3 of the 3-legged OAuth flow and Sign in with X Allows a Consumer application to exchange the OAuth Request Token for an OAuth Access Token. | [POST oauth/access\_token](/resources/fundamentals/authentication/api-reference#post-oauth-access-token) |
| Allows a registered application to revoke an issued OAuth Access Token. | [POST oauth/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth-invalidate-token) |
### OAuth 2.0 Bearer Token
| | |
| :----------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
| **Purpose** | Method |
| Allows a registered App to generate an OAuth 2 app-only Bearer Token, which can be used to make API requests on an App's behalf, without user context. | [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token) |
| Allows a registered App to revoke an issued OAuth 2 app-only Bearer Token. | [POST oauth2/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth2-invalidate-token) |
### POST oauth/request\_token
Allows a Consumer application to obtain an OAuth Request Token to request user authorization. This method fulfills [Section 6.1](https://oauth.net/core/1.0/#auth_step1) of the [OAuth 1.0 authentication flow](http://oauth.net/core/1.0/#anchor9).
**We require you use HTTPS for all OAuth authorization steps.**
**Usage Note:** Only ASCII values are accepted for the `oauth_nonce`
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth/request_token`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :--- |
| Response formats | JSON |
| Requires authentication? | No |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| Name | Required | Description | Example |
| :-------------------- | :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------- |
| oauth\_callback | required | For OAuth 1.0a compliance this parameter is **required** . The value you specify here will be used as the URL a user is redirected to should they approve your application's access to their account. Set this to `oob` for out-of-band pin mode. This is also how you specify custom callbacks for use in desktop/mobile applications. Always send an `oauth_callback` on this step, regardless of a pre-registered callback.
We require that any callback URL used with this endpoint will have to be configured within the App’s settings on developer.x.com\* | `http://themattharris.local/auth.php` `twitterclient://callback` |
| x\_auth\_access\_type | optional | Overrides the access level an application requests to a users account. Supported values are `read` or `write` . This parameter is intended to allow a developer to register a read/write application but also request read only access when appropriate. | |
Learn more about how to approve your callback URLs on [this page](/resources/fundamentals/developer-apps#callback-urls).
**Please note** - You can view and edit your existing [X apps](/resources/fundamentals/developer-apps) via the [X app dashboard](https://developer.x.com/en/apps) if you are logged into your X account on developer.x.com.
**Example request[](#example-request "Permalink to this headline")**
Request URL: `POST https://api.x.com/oauth/request_token`
Request POST Body: *N/A*
Authorization Header: `OAuth oauth_nonce="K7ny27JTpKVsTgdyLdDfmQQWVLERj2zAK5BslRsqyw", oauth_callback="http%3A%2F%2Fmyapp.com%3A3005%2Ftwitter%2Fprocess_callback", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1300228849", oauth_consumer_key="OqEqJeafRSF11jBMStrZz", oauth_signature="Pc%2BMLdv028fxCErFyi8KXFM%2BddU%3D", oauth_version="1.0"`
Response: `oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik&oauth_token_secret=Kd75W4OQfb2oJTV0vzGzeXftVAwgMnEK9MumzYcM&oauth_callback_confirmed=true`
### GET oauth/authorize
Allows a Consumer application to use an OAuth Request Token to request user authorization. This method fulfills [Section 6.2](http://oauth.net/core/1.0/#auth_step2) of the [OAuth 1.0 authentication flow](http://oauth.net/core/1.0/#anchor9). Desktop applications must use this method (and cannot use [GET oauth / authenticate](/resources/fundamentals/authentication/api-reference#get-oauth-authenticate)).
**Usage Note:** An `oauth_callback` is never sent to this method, provide it to [POST oauth / request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token) instead.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth/authorize`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :--- |
| Response formats | JSON |
| Requires authentication? | Yes |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| | | | | |
| :----------- | :------- | :-------------------------------------------------------------------------------------------- | :------------ | :------ |
| Name | Required | Description | Default Value | Example |
| force\_login | optional | Forces the user to enter their credentials to ensure the correct users account is authorized. | | |
| screen\_name | optional | Prefills the username input box of the OAuth login screen with the given value. | | |
**Example request[](#example-request "Permalink to this headline")**
Send the user to the `oauth/authorize` step in a web browser, including an oauth\_token parameter:
`https://api.x.com/oauth/authorize?oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik`
### GET oauth/authenticate
Allows a Consumer application to use an OAuth `request_token` to request user authorization.
This method is a replacement of [Section 6.2](http://oauth.net/core/1.0/#auth_step2) of the [OAuth 1.0 authentication flow](http://oauth.net/core/1.0/#anchor9) for applications using the callback authentication flow. The method will use the currently logged in user as the account for access authorization unless the `force_login` parameter is set to `true`.
This method differs from [GET oauth / authorize](/resources/fundamentals/authentication/api-reference#get-oauth-authorize) in that if the user has already granted the application permission, the redirect will occur without the user having to re-approve the application. To realize this behavior, you must enable the *Use Sign in with X* setting on your [application record](https://developer.x.com/apps).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth/authenticate`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :--- |
| Response formats | JSON |
| Requires authentication? | Yes |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| | | | | |
| :----------- | :------- | :-------------------------------------------------------------------------------------------- | :------------ | :------ |
| Name | Required | Description | Default Value | Example |
| force\_login | optional | Forces the user to enter their credentials to ensure the correct users account is authorized. | | *true* |
| screen\_name | optional | Prefills the username input box of the OAuth login screen with the given value. | | |
**Example request[](#example-request "Permalink to this headline")**
Send the user to the `oauth/authenticate` step in a web browser, including an oauth\_token parameter:
`https://api.x.com/oauth/authenticate?oauth_token=Z6eEdO8MOmk394WozF5oKyuAv855l4Mlqo7hhlSLik`
### POST oauth/access\_token
Allows a Consumer application to exchange the OAuth Request Token for an OAuth Access Token. This method fulfills [Section 6.3](http://oauth.net/core/1.0/#auth_step3) of the [OAuth 1.0 authentication flow](http://oauth.net/core/1.0/#anchor9).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth/access_token`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :--- |
| Response formats | JSON |
| Requires authentication? | Yes |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| | | | | |
| :-------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :------ |
| Name | Required | Description | Default Value | Example |
| oauth\_token | required | The oauth\_token here must be the same as the oauth\_token returned in the request\_token step. | | |
| oauth\_verifier | required | If using the OAuth web-flow, set this parameter to the value of the *oauth\_verifier* returned in the callback URL. If you are using out-of-band OAuth, set this value to the pin-code. For OAuth 1.0a compliance this parameter is **required**. OAuth 1.0a is strictly enforced and applications not using the *oauth\_verifier* will fail to complete the OAuth flow. | | |
**Example request[](#example-request "Permalink to this headline")**
`POST https://api.x.com/oauth/access_token?oauth_token=qLBVyoAAAAAAx72QAAATZxQWU6P&oauth_verifier=ghLM8lYmAxDbaqL912RZSRjCCEXKDIzx`
From PIN-based `POST https://api.x.com/oauth/access_token?oauth_token=9Npq8AAAAAAAx72QBRABZ4DAfY9&oauth_verifier=4868795`
**Example response[](#example-response "Permalink to this headline")**
`oauth_token=6253282-eWudHldSbIaelX7swmsiHImEL4KinwaGloHANdrY&oauth_token_secret=2EEfA6BG5ly3sR3XjE0IBSnlQu4ZrUzPiYTmrkVU&user_id=6253282&screen_name=xapi`
### POST oauth/invalidate\_token
Allows a registered application to revoke an issued OAuth access\_token by presenting its client credentials. Once an access\_token has been invalidated, new creation attempts will yield a different Access Token and usage of the invalidated token will no longer be allowed.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/1.1/oauth/invalidate_token`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :-------------------------------------------------------------------------- |
| Response formats | JSON |
| Requires authentication? | Yes - User context with the access tokens that you would like to invalidate |
| Rate limited? | Yes |
**Example request[](#example-request "Permalink to this headline")**
```bash theme={null}
curl --request POST
--url 'https://api.x.com/1.1/oauth/invalidate_token.json'
--header 'authorization: OAuth oauth_consumer_key="CLIENT_KEY",
oauth_nonce="AUTO_GENERATED_NONCE", oauth_signature="AUTO_GENERATED_SIGNATURE",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="AUTO_GENERATED_TIMESTAMP",
oauth_token="ACCESS_TOKEN", oauth_version="1.0"'
```
**Example response[](#example-response "Permalink to this headline")**
```bash theme={null}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 127
...
{"access_token":"ACCESS_TOKEN"}
```
**Example error response after token has been invalidated[](#example-error-response-after-token-has-been-invalidated "Permalink to this headline")**
```bash theme={null}
HTTP/1.1 401 Authorization Required
...
{"errors": [{
"code": 89,
"message": "Invalid or expired token."}
]}
```
### POST oauth2/token
Allows a registered application to obtain an OAuth 2 Bearer Token, which can be used to make API requests on an application's own behalf, without a user context. This is called [Application-only authentication](/resources/fundamentals/authentication/oauth-2-0/application-only).
A Bearer Token may be invalidated using oauth2/invalidate\_token. Once a Bearer Token has been invalidated, new creation attempts will yield a different Bearer Token and usage of the previous token will no longer be allowed.
Only one bearer token may exist outstanding for an application, and repeated requests to this method will yield the same already-existent token until it has been invalidated.
Successful responses include a JSON-structure describing the awarded Bearer Token.
Tokens received by this method should be cached. If attempted too frequently, requests will be rejected with an HTTP 403 with code 99.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth2/token`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :-------------------------------------------------------------------------------------- |
| Response formats | JSON |
| Requires authentication? | Yes - Basic auth with your API key as your username and API key secret as your password |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| | | | | |
| :---------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :-------------------- |
| Name | Required | Description | Default Value | Example |
| grant\_type | required | Specifies the type of grant being requested by the application. At this time, only *client\_credentials* is allowed. See [Application-Only Authentication](/resources/fundamentals/authentication/oauth-2-0/application-only) for more information. | | *client\_credentials* |
**Example request[](#example-request "Permalink to this headline")**
```bash theme={null}
POST /oauth2/token HTTP/1.1
Host: api.x.com
User-Agent: My X App v1.0.23
Authorization: Basic eHZ6MWV2R ... o4OERSZHlPZw==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant_type=client_credentials
```
**Example response:**
```bash theme={null}
HTTP/1.1 200 OK
Status: 200 OK
Content-Type: application/json; charset=utf-8
...
Content-Encoding: gzip
Content-Length: 140
{"token_type":"bearer","access_token":"AAAA%2FAAA%3DAAAAAAAA"}
```
### POST oauth2/invalidate\_token
Allows a registered application to revoke an issued oAuth 2.0 Bearer Token by presenting its client credentials. Once a Bearer Token has been invalidated, new creation attempts will yield a different Bearer Token and usage of the invalidated token will no longer be allowed.
Successful responses include a JSON-structure describing the revoked Bearer Token.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://api.x.com/oauth2/invalidate_token`
**Resource Information[](#resource-information "Permalink to this headline")**
| | |
| :----------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Response formats | JSON |
| Requires authentication? | Yes - [oAuth 1.0a](/resources/fundamentals/authentication/oauth-1-0a) with the application's consumer API keys and the application owner's access token & access token secret |
| Rate limited? | Yes |
**Parameters[](#parameters "Permalink to this headline")**
| Name | Required | Description |
| :------------ | :------- | :-------------------------------------------------------------- |
| access\_token | required | The value of the bearer token that you would like to invalidate |
**Example request[](#example-request "Permalink to this headline")**
```bash theme={null}
curl --request POST
--url 'https://api.x.com/oauth2/invalidate_token?access_token=AAAA%2FAAA%3DAAAAAAAA'
--header 'authorization: OAuth oauth_consumer_key="CLIENT_KEY",
oauth_nonce="AUTO_GENERATED_NONCE", oauth_signature="AUTO_GENERATED_SIGNATURE",
oauth_signature_method="HMAC-SHA1", oauth_timestamp="AUTO_GENERATED_TIMESTAMP",
oauth_token="ACCESS_TOKEN", oauth_version="1.0"'
```
**Example response[](#example-response "Permalink to this headline")**
```
Status: 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 135
...
{
"access_token": "AAAA%2FAAA%3DAAAAAAAA"
}
```
# Basic authentication
Source: https://docs.x.com/fundamentals/authentication/basic-auth
Use HTTP Basic authentication to access X enterprise APIs like PowerTrack, Decahose, and Search by sending your email and password over HTTPS.
## Basic authentication
Many of X's enterprise APIs require the use of HTTP Basic Authentication. To make a successful request to an API that requires Basic Authentication, you must pass a valid email address and password combination as an authorization header for each request. The email and password combination are the same ones that you will use to access the [enterprise API console](https://console.gnip.com/), and can be edited from within this console.
When building a request using Basic Authentication, make sure you add the Authentication: Basic HTTP header with encoded credentials over HTTPS.
In the following cURL request example, you would replace `` and `` with your credentials before sending the request:
```bash theme={null}
curl -v --compressed -u:
"https://gnip-api.x.com/search/30day/accounts//prod/counts.json?query=from%3Axdevelopers"
```
**APIs that require basic authentication:**
* [PowerTrack API](/x-api/enterprise-gnip-2.0/powertrack-api) enterprise
* [Decahose stream API](http://localhost:3000/x-api/enterprise-gnip-2.0/fundamentals/decahose-api) enterprise
* [30-Day Search API](/x-api/enterprise-gnip-2.0/fundamentals/search-api) enterprise
* [Full-Archive Search API](/x-api/enterprise-gnip-2.0/fundamentals/search-api) enterprise
* [Usage API](/x-api/enterprise-gnip-2.0/fundamentals/usage) enterprise
# OAuth FAQ
Source: https://docs.x.com/fundamentals/authentication/faq
Answers to common questions about OAuth 1.0a, OAuth 2.0, access tokens, scopes, and authentication errors when working with the X API.
## General
OAuth is an authentication protocol that allows users to approve an application to act on their behalf without sharing their password. More information can be found at [oauth.net](http://oauth.net/).
You must have a [X app](/resources/fundamentals/developer-apps) to generate access tokens. Learn more about access tokens [here](/resources/fundamentals/authentication#oauth-1-0a-2).
You must have a [developer account](/resources/fundamentals/developer-portal) to create a [X app](/resources/fundamentals/developer-apps). You can sign up for one [here](https://developer.x.com/en/portal/petition/essential/basic-info).
You can view and edit your app from the [X app dashboard](https://developer.x.com/content/developer-twitter/en/apps) if you are logged into your X account on developer.x.com.
## Technical
Access tokens are not explicitly expired. An access token will be invalidated if a user explicitly revokes an application in their X account settings, or if X suspends an application. If an application is suspended, there will be a note in the [X app](/resources/fundamentals/developer-apps) dashboard stating that it has been suspended.
Assume a user’s access token *may* become invalid at any time. If this happens, prompt the user to re-authorize the application. Ensuring that this situation is handled gracefully is important for a good user experience.
Many users trust an application to read their information, but not necessarily change their user profile information or post new statuses. Updating information via the X API - be it name, location or adding a new status - requires an HTTP POST. Any API method that requires an HTTP POST is considered a write method and requires read & write access.
# Best practices
Source: https://docs.x.com/fundamentals/authentication/guides/authentication-best-practices
Your API keys and tokens should be guarded very carefully. These credentials are directly tied to your developer App and those X account that have authorized.
Your API keys and tokens should be guarded very carefully.
These credentials are directly tied to your [developer App](/resources/fundamentals/developer-apps) and those X account that have authorized you to make requests on behalf of them. If your keys are compromised, bad actors could use them to make requests to the X endpoints on behalf of your developer App or its authorized users, which could mean their requests might cause you to hit unexpected rate limits, use up your paid access allotment, or even cause your developer App to be suspended.
The following sections include best practices that should be considered when managing your API keys and tokens.
## Regenerate API keys and tokens
In the event that you believe that your API keys has been exposed, you should regenerate your API keys by following these steps:
1. Navigate to the [Developer Console's "Apps" page](https://developer.x.com/en/portal/projects-and-apps.html).
2. Click on the "Keys and tokens" icon (🗝 ) next to the relevant App.
3. Click on the "Regenerate" button next to the set of keys and tokens that you would like to regenerate.
If you would prefer to regenerate your Access Tokens or Bearer Tokens programmatically, you can do so using our authentication endpoints.
* If you would like to regenerate your Access Tokens, you must invalidate your tokens using the [POST oauth/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth2-invalidate-token) endpoint, then regenerate your tokens using the [3-legged OAuth flow](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens).
* If you would like to regenerate your Bearer Token, you must invalidate your token using the [POST oauth2/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth2-invalidate-token) endpoint, then regenerate your token using the [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token) endpoint.
## Having a central file for your secrets
Having a file such as .ENV file or any other sort of .yaml file to contain your secrets is an option that could be helpful but be sure to have a strong .gitignore file that can prevent you from accidentally committing these to a git repository.
## Environment variables
Writing code that utilizes environment variables might be helpful.
An example of this is as follows written in Python:
```python theme={null}
import os
consumer_key = os.environ.get("CONSUMER_KEY")
consumer_secret = os.environ.get("CONSUMER_SECRET")
```
Inside of your terminal you would want to write something like this:
```bash theme={null}
export CONSUMER_KEY='xxxxxxxxxxxxxxxxxxx'
export CONSUMER_SECRET='xxxxxxxxxxxxxxxxxxxxxxx'
```
## Source code and version control
The most common security mistakes made by developers are having API keys and tokens committed to source code in accessible version control systems like GitHub and BitBucket. Many of these code repositories are publicly accessible. This mistake is made so often in public code repositories that there are lucrative bots that scrape for API keys.
* Use server environment variables. By storing API keys in environment variables, you keep them out of your code and version control. This also allows you to use different keys for different environments easily.
* Use a configuration file excluded from source control. Add the filename to your [.gitignore](https://git-scm.com/docs/gitignore) file to exclude the file from being tracked by version control.
* If you remove the API keys from your code after you have used version control, the API keys are likely still accessible by accessing previous versions of your codebase. Regenerate your API keys, as described in the next section.
## Databases
If you need to store your access tokens in a database, please keep the following in mind:
* Restrict access to the database in a way such that the access tokens are only readable by the owner of the token.
* Restrict edit/write privileges to the database table for access tokens - this should be automated with the key management system.
* Encrypt access tokens before storing in any data stores.
## Password management tools
Password management tools such as 1password or Last Pass can be helpful in keeping your keys and tokens in a secure place. You might want to avoid sharing these inside of a shared team password management tool.
## Web storage & cookies
There are two types of web storage: LocalStorage and SessionStorage. These were created as improvements to using Cookies since the storage capacity for web storage is much higher than Cookie storage. However, there are different pros and cons to each of these storage options.
**Web Storage: LocalStorage**
Anything stored in local web storage is persistent. This means that the data will persist until the data is explicitly deleted. Depending on the needs of your project, you might view this as a positive. However, you should be mindful of using LocalStorage, since any changes/additions to data will be available on all future visits to the webpage in question. We would not usually recommend using LocalStorage, although there may be a few exceptions to this. If you decide to use LocalStorage, it is good to know that it supports the same-origin policy, so all data stored here will only be available via the same origin. An added performance perk of using LocalStorage would be a resulting decrease in client-server traffic since the data does not have to be sent back to the server for every HTTP request.
**Web Storage: SessionStorage**
SessionStorage is similar to LocalStorage, but the key difference is that SessionStorage is not persistent. Once the window (or tab, depending on which browser you are using) that was used to write to SessionStorage is closed, the data will be lost. This is useful in restricting read access to your token within a user session. Using SessionStorage is normally more preferable than LocalStorage when thinking in terms of security. Like LocalStorage, the perks of same-origin policy support and decreased client-server traffic apply to SessionStorage as well.
**Cookies**
Cookies are the more traditional way to store session data. You can set an expiration time for each cookie, which would allow for ease of revocability and restriction of access. However, the client-server traffic would definitely increase when using cookies, since the data is being sent back to the server for every HTTP request. If you decide to use cookies, you need to protect against session hijacking. By default, cookies are sent in plaintext over HTTP, which makes their contents vulnerable to packet sniffing and/or man-in-the-middle attacks where attackers may modify your traffic. You should always enforce HTTPS to protect your data in transit. This will provide confidentiality, integrity (of the data), and authentication. However, if your web application or site is available both through HTTP and HTTPS, you will also want to use the 'Secure' flag on the cookie. This will prevent attackers from being able to send links to the HTTP version of your site to a user and listening in on the resulting HTTP request generated.
Another secondary defense against session hijacking when using cookies would be to validate the user's identity again before any high-impact actions are carried out. One other flag to consider for improving the security of your cookies would be the 'HttpOnly' flag. This flag tells the browser that the cookie in question shall only be accessible from the server specified. Any attempts made by client-side scripts would be forbidden by this flag, therefore helping to protect against most cross-site scripting (XSS) attacks.
# Log in with X
Source: https://docs.x.com/fundamentals/authentication/guides/log-in-with-x
Implement Sign in with X on websites and mobile apps using the OAuth 1.0a request token flow to authenticate users and obtain access tokens.
Use Log in with X, also known as Sign in with X, to place a button on your site or application which allows X users to enjoy the benefits of a registered user account in as little as one click. This works on websites, iOS, mobile, and desktop applications.
## Features
* Ease of use - A new visitor to your site only has to click two buttons in order to log in for the first time.
* X integration - The Log in with X flow can grant authorization to use X APIs on your users' behalf.
* OAuth based - A wealth of client libraries and example code are compatible with the Log in with X API.
## Available for
* Browsers - If your users can access a browser, you can integrate with Log in with X. Learn about the browser sign in flow.
* Mobile devices - Any web-connected mobile device can take advantage of Log in with X. Learn about the mobile sign in flow.
## Implementing Log in with X
The browser and mobile web implementations of Log in with X are based on OAuth. This page demonstrates the requests needed to obtain an access token for the sign in flow.
To use the “Log in with X" flow, please go to your [X app settings](/resources/fundamentals/developer-apps) and ensure that the *"Allow this app to be used to Sign in with X?*” option is enabled.
This page assumes that the reader knows how to sign requests using the OAuth 1.0a protocol. If you want to know how to sign a request, read the [Authorizing a request](/resources/fundamentals/authentication/oauth-1-0a/authorizing-a-request) page.
If you want to check the signing of the requests on this page, the consumer secret used is: L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg. This value is for test purposes and will not work for real requests.
The three steps for implementing Log in with X through obtaining a request token, redirecting a user, and converting a request token into an access token are listed below.
### Step 1: Obtaining a request token
To start a sign-in flow, your [X app](/resources/fundamentals/developer-apps) must obtain a request token by sending a signed message to [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token). The only unique parameter in this request is oauth\_callback, which must be a URL-encoded version of the URL you wish your user to be redirected to when they complete step 2. The remaining parameters are added by the OAuth signing process.
**Note:** Any [callback URL](/resources/fundamentals/developer-apps#callback-urls) that you use with the [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token) endpoint will have to be registered within the [X app settings](/resources/fundamentals/developer-apps) in the [Developer Console](/resources/fundamentals/developer-portal).
**Example request (Authorization header has been wrapped):**
```
POST /oauth/request_token HTTP/1.1
User-Agent: themattharris' HTTP Client
Host: api.x.com
Accept: */*
Authorization:
OAuth oauth_callback="http%3A%2F%2Flocalhost%2Fsign-in-with-twitter%2F",
oauth_consumer_key="cChZNFj6T5R0TigYB9yd1w",
oauth_nonce="ea9ec8429b68d6b77cd5600adbbb0456",
oauth_signature="F1Li3tvehgcraF8DMJ7OyxO4w9Y%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_version="1.0"
```
Your app should examine the HTTP status of the response. Any value other than 200 indicates a failure. The body of the response will contain the oauth\_token, oauth\_token\_secret, and oauth\_callback\_confirmed parameters. Your app should verify that oauth\_callback\_confirmed is true and store the other two values for the next steps.
**Example response (response body has been wrapped):**
```
HTTP/1.1 200 OK
Date: Thu, 13 Oct 2011 00:57:06 GMT
Status: 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 146
Pragma: no-cache
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Vary: Accept-Encoding
Server: tfe
oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&
oauth_token_secret=veNRnAWe6inFuo8o2u8SLLZLjolYDmDP7SzL0YfYI&
oauth_callback_confirmed=true
```
### Step 2: Redirecting the user
The next step is to direct the user to X so that they may complete the appropriate flow, as described in Browser sign-in flow below. Direct the user to [GET oauth/authenticate](/resources/fundamentals/authentication/api-reference#get-oauth-authenticate), and the request token obtained in step 1 should be passed as the oauth\_token parameter.
The most seamless way for a website to implement this would be to issue an HTTP 302 redirect as the response to the original “sign in” request. Mobile and desktop apps should open a new browser window or direct to the URL via an embedded web view.
**Example URL to redirect to:**
[https://api.x.com/oauth/authenticate?oauth\_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0](https://api.x.com/oauth/authenticate?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0)
The sign in endpoint will behave in one of three ways depending on the user’s status:
1. **Signed in and approved**: If the user is signed in on x.com and has already approved the calling application, they will be immediately authenticated and returned to the callback URL with a valid OAuth request token. The redirect to x.com is not obvious to the user.
2. **Signed in but not approved**: If the user is signed in to x.com but has not approved the calling application, a request to share access with the calling application will be shown. After accepting the authorization request, the user will be redirected to the callback URL with a valid OAuth request token.
3. **Not signed in**: If the user is not signed in on x.com, they will be prompted to enter their credentials and grant access for the application to access their information on the same screen. Once signed in, the user will be returned to the callback URL with a valid OAuth request token.
Upon a successful authentication, your callback\_url would receive a request containing the oauth\_token and oauth\_verifier parameters. Your application should verify that the token matches the request token received in step 1.
**Request from client’s redirect (querystring parameters wrapped):**
```
GET /sign-in-with-twitter/?
oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&
oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.5 (KHTML, like Gecko) Chrome/16.0.891.1 Safari/535.5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://localhost/sign-in-with-twitter/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
```
### Step 3: Converting the request token to an access token
To render the request token into a usable access token, your application must make a request to the [POST oauth/access\_token](/resources/fundamentals/authentication/api-reference#post-oauth-access-token) endpoint, containing the oauth\_verifier value obtained in step 2. The request token is also passed in the oauth\_token portion of the header, but this will have been added by the signing process.
**Example request (Authorization header wrapped):**
```
POST /oauth/access_token HTTP/1.1
User-Agent: themattharris' HTTP Client
Host: api.x.com
Accept: */*
Authorization: OAuth oauth_consumer_key="cChZNFj6T5R0TigYB9yd1w",
oauth_nonce="a9900fe68e2573b27a37f10fbad6a755",
oauth_signature="39cipBtIOHEEnybAR4sATQTpl2I%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_token="NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0",
oauth_version="1.0"
Content-Length: 57
Content-Type: application/x-www-form-urlencoded
oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY
```
A successful response contains the oauth\_token, oauth\_token\_secret parameters. The token and token secret should be stored and used for future authenticated requests to the X API. To determine the identity of the user, use [GET account/verify\_credentials](https://dev.x.com/rest/reference/get/account/verify_credentials).
**Example response (response body has been wrapped):**
```
HTTP/1.1 200 OK
Date: Thu, 13 Oct 2011 00:57:08 GMT
Status: 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 157
Pragma: no-cache
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Vary: Accept-Encoding
Server: tfe
oauth_token=7588892-kagSNqWge8gB1WwE3plnFsJHAZVfxWD7Vb57p0b4&
oauth_token_secret=PbKfYqSryyeKDWz4ebtY3o5ogNLG11WJuZBc9fQrQo
```
### Log in with X Resources
#### Client libraries
The client libraries listed at [X libraries](/resources/tools-and-libraries) will help implement Log in with X. Use the /oauth/authenticate endpoint, as described in the previous steps.
#### Brand Toolkit
X would prefer your application to use the official [X Brand Toolkit](https://about.x.com/en/who-we-are/brand-toolkit) for consistent branding. Save these assets and use them when creating a 'Login with X' button.
The browser log in flow is appropriate for websites and applications which are able to open or embed a web browser. At a very high level:
* The application renders a “Sign in with X” link or button.
* The user clicks the sign in button.
* The current web browser is redirected to X (or a new browser is opened and directed to X).
* The user completes a login and authorization step at X if needed.
* X redirects back to an URL under the application’s control, passing authorization information for the user.
X keeps track of the authorizations, so for users already signed in to X.com who have authorized the application, no UI is shown - instead, they are automatically redirected back to the application.
### Desktop flow
To demonstrate the flows, pretend the website pictured above (“The greatest website ever created”) has implemented this API, as shown by the Sign in with X button on the landing page.
When the user clicks the Sign in button, the page they see depends on whether they are signed in and whether they have previously allowed the application to access their account.
When the user is signed in to x.com but has not granted access, a list of requested permissions, along with Sign In and Cancel buttons are shown.
When the user is not signed in to x.com input fields for a username and password will be shown. Note that even if the user has already granted access to the application, the list of permissions will still be shown.
After the user inputs valid credentials (if needed) and clicks “Sign In”, X will redirect the user to the website which started the sign in flow.
In the case where the user is already signed in to x.com and has granted access to the website, this redirect happens immediately.
The UI flow for mobile web browsers works exactly like the Browser sign in flow, but is optimized for mobile browsers.
Below are screenshots for the signed in, signed out, and redirect screens:
# Connection to X API using TLS
Source: https://docs.x.com/fundamentals/authentication/guides/tls
Connect securely to the X API over TLS 1.2, with guidance on trusted root stores, certificate revocation checks, and HTTPS verification practices.
TLS connections are required in order to access X API endpoints. Communicating over TLS preserves user privacy and security by protecting information between the user and the X API as it travels across the public Internet. Connections to the X API require TLS version 1.2.
## Verification
### Use an up-to-date root store
It's important that your application or library use a trustworthy and up-to-date root store when verifying the X certificate. Where possible, using the root store provided by your operating system may be the simplest approach here. Alternatively, the [Mozilla (NSS) root store](https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/) is well maintained in a public and transparent manner. Curl also provides [a version of this store in PEM format](https://curl.haxx.se/docs/caextract.html).
X currently issues the bulk of our certs from the [DigiCert High Assurance EV Root CA](https://www.digicert.com/digicert-root-certificates.htm), but this is not true for 100% of X-related certificates and may not hold true forever, so trusting only the currently-used Digicert roots may lead to issues with your app in the future.
### Check CRLs and the OCSP status[](#check-crls-and-the-ocsp-status "Permalink to this headline")
Many applications do not check the Certificate Revocation List for returned certificates or rely on the operating system to do so. Ensure that your application or TLS library is configured to force CRL and OCSP (Online Certificate Status Protocol) verification before accepting X’s certificate.
### CDNs[](#cdns "Permalink to this headline")
When showing Tweets that contain media, use the `media_url_https` attribute for the HTTPS URLs to use when showing images. In the future, all URLs served from API endpoints will provide HTTPS paths.
## Provide an indication of security status
If possible, you should show an indication of the current status between your application and X. Some web browsers indicate this by offering a Lock Icon, while others indicate the current connection state with descriptive messaging.
# X API v2 authentication mapping
Source: https://docs.x.com/fundamentals/authentication/guides/v2-authentication-mapping
The following chart illustrates which v2 endpoints map to what authentication methods. Documentation for the X developer platform covering v2 authentication.
The following chart illustrates which v2 endpoints map to what authentication methods.
| | | | |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :-------------------------- | :---------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| **Endpoint** | **OAuth 1.0a User Context** | **OAuth 2.0** **App Only ** | **OAuth 2.0 Authorization Code with PKCE** |
| [Tweet lookup](/x-api/posts/lookup/introduction)
Scope |
# API Key and Secret
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/api-key-and-secret
Learn what the X API Key and Secret (consumer key and secret) are, how to create them in the Developer Portal, and how to regenerate or rotate them.
### API Key and Secret
The API Key and Secret (also known as Consumer Key and Secret) are the most fundamental credentials required to access the X API. These credentials act as the username and password for your X App, and are used by the X API to understand which App requests are coming from.
These credentials can be used by [authentication endpoints](/resources/fundamentals/authentication/api-reference) to generate additional credentials, such as [user Access Tokens and Secrets](/resources/fundamentals/authentication/oauth-1-0a/api-key-and-secret), and [Bearer Tokens](/resources/fundamentals/authentication/oauth-2-0/bearer-tokens). You also need to use these credentials along with Access Tokens and other authorization parameters to [authorize requests](/resources/fundamentals/authentication/oauth-1-0a/authorizing-a-request) that require OAuth 1.0a User Context authentication.
#### How to acquire an API Key and Secret
To acquire a X API Key and Secret, please follow these steps:
1. [Sign up for a X developer account](https://developer.x.com/en/apply-for-access)
2. Create a [X App](/resources/fundamentals/developer-apps) within the [Developer Console](/resources/fundamentals/developer-portal). Note that if you would like to use [X API v2](/x-api/introduction), you must use keys and tokens from a developer App.
When you create your X App, you will be presented with your API Key and Secret, along with a Bearer Token. Please note that we only display these credentials once, so make sure to save them in your password manager or somewhere secure.
We have more recommendations on how to handle your keys and tokens within our [authentication best practices](/resources/fundamentals/authentication/guides/authentication-best-practices) page, including details on what you should do if your credentials have been compromised.
#### How to find and regenerate your API Key and Secret after App creation
If you've already created an App and need to find or regenerate your API Key and Secret, please follow these steps:
1. Navigate to the Developer Console
2. Expand the 'Apps' dropdown in the sidenav
3. Open the App which is associated with the API Key and Secret that you would like to find or regenerate
4. Navigate to the Keys and tokens tab
From there, you will find all of the credentials associated with your App.
#### How to use your API Key and Secret
If you are just exploring the X Developer Platform, we recommend that you use a [tool or library](/resources/tools-and-libraries) to see what’s available on the platform. These tools handle authentication gracefully, and can save you a lot of time and frustration. We specifically recommend [getting started with Postman](/tutorials/postman-getting-started) or [Insomnia](https://insomnia.rest/) for beginner developers.
If you are interested in building a request from scratch, please read our guide on [authorizing an OAuth 1.0a request](/resources/fundamentals/authentication/oauth-1-0a/authorizing-a-request).
# Authorizing a request
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/authorizing-a-request
Build an OAuth 1.0a Authorization header to sign X API requests, including the consumer key, nonce, signature, timestamp, token, and version fields.
### Authorizing a request
The purpose of this document is to show you how to modify HTTP requests for the purpose of sending authorized requests to the X API.
All of X's APIs are based on the HTTP protocol. This means that any software you write which uses X's APIs sends a series of structured messages to X’s servers. For example, a request to post the text “**Hello Ladies + Gentlemen, a signed OAuth request!**” as a Tweet will look something like this:
```
POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length: 76
Host: api.x.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
```
Any HTTP library should be able to generate and issue the above request with a minimum of difficulty. However, the above request is considered invalid, since there is no way of knowing:
1. Which application is making the request
2. Which user the request is posting on behalf of
3. Whether the user has granted the application authorization to post on the user’s behalf
4. Whether the request has been tampered by a third party while in transit
To allow applications to provide this information, X’s API relies on the [OAuth 1.0a protocol](http://tools.ietf.org/html/rfc5849). At a very simplified level, X’s implementation requires that requests needing authorization contain an additional HTTP Authorization header with enough information to answer the questions listed above. A version of the HTTP request shown above, modified to include this header, looks like this (normally the Authorization header would need to be on one line, but has been wrapped for legibility here):
```
POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Authorization:
OAuth oauth\_consumer\_key="xvz1evFS4wEEPTGEFPHBog",
oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg",
oauth_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D",
oauth\_signature\_method="HMAC-SHA1",
oauth_timestamp="1318622958",
oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb",
oauth_version="1.0"
Content-Length: 76
Host: api.x.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
```
When this request was created, it would have been accepted by the X API as valid.
If this signing process sounds like it is beyond the scope of your integration, consider using [Web Intents](https://dev.x.com/web/intents), which do not need to use OAuth to interact with the X API.
**Collecting parameters**
You should be able to see that the header contains 7 key/value pairs, where the keys all begin with the string “oauth\_”. For any given X API request, collecting these 7 values and creating a similar header will allow you to specify authorization for the request. How each value was generated is described below:
**Consumer key**
The oauth\_consumer\_key identifies which application is making the request. Obtain this value from the settings page for your [X app](/resources/fundamentals/developer-apps) in the [Developer Console](/resources/fundamentals/developer-portal).
| | |
| :------------------- | :--------------------- |
| oauth\_consumer\_key | xvz1evFS4wEEPTGEFPHBog |
**Nonce**
The oauth\_nonce parameter is a unique token your application should generate for each unique request. X will use this value to determine whether a request has been submitted multiple times. The value for this request was generated by base64 encoding 32 bytes of random data, and stripping out all non-word characters, but any approach which produces a relatively random alphanumeric string should be OK here.
| | |
| :----------- | :----------------------------------------- |
| oauth\_nonce | kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg |
**Signature**
The oauth\_signature parameter contains a value which is generated by running all of the other request parameters and two secret values through a signing algorithm. The purpose of the signature is so that X can verify that the request has not been modified in transit, verify the application sending the request, and verify that the application has authorization to interact with the user’s account.
The process for calculating the oauth\_signature for this request is described in [Creating a signature](/resources/fundamentals/authentication/oauth-1-0a/creating-a-signature).
| | |
| :--------------- | :--------------------------- |
| oauth\_signature | tnnArxj06cWHq44gCs1OSKk/jLY= |
**Signature method**
The oauth\_signature\_method used by X is HMAC-SHA1. This value should be used for any authorized request sent to X’s API.
| | |
| :----------------------- | :-------- |
| oauth\_signature\_method | HMAC-SHA1 |
**Timestamp**
The oauth\_timestamp parameter indicates when the request was created. This value should be the number of seconds since the Unix epoch at the point the request is generated, and should be easily generated in most programming languages. X will reject requests which were created too far in the past, so it is important to keep the clock of the computer generating requests in sync with NTP.
| | |
| :--------------- | :--------- |
| oauth\_timestamp | 1318622958 |
**Token**
The oauth\_token parameter typically represents a user’s permission to share access to their account with your application. There are a few authentication requests where this value is not passed or is a different form of token, but those are covered in detail in [Obtaining access tokens](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens). For most general-purpose requests, you will use what is referred to as an **access token**.
You can generate a valid [access token](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) for your account on the settings page for your [X app](/resources/fundamentals/developer-apps) on the [Developer Console](/resources/fundamentals/developer-portal).
| | |
| :----------- | :------------------------------------------------- |
| oauth\_token | 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb |
**Version**
The oauth\_version parameter should always be 1.0 for any request sent to the X API.
| | |
| :------------- | :-- |
| oauth\_version | 1.0 |
#### Building the header string
To build the header string, imagine writing to a string named DST.
1. Append the string “OAuth ” (including the space at the end) to DST.
2. For each key/value pair of the 7 parameters listed above:
1. [Percent encode](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) the key and append it to DST.
2. Append the equals character ‘=’ to DST.
3. Append a double quote ‘”’ to DST.
4. [Percent encode](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) the value and append it to DST.
5. Append a double quote ‘”’ to DST.
6. If there are key/value pairs remaining, append a comma ‘,’ and a space ‘ ‘ to DST.
Pay particular attention to the percent encoding of the values when building this string. For example, the oauth\_signature value of tnnArxj06cWHq44gCs1OSKk/jLY= must be encoded as tnnArxj06cWHq44gCs1OSKk%2FjLY%3D.
Performing these steps on the parameters collected above results in the following string:
```
OAuth oauth\_consumer\_key="xvz1evFS4wEEPTGEFPHBog", oauth\_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg", oauth\_signature="tnnArxj06cWHq44gCs1OSKk%2FjLY%3D", oauth\_signature\_method="HMAC-SHA1", oauth\_timestamp="1318622958", oauth\_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb", oauth_version="1.0"
```
This value should be set as the Authorization header for the request.
# Creating a signature
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/creating-a-signature
Generate an OAuth 1.0a HMAC-SHA1 signature for X API requests by collecting parameters, building the signature base string, and signing with your keys.
### Creating a signature
This page explains how to generate an OAuth 1.0a HMAC-SHA1 signature for an HTTP request. This signature will be suitable for passing to the X API as part of an authorized request, as described in [authorizing a request.](/resources/fundamentals/authentication/oauth-1-0a/authorizing-a-request)
The request used to demonstrate signing is a POST to [https://api.x.com/1.1/statuses/update.json](https://api.x.com/1.1/statuses/update.json). The raw request looks like this:
```
POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length: 76
Host: api.x.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
```
**Collecting the request method and URL**
To produce a signature, start by determining the HTTP method and URL of the request. These two are known when creating the request, so they are easy to obtain.
The request method will almost always be GET or POST for X API requests.
| | |
| :---------- | :--- |
| HTTP Method | POST |
The base URL is the URL to which the request is directed, minus any query string or hash parameters. It is important to use the correct protocol here, so make sure that the “https\://” portion of the URL matches the actual request sent to the API.
| | |
| :------- | :--------------------------------------------------------------------------------------- |
| Base URL | [https://api.x.com/1.1/statuses/update.json](https://api.x.com/1.1/statuses/update.json) |
#### Collecting parameters
Next, gather all of the parameters included in the request. There are two such locations for these additional parameters - the URL (as part of the query string) and the request body. The sample request includes a single parameter in both locations:
```
POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent: OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length: 76
Host: api.x.com
status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
```
An HTTP request has parameters that are URL encoded, but you should collect the raw values. In addition to the request parameters, every oauth\_\* parameter needs to be included in the signature, so collect those too. Here are the parameters from [authorizing a request](/resources/fundamentals/authentication/oauth-1-0a/authorizing-a-request):
| | |
| :----------------------- | :------------------------------------------------- |
| status | Hello Ladies + Gentlemen, a signed OAuth request! |
| include\_entities | true |
| oauth\_consumer\_key | xvz1evFS4wEEPTGEFPHBog |
| oauth\_nonce | kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg |
| oauth\_signature\_method | HMAC-SHA1 |
| oauth\_timestamp | 1318622958 |
| oauth\_token | 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb |
| oauth\_version | 1.0 |
These values need to be encoded into a single string, which will be used later on. The process to build the string is very specific:
1. [Percent encode](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) every key and value that will be signed.
2. Sort the list of parameters alphabetically [\[1\]](/resources/fundamentals/authentication/oauth-1-0a/creating-a-signature) by encoded key [\[2\]](/resources/fundamentals/authentication/oauth-1-0a/creating-a-signature).
3. For each key/value pair:
4. Append the encoded key to the output string.
5. Append the ‘=’ character to the output string.
6. Append the encoded value to the output string.
7. If there are more key/value pairs remaining, append a ‘&’ character to the output string.
\[1] The OAuth spec says to sort lexicographically, which is the default alphabetical sort for many libraries.
\[2] In the case of two parameters with the same encoded key, the OAuth spec says to continue sorting based on value. However, X does not accept duplicate keys in API requests
**Parameter string**
The following *parameter string* will be produced by repeating these steps with the parameters collected above:
| status | Hello Ladies + Gentlemen, a signed OAuth request! |
| :----------------------- | :------------------------------------------------- |
| `include_entities` | true |
| `oauth_consumer_key` | xvz1evFS4wEEPTGEFPHBog |
| `oauth_nonce` | kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg |
| `oauth_signature_method` | HMAC-SHA1 |
| `oauth_timestamp` | 1318622958 |
| `oauth_token` | 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb |
| `oauth_version` | 1.0 |
#### Creating the signature base string
The three values collected so far must be joined to make a single string, from which the signature will be generated. This is called the **signature base string** by the OAuth specification.
To encode the HTTP method, base URL, and parameter string into a single string:
1. Convert the HTTP Method to uppercase and set the output string equal to this value.
2. Append the ‘&’ character to the output string.
3. [Percent encode](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) the URL and append it to the output string.
4. Append the ‘&’ character to the output string.
5. [Percent encode](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) the parameter string and append it to the output string.
This will produce the following *signature base string*:
```
POST&https%3A%2F%2Fapi.x.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521
```
Make sure to percent encode the parameter string. The signature base string should contain exactly 2 ampersand ‘&’ characters. The percent ‘%’ characters in the parameter string should be encoded as %25 in the signature base string.
#### Getting a signing key
The last pieces of data to collect are secrets which identify the [X app](/resources/fundamentals/developer-apps) making the request, and the user the request is on behalf of. It is very important to note that these values are incredibly sensitive and should never be shared with anyone.
The value which identifies your app to X is called the **consumer secret** and can be found in the [Developer Console](/resources/fundamentals/developer-portal) by viewing the [app details page](/resources/fundamentals/developer-apps). This will be the same for every request your X app sends.
| | |
| :-------------- | :------------------------------------------ |
| Consumer secret | kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw |
The value which identifies the account your application is acting on behalf of is called the **OAuth token secret**. This value can be obtained in several ways, all of which are described in [obtaining access tokens](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens).
| | |
| :----------------- | :---------------------------------------- |
| OAuth token secret | LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE |
Once again, it is very important to keep these values private to your application. If you feel that your values have been compromised, regenerate your tokens (the tokens on this page have been marked as invalid for real requests).
Both of these values need to be combined to form a **signing key** which will be used to generate the signature. The signing key is simply the [percent encoded](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) token secret:
Note that there are some flows, such as when obtaining a [request token](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens), where the token secret is not yet known. In this case, the signing key should consist of the [percent encoded](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) **consumer secret** followed by an ampersand character ‘&’.
| | |
| :---------- | :------------------------------------------------------------------------------------- |
| Signing key | kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw\&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE |
#### Calculating the signature
Finally, the signature is calculated by passing the signature base string and signing key to the HMAC-SHA1 hashing algorithm. The details of the algorithm are explained as hash\_hmac function.
The output of the HMAC signing function is a binary string. This needs to be base64 encoded to produce the signature string. For example, the output given the base string and signing key given on this page is 2E CF 77 84 98 99 6D 0D DA 90 5D C7 17 7C 75 07 3F 3F CD 4E. That value, when converted to base64, is the OAuth signature for this request:
| | |
| :-------------- | :--------------------------- |
| OAuth signature | Ls93hJiZbQ3akF3HF3x1Bz8/zU4= |
# OAuth Echo
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/oauth-echo
Use OAuth Echo to securely delegate X authentication to a third party media provider for uploads using x-auth-service-provider and verify-credentials headers.
### OAuth Echo
OAuth Echo is a means to securely delegate OAuth authorization with a third party while interacting with an API.
There are four parties involved in this interaction:
* **the User** who is using X through a particular, authorized X application
* **the Consumer**, or the X application that is attempting to interact with the 3rd party media provider (e.g. the photo-sharing site)
* **the Delegator**, or the 3rd party media provider
* **the Service Provider** a.k.a. X itself
Essentially, prepare a request for the delegator to send to the X API on behalf of an application and a user. Add what would otherwise be a signed OAuth request into an HTTP header and ask the delegator to send that request to X after completing the intermediary operation.
Here’s an example: the User wants to upload a photo. The Consumer is going to call upload on the Delegator with a POST. The POST should contain the image, but it should also contain two additional items as HTTP headers:
* `x-auth-service-provider` — effectively, this is the realm that identity delegation should be sent to — in the case of X, set this to [https://api.x.com/1.1/account/verify\_credentials.json](https://api.x.com/1.1/account/verify_credentials.json). iOS5-based X integrations will add an additional application\_id parameter to this URL that will also be used to calculate the oauth\_signature used in x-verify-credentials-authorization.
* `x-verify-credentials-authorization` — Consumer should create all the OAuth parameters necessary so it could call [https://api.x.com/1.1/account/verify\_credentials.json](https://api.x.com/1.1/account/verify_credentials.json) using OAuth in the HTTP header (e.g. it should look like OAuth oauth\_consumer\_key=”...”, oauth\_token=”...”, oauth\_signature\_method=”...”, oauth\_signature=”...”, oauth\_timestamp=”...”, oauth\_nonce=”...”, oauth\_version=”...” ).
Keep in mind that the entire transaction period needs to occur within an amount of time where the `oauth_timestamp` will still be valid.
Alternatively, instead of sending these two parameters in the header, they could be sent in the POST as x\_auth\_service\_provider and x\_verify\_credentials\_authorization — in this case, remember to escape and include the parameters in the OAuth signature base string — similar to encoding parameters in any request. It’s best to use HTTP headers to keep the operations as separate as possible.
The Delegator’s goal, at this point, is to verify that the User is who they say they are before it saves the media. Once the Delegator receives all the data above via its upload method, it should temporarily store the image, and then construct a call to the endpoint specified in the x-auth-service-provider header — in this case, [https://api.x.com/1.1/account/verify\_credentials.json](https://api.x.com/1.1/account/verify_credentials.json), using the same OAuth authentication header provided by the Consumer in the x-verify-credentials-authorization header.
#### OAuth Echo best practices
Use the URL provided by `x-auth-service-provider` to perform the lookup, *not* a hard-coded value. Apple iOS, for example, adds an additional application\_id parameter to all OAuth requests, and its existence should be maintained at each stage of OAuth Echo.
For the OAuth authorization portion, take the header value in x-verify-credentials-authorization, and place that into its own Authorization header for its call to the service provider. For good measure, confirm that the value in `x-auth-service-provider` is what it should be.
* If the Service Provider returns an HTTP 200, then good. The Delegator should permanently store the image, generate a URL, and return it.
* If the Service Provider doesn’t return an HTTP 200, then dump the image, and then return an error back to the Consumer.
# Obtaining Access Tokens using 3-legged OAuth flow
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens
Walk through the 3-legged OAuth 1.0a flow to obtain user access tokens for the X API using request_token, authorize, and access_token endpoints.
### Obtaining access tokens using 3-legged OAuth flow
To perform actions on behalf of another user, you'll need to obtain their access tokens. Access tokens specify the X account the request is made on behalf of, so for you to obtain these they will need to first grant you access. These tokens do not expire but can be revoked by the user at any time.
X allows you to obtain user access tokens through the 3-legged OAuth flow, which allows your application to obtain an **access token** and access token secret by redirecting a user to X and having them authorize your application. This flow is almost identical to the flow described in [implementing Log in with X](/resources/fundamentals/authentication/guides/log-in-with-x), with two exceptions:
* The [GET oauth/authorize](/resources/fundamentals/authentication/api-reference#get-oauth-authorize) endpoint is used instead of [GET oauth/authenticate](/resources/fundamentals/authentication/api-reference#get-oauth-authenticate).
* The user will **always** be prompted to authorize access to your application, even if access was previously granted.
Before you get started, you will need to check your [application's](/resources/fundamentals/developer-apps) permissions and know the consumer keys and callback URL. If you don't have a callback URL or publicly accessible UI, consider using [PIN-based authorization](/resources/fundamentals/authentication/oauth-1-0a/pin-based-oauth), which is intended for applications that cannot access or embed a web browser in order to redirect the user after authorization.
The possible states for the 3-legged sign in interaction are illustrated in the following flowchart:

#### Overview of the process
At a high level, the 3-Legged OAuth process will:
1. Create a request for a consumer application to obtain a request token.
2. Have the user authenticate, and send the consumer application a request token.
3. Convert the request token into a usable user access token.
**Terminology clarification**
In the guide below, you may see different terms referring to the same thing.
**Client credentials:**
* App Key === API Key === Consumer API Key === Consumer Key === Customer Key === `oauth_consumer_key`
* App Key Secret === API Secret Key === Consumer Secret === Consumer Key === Customer Key === `oauth_consumer_secret`
* Callback URL === `oauth_callback`
**Temporary credentials:**
* Request Token === `oauth_token`
* Request Token Secret === `oauth_token_secret`
* oauth\_verifier
**Token credentials:**
* Access token === Token === resulting `oauth_token`
* Access token secret === Token Secret === resulting `oauth_token_secret`
#### Walkthrough steps
**Step 1: [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token)**
Create a request for a consumer application to obtain a request token.
The only unique parameter in this request is oauth\_callback, which must be a [URL encoded](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters) version of the URL you wish your user to be redirected to when they complete step 2. The remaining parameters are added by the OAuth signing process.
Please note - any callback URL that you use with the [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token) endpoint will have to be configured within your [developer App's](/resources/fundamentals/developer-apps) settings in the app details page of Developer Console.
**Request includes:**
`oauth_callback="https%3A%2F%2FyourCallbackUrl.com"`
`oauth_consumer_key="cChZNFj6T5R0TigYB9yd1w" `
Your app should examine the HTTP status of the response. Any value other than 200 indicates a failure. The body of the response will contain the `oauth_token`, `oauth_token_secret`, and `oauth_callback_confirmed` parameters. Your app should verify that `oauth_callback_confirmed` is true and store the other two values for the next steps.
**Response includes**
`oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0`
`oauth_token_secret=veNRnAWe6inFuo8o2u8SLLZLjolYDmDP7SzL0YfYI`
`oauth_callback_confirmed=true`
**Step 2: [GET oauth/authorize](/resources/fundamentals/authentication/api-reference#get-oauth-authorize)**
Have the user authenticate, and send the consumer application a request token.
**Example URL to redirect user to:**
`https://api.x.com/oauth/authorize?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0`
Upon successful authentication, your `callback_url` would receive a request containing the `oauth_token` and `oauth_verifier` parameters. Your application should verify that the token matches the request token received in step 1.
**Request from client’s redirect:**
`https://yourCallbackUrl.com?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY`
**Step 3: [POST oauth/access\_token](/resources/fundamentals/authentication/api-reference#post-oauth-access-token)**
Convert the request token into a usable access token.
To render the request token into a usable access token, your application must make a request to the [POST oauth/access\_token](/resources/fundamentals/authentication/api-reference#post-oauth-access-token) endpoint, containing the `oauth_verifier` value obtained in step 2. The request token is also passed in the `oauth_token` portion of the header, but this will have been added by the signing process.
**Request includes:**
`POST /oauth/access_token`
`oauth_consumer_key=cChZNFj6T5R0TigYB9yd1w`
`oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0`
`oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY`
A successful response contains the `oauth_token`, `oauth_token_secret` parameters. The token and token secret should be stored and used for future authenticated requests to the X API. To determine the identity of the user, use [GET account/verify\_credentials](/resources/fundamentals/authentication/api-reference).
**Response includes:**
`oauth_token=7588892-kagSNqWge8gB1WwE3plnFsJHAZVfxWD7Vb57p0b4`
`oauth_token_secret=PbKfYqSryyeKDWz4ebtY3o5ogNLG11WJuZBc9fQrQo`
**Using these credentials for OAuth 1.0a (application-user) required requests**
Now you've obtained the user access tokens; you can use them to access certain APIs such as [POST statuses/update](/x-api/posts/manage-tweets/introduction) to create Tweets on the users' behalf.
**Request includes:**
`POST statuses/update.json`
`oauth_consumer_key=cChZNFj6T5R0TigYB9yd1w`
`oauth_token=7588892-kagSNqWge8gB1WwE3plnFsJHAZVfxWD7Vb57p0b4`
#### Sample use case
The standard flow is web-based and uses the 3-legged authorization OAuth flow. The screenshots outlined here are part of a sample that you can view the source of at [https://github.com/xdevplatform/twauth-web](https://github.com/xdevplatform/twauth-web).
At some point in your application, you will want to redirect to X in order to authorize your application.
When you redirect to X with the request token, the user will be prompted to authorize your application.
Upon authorizing your application, the user will be redirected to the callback URL provided when you generated the request token. You will use this to obtain the permanent access token for this user and store it locally.
# OAuth 1.0a
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/overview
Overview of OAuth 1.0a user context authentication on X, covering API keys, access tokens, request signing, and tools for making authorized API calls.
## OAuth 1.0a
Many endpoints on the X developer platform use the OAuth 1.0a method to act, or make API requests, on behalf of a X account. For example, if you have a X developer app, you can make API requests on behalf of any X account as long as that user authenticates your app.
Please note: if you aren’t familiar with concepts such as HMAC-SHA1 and percent encoding, we recommend that you check out the "useful tools" section below that lists some API clients that greatly simplify the authentication process.
### Key concepts
#### Signing a request with keys and tokens
You have to sign each API request by passing several generated keys and tokens in an authorization header. To start, you can generate several keys and tokens in your [X developer app’s](/resources/fundamentals/developer-apps) details page, including the following:
| | |
| :------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API key and secret:
`oauth_consumer_key`
`oauth_consumer_secret` | Think of these as the user name and password that represents your X developer app when making API requests. |
| Access token and secret:
`oauth_token`
`oauth_token_secret` | An access token and access token secret are user-specific credentials used to authenticate OAuth 1.0a API requests. They specify the X account the request is made on behalf of.
You can generate your own access token and token secret if you would like your app to make requests on behalf of the same X account associated with your developer account on the [X developer app's](/resources/fundamentals/developer-apps) details page.
If you'd like to generate access tokens for a different user, see "Making requests on behalf of users" below. |
#### Making requests on behalf of users
When creating a signature, you need a set of access tokens that represent the user that you are going to make a request on behalf of.
You can generate a set of access tokens that represents the X account that owns the X developer app from the [app’s details page,](https://developer.x.com/content/developer-twitter/en/apps) but if you are wanting to make a request on behalf of a different X account, that account’s owner must grant access to you by signing in to their account as part of the [3-legged OAuth flow](/resources/fundamentals/authentication#obtaining-access-tokens-using-3-legged-oauth-flow). The output of this process is a set of access tokens (oauth\_token and oauth\_token\_secret) that can be used to make an OAuth 1.0a request.
Once you have these keys and tokens, you can either [create a signature](/resources/fundamentals/authentication#creating-a-signature) from scratch. We don't recommend this unless you know what you are doing, or if you're using one of the tools mentioned below to make a request to an endpoint that requires OAuth 1.0a.
For reference, here is an example of a signed cURL request with all of the generated tokens passed in an authorization header:
```bash theme={null}
curl --request POST \
--url 'https://api.x.com/1.1/statuses/update.json?status=Hello%20world' \
--header 'authorization: OAuth oauth_consumer_key="CONSUMER_API_KEY", oauth_nonce="OAUTH_NONCE", oauth_signature="OAUTH_SIGNATURE", oauth_signature_method="HMAC-SHA1", oauth_timestamp="OAUTH_TIMESTAMP", oauth_token="ACCESS_TOKEN", oauth_version="1.0"' \
```
**Note:** User access tokens are sensitive and should be guarded very carefully. When access tokens are generated, the user they represent is trusting your application to keep them secure. If the security of both API keys and user access tokens are compromised, your application would potentially expose access to private information and account functionality. We encourage you to learn more about [securing keys and access tokens](/resources/fundamentals/developer-apps).
### Useful tools
The process of [signing a request](/resources/fundamentals/authentication#creating-a-signature) is complicated. We recommend that you use an API client library that automatically generates a lot of the authentication token:
| | |
| :------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Postman](https://www.getpostman.com/) | An API client that lets you build and send REST API requests. Read our “[Getting started with Postman](/tutorials/postman-getting-started)” tutorial to learn more about this tool. |
| [Insomnia](https://insomnia.rest/) | Insomnia is a REST API Client with cookie management, environment variables, code generation, and authentication for Mac, Window, and Linux. |
# Percent encoding parameters
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters
Apply RFC 3986 percent encoding to OAuth 1.0a parameters for X API requests, with rules for reserved characters and worked URL encoding examples.
### Percent encoding parameters
Parts of the X API, particularly those dealing with OAuth signatures, require strings to be encoded according to [RFC 3986, Section 2.1](http://tools.ietf.org/html/rfc3986#section-2.1). Since many implementations of URL encoding algorithms are not fully compatible with RFC 3986, bad encodings are a cause of many OAuth signature errors. For this reason, the exact signing algorithm to use is covered on this page.
This page covers the URL encoding process described in [RFC 3986, Section 2.1](http://tools.ietf.org/html/rfc3986#section-2.1). We encourage you to reference that specification in case of any ambiguity or conflict with this document.
#### Encoding a string
The following algorithm assumes you are encoding a string SRC by copying its values byte-by-byte to a string DST.
**Step 1: While SRC contains unread bytes, read the next byte (8 bits) from SRC.** Typically, this is considered a character, but in the case of encodings where a character may be more than one byte (such as UTF-8), just read the first byte.
**Step 2: Check whether the read byte matches any of the following ASCII equivalents.** The following table has been broken down into rows for legibility, but you only need to determine whether the read byte exists in the table at all, not the specific row.
| Name | ASCII characters | Equivalent byte values |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Digits | ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ | 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 |
| Uppercase letters | ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’ | 0x41, 0x42, 0x43, 0x44, 0x45,0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,0x52, 0x53, 0x54, 0x55, 0x56, 0x57,0x58, 0x59, 0x5A |
| Lowercase letters | ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’ | 0x61, 0x62, 0x63, 0x64, 0x65,0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B,0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,0x72, 0x73, 0x74, 0x75, 0x76, 0x77,0x78, 0x79, 0x7A |
| Reserved characters | ‘-‘, ‘.’, ‘\_’, ‘\~’ | 0x2D, 0x2E, 0x5F, 0x7E |
**Step 2b: If the byte is not listed in the above table, continue.** Any other value must be encoded. **Step 2a: If the byte is listed in the above table, copy it into DST and go back to Step 1.** Characters listed in the above table do not need to be escaped, so you will just copy the byte directly.
**Step 3: Write the character ‘%’ to DST.** The percent character ‘%’ (or 0x25 in hex and 00100101 in binary) indicates that the next two bytes will represent an encoded byte.
**Step 4: Write two characters representing the uppercase ASCII-encoded hex value of the current byte to DST.** This is a bit confusing, so here is an example. Pretend the current byte is 0xE6 (11100110 in binary). This corresponds with the UTF-8 encoded value of ‘æ’. To encode this value, write the character ‘E’ (0x45, from the table above) and then the character ‘6’ (0x36) to DST. The last three characters are written should have been “%E6”. Note that if you write a letter such as A,B,C,D,E or F, you must use the uppercase character.
**Step 5: Return to Step 1.** Keep going until the entirety of SRC is copied to DST.
#### Examples
The following examples may be helpful to compare with the output of your own code. You should consider any differences an error. Spaces encoded as “+” characters are an example of incorrect encoding.
| Original string | Encoded string |
| :----------------- | :-------------------------- |
| Ladies + Gentlemen | Ladies%20%2B%20Gentlemen |
| An encoded string! | An%20encoded%20string%21 |
| Dogs, Cats & Mice | Dogs%2C%20Cats%20%26%20Mice |
| ☃ | %E2%98%83 |
# PIN-based authorization
Source: https://docs.x.com/fundamentals/authentication/oauth-1-0a/pin-based-oauth
Use the PIN-based OAuth flow for X apps that cannot embed a browser, like CLI tools and game consoles, by entering a numeric PIN as the oauth_verifier.
### PIN-based authorization
The PIN-based OAuth flow is a version of the [3-legged OAuth](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) process and is intended for applications that cannot access or embed a web browser to redirect the user after authorization. Examples of such applications would be command-line applications, embedded systems, game consoles, and certain types of mobile apps.
PIN-based OAuth flow is initiated by an app in the `request_token` with the `oauth_callback` set to `oob`. The term `oob` means out-of-band OAuth. The user still visits X to login or authorize the app, but they will not be automatically redirected to the application upon approving access. Instead, they will see a numerical PIN code, with instructions to return to the application and enter this value.
**Note:** The `callback_url` within the X app settings is still required, even when using PIN-based auth.
#### Implementing the PIN-based OAuth flow
The PIN-based flow is implemented in the same way as [3-legged authorization](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) (and [Sign in with X](/resources/fundamentals/authentication#log-in-with-x)), with the following differences:
1. The value for `oauth_callback` must be set to `oob` during the [POST oauth/request\_token](/resources/fundamentals/authentication/api-reference#post-oauth-request-token) call.
2. After the user is sent to X to authorize your app using either a [GET oauth/authenticate](/resources/fundamentals/authentication/api-reference#get-oauth-authenticate) or [GET oauth/authorize URL](/resources/fundamentals/authentication/api-reference#get-oauth-authorize), they will not be redirected to your `callback_url`, instead they will see a screen with a X generated \~7 digit PIN with directions to enter the PIN into your applications name.
3. The user enters this PIN into your application, and your application uses the PIN number as the `oauth_verifier` in the [POST oauth/access\_token](/resources/fundamentals/authentication/api-reference#post-oauth-access-token) to obtain an access\_token.
**Note:** PIN numbers are not reusable, and the `access_token` obtained should be used for application-user requests.
# App only authentication and OAuth 2.0 Bearer Token
Source: https://docs.x.com/fundamentals/authentication/oauth-2-0/application-only
Authenticate X API requests with OAuth 2.0 App-Only Bearer Tokens for server-to-server, read-only access to public data without a user context.
### App only authentication and OAuth 2.0 Bearer Token
X offers applications the ability to issue authenticated requests on behalf of the application itself, as opposed to on behalf of a specific user. X's implementation is based on the [Client Credentials Grant](http://tools.ietf.org/html/rfc6749#section-4.4) flow of the [OAuth 2 specification](http://tools.ietf.org/html/rfc6749).
Application-only authentication doesn't include any user-context and is a form of authentication where an application makes API requests on its own behalf. This method is for developers that just need read-only access to public information.
You can do application-only authentication using your apps consumer API keys, or by using an App only Access Token (Bearer Token). This means that the only requests you can make to a X API must not require an authenticated user.
With application-only authentication, you can perform actions such as:
* Pull user timelines
* Access friends and followers of any account
* Access lists resources
* Search Tweets
Please note that only [OAuth 1.0a](/resources/fundamentals/authentication/oauth-1-0a/api-key-and-secret) or [OAuth 2.0 Authorization Code Flow](/resources/fundamentals/authentication/oauth-2-0/authorization-code) with PKCE is required to issue requests on behalf of users. The [API reference](/resources/fundamentals/authentication/api-reference) page describes the authentication method required to use an API. You will need user-authentication, user-context, with an [access token](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) to perform the following:
* Post Tweets or other resources
* Search for users
* Use any geo endpoint
* Access Direct Messages or account credentials
* Retrieve user's email addresses
#### Auth Flow
To use this method, you need to use a [App only Access Token](/resources/fundamentals/authentication/oauth-2-0/application-only)(also known as [Bearer Token](/resources/fundamentals/authentication/oauth-2-0/bearer-tokens)). You can generate an App only Access Token (Bearer Token) by passing your consumer key and secret through the [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token) endpoint.
The application-only auth flow follows these steps:
* An application encodes its consumer key and secret into a specially encoded set of credentials.
* An application makes a request to the [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token) endpoint to exchange these credentials for an [App only Access Token](/resources/fundamentals/authentication/oauth-2-0/application-only).
* When accessing the REST API, the application uses the App only Access Token to authenticate.
Because there is no need to sign a request, this approach is much simpler than the standard OAuth 1.0a model.
#### About application-only auth
**Tokens are passwords**
Keep in mind that the consumer key & secret and the App only Access Token (Bearer Token) itself grant access to make requests on behalf of an application. These values should be considered as sensitive as passwords, and must not be shared or distributed to untrusted parties.
**SSL required**
All requests (both to obtain and use the tokens) *must* use HTTPS endpoints. Follow the best practices detailed in [Connecting to X API using TLS](/resources/fundamentals/authentication/guides/tls) — peers should **always** be verified.
**No user-context**
When issuing requests using application-only auth, there is no concept of a "current user". Therefore, endpoints such as [POST statuses/update](/x-api/posts/creation-of-a-post) will not function with application-only auth. See [using OAuth](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) for more information for issuing requests on behalf of a user.
**Rate limiting**
Applications have two kinds of rate limiting pools.
Requests made on behalf of users with access tokens, also known as user-context, depletes from a different rate limiting context than that used in application-only authentication. So, in other words, requests made on behalf of users will not deplete from the rate limits available through app-only auth, and requests made through app-only auth will not deplete from the rate limits used in user-based auth.
Read more about [API Rate Limiting](/x-api/fundamentals/rate-limits) and [review the limits](https://developer.x.com/en/portal/products).
#### Issuing application-only requests
**Step 1: Encode consumer key and secret**
The steps to encode an application’s consumer key and secret into a set of credentials to obtain a Bearer Token are:
1. URL encode the consumer key and consumer secret according to [RFC 1738](http://www.ietf.org/rfc/rfc1738.txt). Note that at the time of writing, this will not actually change the consumer key and secret, but this step should still be performed in case the format of those values changes in the future.
2. Concatenate the encoded consumer key, a colon character ":", and the encoded consumer secret into a single string.
3. [Base64 encode](http://en.wikipedia.org/wiki/Base64) the string from the previous step.
Below are example values showing the result of this algorithm. Note that the consumer secret used in this page is for test purposes and will not work for real requests.
| | |
| :------------------------------------------------------------ | :------------------------------------------------------------------------------------------ |
| Consumer key | xvz1evFS4wEEPTGEFPHBog |
| Consumer secret | L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg |
| RFC 1738 encoded consumer
secret (does not change) | L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg |
| Bearer Token credentials | xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg |
| Base64 encoded Bearer Token credentials | :: eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw== |
**Step 2: Obtain an App only Access Token (Bearer Token)**
The value calculated in step 1 must be exchanged for an App only Access Token by issuing a request to [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token):
* The request must be an HTTP POST request.
* The request must include an `Authorization` header with the value of `Basic .`
* The request must include a `Content-Type` header with the value of `application/x-www-form-urlencoded;charset=UTF-8.`
* The body of the request must be `grant_type=client_credentials`.
**Example request (Authorization header has been wrapped):**
```json theme={null}
POST /oauth2/token HTTP/1.1
Host: api.x.com
User-Agent: My X App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip
grant\_type=client\_credentials
```
If the request was formatted correctly, the server would respond with a JSON-encoded payload:
**Example response:**
```json theme={null}
HTTP/1.1 200 OK
Status: 200 OK
Content-Type: application/json; charset=utf-8
...
Content-Encoding: gzip
Content-Length: 140
{"token\_type":"bearer","access\_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
```
Applications should verify that the value associated with the `token_type` key of the returned object is `bearer`. The value associated with the `access_token` key is the App only Access Token (Bearer Token).
Note that one App only Access Token is valid for an application at a time. Issuing another request with the same credentials to `/oauth2/token` will return the same token until it is invalidated.
**Step 3: Authenticate API requests with the App only Access Token (Bearer Token)**
The App only Access Token (Bearer Token) may be used to issue requests to API endpoints that support application-only auth. To use the App Access Token, construct a normal HTTPS request and include an `Authorization` header with the value of `Bearer . Signing is not required.`
**Example request (Authorization header has been wrapped):**
```
GET /1.1/statuses/user\_timeline.json?count=100&screen\_name=twitterapi HTTP/1.1
Host: api.x.com
User-Agent: My X App v1.0.23
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAA
AAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Accept-Encoding: gzip
```
**Invalidating an App only Access Token (Bearer Token)**
Should an App only Access Token become compromised or need to be invalidated for any reason, issue a call to [POST oauth2/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth2-invalidate-token).
**Example request (Authorization header has been wrapped):**
```bash theme={null}
POST /oauth2/invalidate_token HTTP/1.1
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
User-Agent: My X App v1.0.23
Host: api.x.com
Accept: */*
Content-Length: 119
Content-Type: application/x-www-form-urlencoded
access_token=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```
**Example response:**
```json theme={null}
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 127
...
{"access_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
```
#### Common error cases
This section describes some common mistakes involved in the negotiation and use of Bearer Tokens. Be aware that not all possible error responses are covered here - be observant of unhandled error codes and responses.
**Invalid requests to obtain or revoke an App only Access Token**
Attempts to:
* Obtain an App only Access Token (Bearer Token) with an invalid request (for example, leaving out `grant_type=client_credentials`).
* Obtain or revoke an App only Access Token (Bearer Token) with incorrect or expired app credentials.
* Invalidate an incorrect or revoked App only Access Token (Bearer Token).
* Obtain an App only Access Token (Bearer Token) too frequently in a short period of time.
Will result in:
```json theme={null}
HTTP/1.1 403 Forbidden
Content-Length: 105
Content-Type: application/json; charset=utf-8
...
{"errors":\[{"code":99,"label":"authenticity\_token\_error","message":"Unable to verify your credentials"}\]}
```
#### API request contains invalid App only Access Token (Bearer Token)
Using an incorrect or revoked Access Token to make API requests will result in:
```json theme={null}
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Content-Length: 61
...
{"errors":\[{"message":"Invalid or expired token","code":89}\]}
```
#### App only Access Token (Bearer Token) used on endpoint which doesn't support application-only auth
Requesting an endpoint which requires a user context (such as `statuses/home_timeline`) with an App only Access Token (Bearer Token) will produce:
```json theme={null}
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Content-Length: 91
...
{"errors":\[{"message":"Your credentials do not allow access to this resource","code":220}\]}
```
# OAuth 2.0 Authorization Code Flow with PKCE
Source: https://docs.x.com/fundamentals/authentication/oauth-2-0/authorization-code
Reference for the X OAuth 2.0 Authorization Code Flow with PKCE, covering scopes, refresh tokens, confidential clients, and access token lifetimes.
### OAuth 2.0 Authorization Code Flow with PKCE
#### Introduction
OAuth 2.0 is an industry-standard authorization protocol that allows for greater control over an application’s scope, and authorization flows across multiple devices. OAuth 2.0 allows you to pick specific fine-grained scopes which give you specific permissions on behalf of a user.
To enable OAuth 2.0 in your App, you must enable it in your App’s authentication settings found in the App settings section of the Developer Console.
#### How long will my credentials stay valid?
By default, the access token you create through the Authorization Code Flow with PKCE will only stay valid for two hours unless you’ve used the `offline.access` scope.
#### Refresh tokens
Refresh tokens allow an application to obtain a new access token without prompting the user via the refresh token flow.
If the scope `offline.access` is applied an OAuth 2.0 refresh token will be issued. With this refresh token, you obtain an access token. If this scope is not passed, we will not generate a refresh token.
An example of the request you would make to use a refresh token to obtain a new access token is as follows:
```bash theme={null}
POST 'https://api.x.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'refresh_token=bWRWa3gzdnk3WHRGU1o0bmRRcTJ5VUxWX1lZTDdJSUtmaWcxbTVxdEFXcW5tOjE2MjIxNDc3NDM5MTQ6MToxOnJ0OjE' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=rG9n6402A3dbUJKzXTNX4oWHJ
```
#### App settings
You can select your App’s authentication settings to be OAuth 1.0a or OAuth 2.0. You can also enable an App to access both OAuth 1.0a and OAuth 2.0.
OAuth 2.0 can be used with the X API v2 only. If you have selected OAuth 2.0 you will be able to see a Client ID in your App’s Keys and Tokens section.
#### Confidential clients
[Confidential clients](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) can hold credentials in a secure way without exposing them to unauthorized parties and securely authenticate with the authorization server they keep your client secret safe. Public clients as they’re usually running in a browser or on a mobile device and are unable to use your client secrets. If you select a type of App that is a confidential client, you will be provided with a client secret.
If you selected a type of client that is a confidential client in the Developer Console, you will also be able to see a Client Secret. Your options are Native App, Single page App, Web App, Automated App, or bot. Native App and Single page Apps are public clients and Web App and Automated App or bots are confidential clients.
You don’t need client id for confidential clients with a valid Authorization Header. You still are required to include Client Id in the body for the requests with a public client.
#### Scopes
Scopes allow you to set granular access for your App so that your App only has the permissions that it needs. To learn more about what scopes map to what endpoints, view our [authentication mapping guide](/resources/fundamentals/authentication/guides/v2-authentication-mapping).
| | |
| :------------------- | :----------------------------------------------------------------------------------------------------------- |
| **Scope** | **Description** |
| tweet.read | All the Tweets you can view, including Tweets from protected accounts. |
| tweet.write | Tweet and Retweet for you. |
| tweet.moderate.write | Hide and unhide replies to your Tweets. |
| users.email | Email from an authenticated user. |
| users.read | Any account you can view, including protected accounts. |
| follows.read | People who follow you and people who you follow. |
| follows.write | Follow and unfollow people for you. |
| offline.access | Stay connected to your account until you revoke access. |
| space.read | All the Spaces you can view. |
| mute.read | Accounts you’ve muted. |
| mute.write | Mute and unmute accounts for you. |
| like.read | Tweets you’ve liked and likes you can view. |
| like.write | Like and un-like Tweets for you. |
| list.read | Lists, list members, and list followers of lists you’ve created or are a member of, including private lists. |
| list.write | Create and manage Lists for you. |
| block.read | Accounts you’ve blocked. |
| block.write | Block and unblock accounts for you. |
| bookmark.read | Get Bookmarked Tweets from an authenticated user. |
| bookmark.write | Bookmark and remove Bookmarks from Tweets. |
| dm.read | All the Direct Messages you can view, including Direct Messages from protected accounts. |
| dm.write | Send and manage Direct Messages for you. |
| media.write | Upload media. |
#### Rate limits
For the most part, the rate limits are the same as they are authenticating with OAuth 1.0a, with the exception of Tweets lookup and Users lookup. We are increasing the per-App limit from 300 to 900 requests per 15 minutes while using OAuth 2.0 for Tweet lookup and user lookup. To learn more be sure to check out our [documentation on rate limits](/resources/fundamentals/rate-limits).
#### Grant types
We only provide [authorization code](https://oauth.net/2/grant-types/authorization-code/) with [PKCE](https://oauth.net/2/pkce/) and [refresh token](https://oauth.net/2/grant-types/refresh-token/) as the supported [grant types](https://oauth.net/2/grant-types/) for this initial launch. We may provide more grant types in the future.
#### OAuth 2.0 flow
OAuth 2.0 uses a similar flow to what we are currently using for OAuth 1.0a. You can check out a diagram and detailed explanation in our [documentation on this subject](/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens).
#### Glossary
| | |
| :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Term** | **Description** |
| Grant types | The OAuth framework specifies several grant types for different use cases and a framework for creating new grant types. Examples include authorization code, client credentials, device code, and refresh token. |
| Confidential client | Clients are applications that can securely authenticate with the authorization server, for example, keeping their registered client secret safe. |
| Public client | Clients cannot use registered client secrets, such as applications running in a browser or mobile device. |
| Authorization code flow | Used by both confidential and public clients to exchange an authorization code for an access token. |
| PKCE | An extension to the authorization code flow to prevent several attacks and to be able to perform the OAuth exchange from public clients securely. |
| Client ID | Can be found in the keys and tokens section of the Developer Console under the header "Client ID." If you don't see this, please get in touch with our team directly. The Client ID will be needed to generate the authorize URL. |
| Redirect URI | Your callback URL. You will need to have [exact match validation](https://datatracker.ietf.org/doc/html/rfc6749#section-10.6). |
| Authorization code | This allows an application to hit APIs on behalf of users. Known as the auth\_code. The auth\_code has a time limit of 30 seconds once the App owner receives an approved auth\_code from the user. You will have to exchange it with an access token within 30 seconds, or the auth\_code will expire. |
| Access token | Access tokens are the token that applications use to make API requests on behalf of a user. |
| Refresh token | Allows an application to obtain a new access token without prompting the user via the refresh token flow. |
| Client Secret | If you have selected an App type that is a confidential client you will be provided with a “Client Secret” under “Client ID” in your App’s keys and tokens section. |
#### Parameters
To construct an OAuth 2.0 authorize URL, you will need to ensure you have the following parameters in the authorization URL.
| | |
| :---------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Parameter** | **Description** |
| response\_type | You will need to specify that this is a code with the word “code”. |
| client\_id | Can be found in the Developer Console under the header "Client ID". |
| redirect\_uri | Your callback URL. This value must correspond to one of the Callback URLs defined in your App’s settings. For OAuth 2.0, you will need to have [exact match validation](https://datatracker.ietf.org/doc/html/rfc6749#section-10.6) for your callback URL. |
| state | A random string you provide to verify against [CSRF attacks](https://auth0.com/docs/protocols/state-parameters). The length of this string can be up to 500 characters. |
| code\_challenge | A [PKCE](https://www.oauth.com/oauth2-servers/pkce/authorization-request/) parameter, a random secret for each request you make. |
| code\_challenge\_method | Specifies the method you are using to make a request (S256 OR plain). |
#### Authorize URL
With OAuth 2.0, you create an authorize URL, which you can use to allow a user to authenticate via an authentication flow, similar to “Sign In” with X.
An example of the URL you are creating is as follows:
```
https://x.com/i/oauth2/authorize?response_type=code&client_id=M1M5R3BMVy13QmpScXkzTUt5OE46MTpjaQ&redirect_uri=https://www.example.com&scope=tweet.read%20users.read%20account.follows.read%20account.follows.write&state=state&code_challenge=challenge&code_challenge_method=plain
```
You will need to have the proper encoding for this URL to work, be sure to check out our documentation on the [percent encoding](/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters).
# Using and generating an app-only Bearer Token
Source: https://docs.x.com/fundamentals/authentication/oauth-2-0/bearer-tokens
Generate and use an app-only Bearer Token for X API OAuth 2.0 application-only authentication with a curl request to the oauth2/token endpoint.
### Using and generating an app-only Bearer Token
A bearer token allows developers to have a more secure point of entry for using the X APIs, and are one of the core features of OAuth 2.0.
Authentication, which uses a Bearer Token, is also known as application-only authentication. A Bearer Token is a byte array of unspecified format that you generate using a script like a curl command. You can also obtain a Bearer Token from the Developer Console inside the keys and tokens section of your App's settings. More information about this feature can be found on [OAuth's official documentation](https://oauth.net/2/bearer-tokens/).
#### When are they used?
The products that require the use of a Bearer Token are as follows:
* [Engagement API](/x-api/enterprise-gnip-2.0/fundamentals/engagement-api)
* [Account Activity API](/x-api/enterprise-gnip-2.0/fundamentals/account-activity)
* Other APIs that utilize OAuth 2.0 Bearer Token authentication such as v2 and Labs endpoints.
#### Prerequisites
You will need to [sign up for a developer account](https://developer.x.com/en/portal/petition/essential/basic-info) and to have created a [X App](/resources/fundamentals/developer-apps). Once you have those, you'll also need to obtain the API keys found in the [Developer Console](/resources/fundamentals/developer-portal). Follow the steps below:
1. Login to your X account on developer.x.com.
2. Navigate to the [X App dashboard](https://developer.x.com/content/developer-twitter/en/apps) and open the X App for which you would like to generate access tokens.
3. Navigate to the "keys and tokens" page.
4. You'll find the API keys, user Access Tokens, and Bearer Token on this page.
### How to generate a Bearer Token
You can find the Bearer Token for your App with the rest of your "Keys and Tokens".
Copy the following cURL request into your command line after making changes to the following consumer API keys previously obtained from your [X App](/resources/fundamentals/developer-apps). Note that the consumer API keys used on this page have been decommissioned and will not work for real requests.
* **API key** `` e.g.`xvz1evFS4wEEPTGEFPHBog`
* **API secret key** `` e.g. `L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg`
```bash theme={null}
curl -u "$API_KEY:$API_SECRET_KEY" \
--data 'grant_type=client_credentials' \
'https://api.x.com/oauth2/token'
```
Here's an example of how the curl request should look with your API keys entered:
```bash theme={null}
curl -u 'xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg' \
--data 'grant_type=client_credentials' \
'https://api.x.com/oauth2/token'
```
Here is what the response would look like. Note that this is a decommissioned Bearer Token:
`{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAMLheAAAAAAA0%2BuSeid%2BULvsea4JtiGRiSDSJSI%3DEUifiRBkKG5E2XzMDjRfl76ZC9Ub0wnz4XsNiRVBChTYbJcE3F"}`
Our Bearer Token used to authenticate to resources with OAuth 2.0 would be:
`AAAAAAAAAAAAAAAAAAAAAMLheAAAAAAA0%2BuSeid%2BULvsea4JtiGRiSDSJSI%3DEUifiRBkKG5E2XzMDjRfl76ZC9Ub0wnz4XsNiRVBChTYbJcE3F`
# OAuth 2.0
Source: https://docs.x.com/fundamentals/authentication/oauth-2-0/overview
OAuth 2.0 Bearer Token authenticates requests on behalf of your developer App. As this method is specific to the App, it does not involve any users.
### Bearer Token (also known as app-only)
OAuth 2.0 Bearer Token authenticates requests on behalf of your [developer App](/resources/fundamentals/developer-apps). As this method is specific to the App, it does not involve any users. This method is typically for developers that need read-only access to public information.
This authentication method requires for you to pass a Bearer Token with your request, which you can generate within the Keys and tokens section of your developer Apps. Here is an example of what a request looks like with a fake Bearer Token:
```json theme={null}
curl "https://api.x.com/2/tweets?ids=1261326399320715264,1278347468690915330" \
-H "Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAFnz2wAAAAAAxTmQbp%2BIHDtAhTBbyNJon%2BA72K4%3DeIaigY0QBrv6Rp8KZQQLOTpo9ubw5Jt?WRE8avbi"
```
API calls using app-only authentication are [rate limited](/resources/fundamentals/rate-limits) per endpoint at the App level.
To use this method, you'll need a Bearer Token, which you can generate by passing your API Key and Secret through the [POST oauth2/token](/resources/fundamentals/authentication/api-reference#post-oauth2-token) endpoint, or by generating it in the "keys and token" section of your App settings in the [Developer Console](/resources/fundamentals/developer-portal).
If you'd like to revoke a Bearer Token, you can use the [POST oauth2/invalidate\_token](/resources/fundamentals/authentication/api-reference#post-oauth2-invalidate-token) endpoint, or click where it says "revoke" next to the Bearer Token in the "keys and tokens" section of your App settings.
### OAuth 2.0 Authorization Code Flow with PKCE
OAuth 2.0 Authorization Code Flow with PKCE allows you to authenticate on behalf of another user with more control over an application’s scopes and improves authorization flows across multiple devices. In other words, developers building applications for people on X will have more control over the information their App requests from its users, so that you only have to ask your end-users for the data and information you need.
This modern authorization protocol will allow you to present your end-users with a more streamlined consent flow for authorizing your app, which only displays the specific scopes you have requested from them. Not only does this reduce your data burden, but it may also lead to increased trust from end-users.
# OAuth 2.0 Authorization Code Flow with PKCE
Source: https://docs.x.com/fundamentals/authentication/oauth-2-0/user-access-token
Step-by-step guide to connecting users to X API v2 endpoints with OAuth 2.0 Authorization Code Flow with PKCE, including authorize URLs and token exchange.
### How to connect to endpoints using OAuth 2.0 Authorization Code Flow with PKCE
#### How to connect to the endpoints
To authenticate your users, your App will need to implement an authorization flow. This authorization flow lets you direct your users to an authorization dialog on X. From there, the primary X experience will show the authorization dialog and handle the authorization on behalf of your App. Your users will be able to authorize your App or decline permission. After the user makes their choice, X will redirect the user to your App, where you can exchange the authorization code for an access token (if the user authorized your App), or handle a rejection (if the user did not authorize your App).
#### Working with confidential clients
If you are working with confidential clients, you will need to use a [basic authentication](https://datatracker.ietf.org/doc/html/rfc2617#section-2) scheme for generating an authorization header with base64 encoding while making requests to the token endpoints.
The `userid` and `password` are separated by a single colon (":") character within a base64 encoded string in the credentials.
An example would look like this:
`-header 'Authorization: Basic V1ROclFTMTRiVWhwTWw4M2FVNWFkVGQyTldNNk1UcGphUTotUm9LeDN4NThKQThTbTlKSXQyZm1BanEzcTVHWC1icVozdmpKeFNlR3NkbUd0WEViUA=='`
If the user agent wishes to send the Client ID "Aladdin" and password "open sesame,” it would use the following header field:
`Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==`
To create the basic authorization header you will need to base64 encoding on your Client ID and Client Secret which can be obtained from your App’s “Keys and Tokens” page inside of the [Developer Console.](https://developer.x.com/en/portal/dashboard)
#### Steps to connect using OAuth 2.0
**Step 1: Construct an Authorize URL**
Your App will need to build an authorize URL to X, indicating the scopes your App needs to authorize. For example, if your App needs to lookup Tweets, users and to manage follows, it should request the following scopes:
`tweet.read%20users.read%20follows.read%20follows.write`
The URL will also contain the `code_challenge` and state parameters, in addition to the other required parameters. In production you should use a random string for the `code_challenge`.
**Step 2: GET oauth2/authorize**
Have the user authenticate and send the application an authorization code. If you have enabled OAuth 2.0 for your App you can find your Client ID inside your App’s “Keys and Tokens” page.
An example URL to redirect the user to would look like this:
```
https://x.com/i/oauth2/authorize?response_type=code&client_id=M1M5R3BMVy13QmpScXkzTUt5OE46MTpjaQ&redirect_uri=https://www.example.com&scope=tweet.read%20users.read%20follows.read%20follows.write&state=state&code_challenge=challenge&code_challenge_method=plain
```
An example URL with offline\_access would look like this:
```
https://x.com/i/oauth2/authorize?response_type=code&client_id=M1M5R3BMVy13QmpScXkzTUt5OE46MTpjaQ&redirect_uri=https://www.example.com&scope=tweet.read%20users.read%20follows.read%20offline.access&state=state&code_challenge=challenge&code_challenge_method=plain
```
Upon successful authentication, the redirect\_uri you would receive a request containing the auth\_code parameter. Your application should verify the state parameter.
An example request from client’s redirect would be:
```
https://www.example.com/?state=state&code=VGNibzFWSWREZm01bjN1N3dicWlNUG1oa2xRRVNNdmVHelJGY2hPWGxNd2dxOjE2MjIxNjA4MjU4MjU6MToxOmFjOjE
```
**Step 3: POST oauth2/token - Access Token**
At this point, you can use the authorization code to create an access token and refresh token (only if `offline.access` scope is requested). You can make a POST request to the following endpoint:
```
https://api.x.com/2/oauth2/token
```
You will need to pass in the `Content-Type` of `application/x-www-form-urlencoded` via a header. Additionally, you should have in your request: `code`, `grant_type`, `client_id` and `redirect_uri`, and the `code_verifier`.
Here is an example token request for a public client:
```json theme={null}
curl --location --request POST 'https://api.x.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=VGNibzFWSWREZm01bjN1N3dicWlNUG1oa2xRRVNNdmVHelJGY2hPWGxNd2dxOjE2MjIxNjA4MjU4MjU6MToxOmFjOjE' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'client_id=rG9n6402A3dbUJKzXTNX4oWHJ' \
--data-urlencode 'redirect_uri=https://www.example.com' \
--data-urlencode 'code_verifier=challenge'
```
Here is an example using a confidential client:
```json theme={null}
curl --location --request POST 'https://api.x.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic V1ROclFTMTRiVWhwTWw4M2FVNWFkVGQyTldNNk1UcGphUTotUm9LeDN4NThKQThTbTlKSXQyZm1BanEzcTVHWC1icVozdmpKeFNlR3NkbUd0WEViUA=='\
--data-urlencode 'code=VGNibzFWSWREZm01bjN1N3dicWlNUG1oa2xRRVNNdmVHelJGY2hPWGxNd2dxOjE2MjIxNjA4MjU4MjU6MToxOmFjOjE' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'redirect_uri=https://www.example.com' \
--data-urlencode 'code_verifier=challenge'
```
**Step 4: Connect to the APIs**
You are now ready to connect to the endpoints using OAuth 2.0. To do so, you will request the API as you would using [Bearer Token authentication](/resources/fundamentals/authentication/oauth-2-0/application-only). Instead of passing your Bearer Token, you’ll want to use the access token you generated in the last step. As a response, you should see the appropriate payload corresponding to the endpoint you are requesting. This request is the same for both public and confidential clients.
An example of the request you would make would look as follows:
```json theme={null}
curl --location --request GET 'https://api.x.com/2/tweets?ids=1261326399320715264,1278347468690915330' \
--header 'Authorization: Bearer Q0Mzb0VhZ0V5dmNXSTEyNER2MFNfVW50RzdXdTN6STFxQlVkTGhTc1lCdlBiOjE2MjIxNDc3NDM5MTQ6MToxOmF0OjE'
```
**Step 5: POST oauth2/token - refresh token**
A refresh token allows an application to obtain a new access token without prompting the user. You can create a refresh token by making a POST request to the following endpoint: [https://api.x.com/2/oauth2/token](https://api.x.com/2/oauth2/token) You will need to add in the `Content-Type` of `application/x-www-form-urlencoded` via a header. In addition, you will also need to pass in your refresh\_token, set your grant\_type to be a `refresh_token`, and define your `client_id`.
This request will work for public clients:
```json theme={null}
POST 'https://api.x.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'refresh_token=bWRWa3gzdnk3WHRGU1o0bmRRcTJ5VUxWX1lZTDdJSUtmaWcxbTVxdEFXcW5tOjE2MjIxNDc3NDM5MTQ6MToxOnJ0OjE' \
--data-urlencode 'grant_type=refresh_token' \
--data-urlencode 'client_id=rG9n6402A3dbUJKzXTNX4oWHJ'
```
Here is an example of one for confidential clients:
```json theme={null}
POST 'https://api.x.com/2/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic V1ROclFTMTRiVWhwTWw4M2FVNWFkVGQyTldNNk1UcGphUTotUm9LeDN4NThKQThTbTlKSXQyZm1BanEzcTVHWC1icVozdmpKeFNlR3NkbUd0WEViUA=='\
--data-urlencode 'refresh_token=bWRWa3gzdnk3WHRGU1o0bmRRcTJ5VUxWX1lZTDdJSUtmaWcxbTVxdEFXcW5tOjE2MjIxNDc3NDM5MTQ6MToxOnJ0OjE'\
--data-urlencode 'grant_type=refresh_token'
```
**Step 6: POST oauth2/revoke - Revoke Token**
A revoke token invalidates an access token or refresh token. This is used to enable a "log out" feature in clients, allowing you to clean up any security credentials associated with the authorization flow that may no longer be necessary. The revoke token is for an App to revoke a token and not a user. You can create a revoke token request by making a POST request to the following URL if the App wants to programmatically revoke the access given to it:
```
https://api.x.com/2/oauth2/revoke
```
You will need to pass in the `Content-Type` of `application/x-www-form-urlencoded` via a header, your token, and your client\_id.
In some cases, a user may wish to revoke access given to an App, they can revoke access by visiting the [connected Apps page](https://x.com/settings/connected_apps).
```bash theme={null}
curl --location --request POST 'https://api.x.com/2/oauth2/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'token=Q0Mzb0VhZ0V5dmNXSTEyNER2MFNfVW50RzdXdTN6STFxQlVkTGhTc1lCdlBiOjE2MjIxNDc3NDM5MTQ6MToxOmF0OjE' \
--data-urlencode 'client_id=rG9n6402A3dbUJKzXTNX4oWHJ'
```
This request will work for confidential clients:
```bash theme={null}
curl --location --request POST 'https://api.x.com/2/oauth2/revoke' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic V1ROclFTMTRiVWhwTWw4M2FVNWFkVGQyTldNNk1UcGphUTotUm9LeDN4NThKQThTbTlKSXQyZm1BanEzcTVHWC1icVozdmpKeFNlR3NkbUd0WEViUA=='\
--data-urlencode 'token=Q0Mzb0VhZ0V5dmNXSTEyNER2MFNfVW50RzdXdTN6STFxQlVkTGhTc1lCdlBiOjE2MjIxNDc3NDM5MTQ6MToxOmF0OjE'
```
# Authentication
Source: https://docs.x.com/fundamentals/authentication/overview
X APIs handle enormous amounts of data. The way we ensure this data is secured for developers and users alike is through authentication.
X APIs handle enormous amounts of data, and authentication secures that data for developers and users alike. You can choose from several authentication methods, listed below.
Most developers don't need to handle the complexities of authentication directly—client libraries take care of them automatically.
You can find a list of available client libraries on our [Tools and libraries](/resources/tools-and-libraries) page.
## Authentication methods
OAuth 1.0a allows an authorized X developer App to access private account information or perform a X action on behalf of a X account.
[**Learn More**](/resources/fundamentals/authentication/oauth-1-0a/api-key-and-secret)
App only Access Token allows a X developer app to access information publicly available on X.
[**Learn More**](/resources/fundamentals/authentication/oauth-2-0/overview)
Many of X's enterprise APIs require the use of HTTP Basic Authentication.
[**Learn More**](/resources/fundamentals/authentication/basic-auth)
OAuth 2.0 User Context allows you to authenticate on behalf of another account with greater control over an application's scope, and authorization flows across multiple devices.
[**Learn More**](/resources/fundamentals/authentication/oauth-2-0/authorization-code)
**Note:**
You can get your App's API Keys, App-only Access Token, personal Access Token, and Access Token Secret from the [X developer Apps](/resources/fundamentals/developer-apps) section in the [Developer Console](/resources/fundamentals/developer-portal).
**To make requests on behalf of another user**, generate a separate set of Access Tokens for that user using the [3-legged OAuth flow](https://developer.x.com/resources/fundamentals/authentication/obtaining-user-access-tokens), then pass that user's tokens with your OAuth 1.0a User Context or OAuth 2.0 user context requests.
## Additional resources
Learn how to generate tokens and authenticate requests using our integration guides.
Review our reference guides for our authentication endpoints.
Make sure you protect yourself and understand the best practices for storing your keys and tokens.
Have a question? Visit our FAQs.
# Counting Characters
Source: https://docs.x.com/fundamentals/counting-characters
How X counts characters in Posts, including the 280-character limit, weighted code points, URL shortening, emoji and Unicode handling, and edge cases.
Posts on X can contain up to **280 characters**. However, not all characters count equally—emojis, URLs, and certain Unicode ranges have special counting rules.
***
## Character weights
X uses a weighted character counting system. Most characters count as 1, but some count as 2:
| Character type | Weight | Max characters |
| :--------------------------------- | :---------- | :------------- |
| Latin, punctuation, common symbols | 1 | 280 |
| Emojis | 2 | 140 emojis |
| CJK (Chinese, Japanese, Korean) | 2 | 140 characters |
| Other Unicode | 2 (default) | Varies |
Use the open-source [twitter-text](https://github.com/twitter/twitter-text) library to accurately count characters in your app.
***
## Emoji counting
All emojis count as **2 characters**, regardless of complexity:
| Emoji | Display | Character count | Unicode |
| :---------- | :---------------- | :-------------- | :---------------- |
| 👾 | Single emoji | 2 | U+1F47E |
| 🙋🏽 | With skin tone | 2 | 🙋 + 🏽 modifier |
| 👨🎤 | Combined with ZWJ | 2 | 👨 + ZWJ + 🎤 |
| 👨👩👧👦 | Family sequence | 2 | 4 emojis + 3 ZWJs |
Zero-width joiners (ZWJ) combine emojis visually but don't add to the count.
***
## URL handling
All URLs are wrapped with `t.co` shortener and count as **23 characters**, regardless of the original length:
```
https://example.com → 23 characters
https://example.com/very/long/path → 23 characters
```
This applies to any valid URL detected in post text.
***
## Special cases
| Content | Counting rule |
| :----------------------- | :----------------------------------------------------------- |
| **@mentions in replies** | Auto-populated @mentions at the start of replies don't count |
| **New @mentions** | @mentions you add manually count normally |
| **Media** | Attached media (via official clients) counts as 0 characters |
| **Hashtags** | Count normally (# + tag text) |
***
## Text encoding
The X API requires **UTF-8** encoding. Character length is calculated using Unicode Normalization Form C (NFC).
Example with `café`:
| Form | Bytes | Characters |
| :--------------- | :---------- | :--------- |
| NFC (composed) | `c a f é` | 4 |
| NFD (decomposed) | `c a f e ́` | 5 |
X normalizes to NFC, so both encode to 4 characters.
***
## Implementation
Use the official [twitter-text](https://github.com/twitter/twitter-text) library for accurate character counting:
```javascript theme={null}
import { parseTweet } from 'twitter-text';
const result = parseTweet('Hello, world! 👋');
console.log(result.weightedLength); // 16
console.log(result.valid); // true
```
```python theme={null}
from twitter_text import parse_tweet
result = parse_tweet('Hello, world! 👋')
print(result.weightedLength) # 16
print(result.valid) # True
```
The library handles all edge cases including emoji sequences, URL detection, and Unicode normalization.
***
## Resources
Official open-source library for text parsing.
Character weight definitions and Unicode ranges.
# Apps
Source: https://docs.x.com/fundamentals/developer-apps
Create and configure X developer apps to get API credentials, set OAuth 1.0a and OAuth 2.0 permissions, manage callback URLs, and rotate keys.
Apps are containers for your API credentials. Each app has its own keys, tokens, and settings.
***
## App credentials
When you create an app, you can generate these credentials:
| Credential | Use case |
| :------------------------ | :--------------------------------------------------------------------------- |
| **API Key & Secret** | Authenticate with OAuth 1.0a. Used to sign requests or generate user tokens. |
| **Access Token & Secret** | Make requests on behalf of your own account (OAuth 1.0a). |
| **Client ID & Secret** | Authenticate with OAuth 2.0. Used for authorization code flow. |
| **Bearer Token** | App-only authentication for public data endpoints. |
Choose **OAuth 2.0** for new projects. It offers fine-grained scopes and is required for X API v2 user-context endpoints.
***
## Creating an app
Go to [console.x.com](https://console.x.com) and sign in.
Enter a name, description, and use case for your app.
After creation, generate the keys and tokens you need.
Save credentials immediately—they're only shown once.
***
## App permissions (OAuth 1.0a)
OAuth 1.0a apps have three permission levels:
* View posts, users, and public data
* Cannot post, like, or modify anything
* Cannot access Direct Messages
* All read permissions
* Post and delete posts
* Follow/unfollow users
* Like and repost
* Cannot access Direct Messages
* All read and write permissions
* Send and read Direct Messages
Changing permissions requires users to re-authorize your app to get new tokens with the updated scope.
***
## OAuth 2.0 app types
When configuring OAuth 2.0, select your app type:
| Type | Client | Use case |
| :---------------------- | :----------- | :------------------------------------------------------- |
| **Web App** | Confidential | Server-side applications that can securely store secrets |
| **Automated App / Bot** | Confidential | Bots and automated services running on servers |
| **Native App** | Public | Mobile or desktop apps that can't secure secrets |
| **Single Page App** | Public | Browser-based JavaScript apps |
**Confidential clients** receive a Client Secret. **Public clients** use PKCE only.
***
## Callback URLs
Callback URLs (redirect URIs) are required for OAuth flows. After a user authorizes your app, they're redirected to your callback URL with an authorization code.
### Requirements
* Add callback URLs to your app's allowlist in the Developer Console
* URLs must match exactly (including trailing slashes)
* Maximum of **10 callback URLs** per app
* Use `https://` in production
* For local development, use `http://127.0.0.1` (not `localhost`)
### Disallowed protocols
These protocols cannot be used: `javascript`, `data`, `file`, `ftp`, `mailto`, `telnet`, and other non-standard schemes.
`vbscript`, `javascript`, `vbs`, `data`, `mocha`, `keyword`, `livescript`, `ftp`, `file`, `gopher`, `acrobat`, `callto`, `daap`, `itpc`, `itms`, `firefoxurl`, `hcp`, `ldap`, `mailto`, `mmst`, `mmsu`, `msbd`, `rtsp`, `mso-offdap`, `snews`, `news`, `nntp`, `outlook`, `stssync`, `rlogin`, `telnet`, `tn3270`, `shell`, `sip`
***
## Best practices
Create different apps for development, staging, and production.
Regenerate keys periodically and if you suspect a compromise.
Request only the permissions your app actually needs.
Check the Developer Console regularly to track API usage.
***
## Automated account labels
If your app runs a bot account, you can label it as automated:
1. Go to your bot account's **Settings**
2. Select **Your account** → **Automation**
3. Link your managing account
This builds trust with users and distinguishes your bot from spam.
***
## Troubleshooting
Ensure your callback URL is exactly as registered in the Developer Console, including protocol and any trailing slashes. HTTP-encode the URL when passing it as a query parameter.
```json theme={null}
{
"errors": [{
"code": 415,
"message": "Callback URL not approved for this client application."
}]
}
```
If your app shows as suspended, check your email for a notice from the X platform team. Use the [Platform Help Form](https://help.x.com/forms/platform) to appeal.
# Developer Console
Source: https://docs.x.com/fundamentals/developer-portal
Use the X Developer Console to manage projects and apps, monitor API usage, access credentials, invite team members, and view billing information.
The [Developer Console](https://console.x.com) is your central hub for managing X API access. Create apps, generate credentials, monitor usage, and manage billing—all in one place.
***
## What you can do
Set up apps to get API credentials. Configure authentication, permissions, and callback URLs.
Track API usage in real-time. View costs per endpoint and manage your credit balance.
Create API keys, access tokens, and OAuth credentials for your apps.
Buy credits for pay-per-usage billing. No subscriptions or commitments required.
***
## Getting started
Go to [console.x.com](https://console.x.com) and sign in with your X account. Accept the Developer Agreement.
Click **New App** and provide a name and description. This generates your API credentials.
Copy and securely store your API Key, API Secret, and Access Tokens. These won't be shown again.
Use your credentials to authenticate API requests. Check out the [quickstart guide](/x-api/getting-started/make-your-first-request).
**Store credentials securely.** API keys and tokens are only displayed once when generated. Use a password manager or secure vault. If lost, you'll need to regenerate them, which invalidates the old credentials.
***
## Billing & credits
The X API uses pay-per-usage pricing with a credit-based system:
| Feature | Description |
| :----------------------- | :------------------------------------------------------------- |
| **No monthly fees** | Pay only for what you use—no subscriptions |
| **Credit-based** | Purchase credits upfront, deducted as you use the API |
| **Real-time tracking** | Monitor usage and costs in the console dashboard |
| **Per-endpoint pricing** | Different endpoints have different costs |
| **Deduplication** | Same resource requested twice in 24 hours is only charged once |
View current pricing and purchase credits in the [Developer Console](https://console.x.com).
[Learn more about pricing →](/x-api/getting-started/pricing)
***
## Team management
Team management is available for **Enterprise accounts** only.
Enterprise accounts can invite team members to collaborate:
| Role | Capabilities |
| :---------------- | :--------------------------------------------------------- |
| **Administrator** | Full access: manage apps, billing, team members, and roles |
| **Developer** | Manage own apps, read-only access to team apps |
To invite a team member, navigate to the Team page in your console and enter their X handle.
***
## Next steps
Learn about app settings, permissions, and credentials.
Use your credentials to call the API.
# Rate Limits
Source: https://docs.x.com/fundamentals/rate-limits
Understand X API rate limits across access tiers and endpoints, including app-level vs user-level limits, response headers, and best practices for retries.
Rate limits control how many API requests you can make in a given time period. They ensure fair usage and system stability across the platform.
***
## Rate limits by product
Each X API product has its own rate limiting approach:
Per-endpoint limits based on 15-minute windows. View detailed tables and recovery tips.
Custom limits based on your enterprise agreement and data package.
Limits specific to ad management and analytics endpoints.
***
## How rate limits work
| Concept | Description |
| :-------------------- | :------------------------------------------------------ |
| **Time window** | Most limits reset every 15 minutes |
| **Per-user limits** | Apply when using OAuth 1.0a or OAuth 2.0 user tokens |
| **Per-app limits** | Apply when using Bearer Token (app-only) authentication |
| **Endpoint-specific** | Each endpoint has its own limit |
***
## Checking your limits
Every API response includes headers showing your current rate limit status:
```
x-rate-limit-limit: 900
x-rate-limit-remaining: 847
x-rate-limit-reset: 1705420800
```
| Header | Description |
| :----------------------- | :--------------------------------------------- |
| `x-rate-limit-limit` | Maximum requests allowed in the current window |
| `x-rate-limit-remaining` | Requests remaining in the current window |
| `x-rate-limit-reset` | Unix timestamp when the limit resets |
***
## Rate limit errors
When you exceed a rate limit, you'll receive a **429 Too Many Requests** response:
```json theme={null}
{
"errors": [{
"code": 88,
"message": "Rate limit exceeded"
}]
}
```
***
## Best practices
Store API responses locally to reduce repeated requests for the same data.
When rate limited, wait before retrying. Double the wait time with each retry.
Monitor rate limit headers to avoid hitting limits proactively.
For real-time data, use filtered stream instead of polling search endpoints.
***
## Next steps
For detailed rate limit tables by endpoint, see the rate limits page for your specific API:
* [X API v2 Rate Limits](/x-api/fundamentals/rate-limits)
* [X Ads API Rate Limits](/x-ads-api/fundamentals/rate-limiting)
# Security
Source: https://docs.x.com/fundamentals/security
Security best practices for X API developers, including credential storage, OAuth handling, key rotation, secure callbacks, and vulnerability disclosure.
Building secure applications protects both your users and the X platform. This guide covers essential security practices for X API developers.
***
## Core requirements
All API requests must use HTTPS. Plain HTTP is rejected.
Never expose API keys or tokens in client-side code, logs, or repositories.
***
## Protecting credentials
Your API keys and tokens are the keys to your app. Keep them secure:
Store credentials in environment variables, not in code.
```bash theme={null}
export X_API_KEY="your-api-key"
export X_API_SECRET="your-api-secret"
```
Add credential files to `.gitignore`. Use tools like `git-secrets` to prevent accidental commits.
Regenerate keys periodically and immediately if you suspect a compromise.
Only request the OAuth scopes your app actually needs.
### If credentials are compromised
1. **Regenerate immediately** in the [Developer Console](https://console.x.com)
2. **Revoke old tokens** — regenerating automatically invalidates old credentials
3. **Audit usage** — check for unauthorized API activity
4. **Update your app** — deploy new credentials to all environments
***
## Application security
### Input validation
Never trust user input. Validate and sanitize all data before using it:
```python theme={null}
# Bad - vulnerable to injection
query = f"from:{user_input}"
# Good - validate input first
import re
if re.match(r'^[a-zA-Z0-9_]{1,15}$', user_input):
query = f"from:{user_input}"
```
### Output encoding
Escape X API data before displaying in HTML to prevent XSS:
```javascript theme={null}
// Bad - vulnerable to XSS
element.innerHTML = tweet.text;
// Good - escape HTML
element.textContent = tweet.text;
```
### Common vulnerabilities to prevent
| Vulnerability | Prevention |
| :----------------- | :---------------------------------------------------------- |
| **XSS** | Escape all user-generated content before rendering |
| **CSRF** | Use anti-CSRF tokens in forms; verify OAuth state parameter |
| **SQL Injection** | Use parameterized queries, never concatenate user input |
| **Open redirects** | Validate callback URLs against an allowlist |
***
## OAuth security
### State parameter
Always use the `state` parameter in OAuth flows to prevent CSRF:
```python theme={null}
import secrets
# Generate state before authorization
state = secrets.token_urlsafe(32)
session['oauth_state'] = state
# Verify state after callback
if request.args.get('state') != session.get('oauth_state'):
abort(403) # State mismatch - possible CSRF
```
### Token storage
| Token type | Storage recommendation |
| :----------------- | :------------------------------------------------- |
| **Access tokens** | Encrypted database or secure vault |
| **Refresh tokens** | Encrypted database with additional access controls |
| **Bearer tokens** | Environment variables or secure configuration |
***
## Secure development practices
Conduct regular security reviews and penetration testing.
Keep dependencies updated. Use tools to detect vulnerable packages.
Log security events but never log credentials or sensitive data.
Set up alerts for unusual API usage patterns.
***
## Reporting security issues
If you discover a security vulnerability affecting X:
**Report within 48 hours.** X Developer Platform users must notify X no more than 48 hours after suspecting a security incident.
Report vulnerabilities in X's systems through HackerOne.
If your app using X data is breached, report through the same channel.
***
## Compliance checklist
* [ ] All API requests use TLS/HTTPS
* [ ] Credentials stored securely (not in code or logs)
* [ ] User tokens encrypted at rest
* [ ] Input validation on all user-supplied data
* [ ] Output encoding to prevent XSS
* [ ] CSRF protection on OAuth flows
* [ ] Security logging enabled (without sensitive data)
* [ ] Incident response plan documented
* [ ] Dependencies regularly updated
* [ ] Minimal OAuth scopes requested
***
## Resources
Implement OAuth correctly.
Configure minimal required permissions.
# X IDs
Source: https://docs.x.com/fundamentals/x-ids
Understand 64-bit Snowflake IDs in the X API for Posts and users, including format, ordering, ID inflation, and safe handling in JavaScript clients.
Every object in the X API—posts, users, lists, DMs, spaces—has a unique ID. Understanding how these IDs work helps you build reliable integrations.
***
## ID format
X IDs are **64-bit unsigned integers** generated using a system called "Snowflake." Each ID encodes:
* **Timestamp** — When the object was created
* **Worker number** — Which server generated the ID
* **Sequence number** — Order within that millisecond
This means IDs are roughly time-ordered: higher IDs generally represent newer objects.
IDs are globally unique across all of X, not just within a single object type.
***
## String vs. integer representation
**Always use string IDs in your code.** Some programming languages (like JavaScript) can't accurately represent 64-bit integers.
In JavaScript, integers are limited to 53 bits. This causes precision loss with large IDs:
```javascript theme={null}
// This loses precision!
const id = 10765432100123456789;
console.log(id.toString()); // "10765432100123458000" — wrong!
// Use strings instead
const id = "10765432100123456789";
console.log(id); // "10765432100123456789" — correct!
```
### API versions
| Version | ID format |
| :------------- | :---------------------------------------------------------------------- |
| **X API v2** | IDs are returned as strings by default |
| **X API v1.1** | Returns both `id` (integer) and `id_str` (string) — always use `id_str` |
***
## Working with IDs
### Storing IDs
Store IDs as strings or 64-bit integers in your database:
| Database | Recommended type |
| :--------- | :-------------------------------------- |
| PostgreSQL | `BIGINT` or `TEXT` |
| MySQL | `BIGINT UNSIGNED` or `VARCHAR(20)` |
| MongoDB | String |
| SQLite | `TEXT` (SQLite integers max at 63 bits) |
### Comparing IDs
When comparing IDs for chronological ordering:
```python theme={null}
# Python - safe for 64-bit integers
if int(id1) > int(id2):
print("id1 is newer")
# JavaScript - compare as strings (lexicographically works for same-length IDs)
# Or use BigInt
if (BigInt(id1) > BigInt(id2)) {
console.log("id1 is newer");
}
```
***
## Common ID types
| Object | Example ID | Notes |
| :----------- | :-------------------- | :--------------------------------- |
| Post (Tweet) | `1234567890123456789` | Also called Tweet ID |
| User | `2244994945` | Older accounts have shorter IDs |
| List | `1234567890` | |
| Space | `1YqGodQbNXDxv` | Alphanumeric, not Snowflake format |
| DM Event | `1234567890123456789` | |
***
## Related resources
See ID fields for each object type.
Retrieve posts by ID.
# Important Resources
Source: https://docs.x.com/important-resources
Bookmark key X API documentation, SDKs, Postman collections, support channels, status pages, and community resources for developers building on X.
Bookmark these essential resources for X API development.
***
## Documentation
Complete endpoint documentation with parameters and examples.
Object schemas for posts, users, media, and more.
OAuth 1.0a and OAuth 2.0 implementation guides.
Per-endpoint limits and best practices.
***
## Tools
| Tool | Description |
| :------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------ |
| [Developer Console](https://console.x.com) | Manage apps, credentials, and billing |
| [Postman Collection](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80) | Interactive API testing |
| [Python SDK](/xdks/python/overview) | Official Python library |
| [TypeScript SDK](/xdks/typescript/overview) | Official TypeScript library |
| [OpenAPI Spec](https://api.x.com/2/openapi.json) | Machine-readable API specification |
***
## Learning
Step-by-step guides for common use cases.
Example apps and code samples.
Ideas and inspiration for projects.
Upgrade from v1.1 to v2.
***
## Community and support
Ask questions and share solutions with the community.
FAQs, troubleshooting, and contact options.
Official updates and announcements.
API-specific news and tips.
***
## Stay updated
| Resource | What you'll get |
| :------------------------------------------------------------------- | :------------------------------------- |
| [Changelog](/changelog) | All platform changes and updates |
| [Changelog RSS feed](https://docs.x.com/changelog/rss.xml) | Changelog updates for your feed reader |
| [Newsletter](/newsletter) | Monthly roundup of news and features |
| [Forum Announcements](https://devcommunity.x.com/c/announcements/22) | Important platform notices |
| [API Status](https://developer.x.com/status) | Real-time service availability |
Follow [@XDevelopers](https://x.com/XDevelopers) and turn on notifications to catch breaking changes and new features.
***
## Quick reference
### Response structure
All v2 responses follow this structure:
```json theme={null}
{
"data": { ... }, // Primary object(s)
"includes": { ... }, // Expanded objects (if requested)
"meta": { ... }, // Pagination info
"errors": [ ... ] // Partial errors (if any)
}
```
### Common parameters
| Parameter | Use |
| :----------------- | :--------------------------- |
| `tweet.fields` | Request specific post fields |
| `user.fields` | Request specific user fields |
| `expansions` | Include related objects |
| `max_results` | Limit results per page |
| `pagination_token` | Get next/previous page |
### Authentication methods
| Method | Use case |
| :----------- | :-------------------------------------- |
| Bearer Token | Read-only public data |
| OAuth 2.0 | User actions with fine-grained scopes |
| OAuth 1.0a | User actions (legacy, full permissions) |
[Full authentication guide →](/resources/fundamentals/authentication/overview)
# X Developer Platform incident history
Source: https://docs.x.com/incidents
Historical record of past incidents, outages, and service disruptions affecting the X API v2, Enterprise APIs, Ads API, and streaming endpoints.
This page records past incidents affecting the X Developer Platform. For live service status, see the [X Developer Platform status page](https://developer.x.com/status).
## July 2026
Incident has been resolved. | **June 30, 23:00 UTC - July 1, 01:00 UTC**
## June 2026
Incident has been resolved. | **June 22, 12:00 UTC - 15:41 UTC**
Incident has been resolved. | **June 17, 02:20 UTC - 03:45 UTC**
## April 2026
Incident has been resolved. | **April 14, 21:00 UTC - 21:30 UTC**
Incident has been resolved. | **April 1, 20:15 UTC - 20:30 UTC**
## March 2026
Incident has been resolved. | **March 31, 20:45 UTC - 21:00 UTC**
Incident is ongoing. | **March 24, 02:00 UTC - Current**
Incident has been resolved. | **March 27, 23:20 UTC - March 28, 00:56 UTC**
Incident has been resolved. | **March 24, 15:20:00 UTC - 18:00:00 UTC**
## February 2026
Incident has been resolved. | **February 16, 18:20 UTC - 19:50 UTC**
Incident has been resolved. | **February 16, 13:27 UTC - 14:29 UTC**
## January 2026
Incident has been resolved. | **January 29, 04:00 UTC - 04:45 UTC**
Incident has been resolved. | **January 25, 17:00 UTC - 19:00 UTC**
Incident has been resolved. | **January 24, 16:48 UTC - 20:30 UTC**
Incident has been resolved. | **January 23, 19:25 UTC - 20:30 UTC**
Incident has been resolved. | **January 22, 17:30 UTC - 17:45 UTC**
Incident has been resolved. | **January 16, 15:39 UTC - 21:00 UTC**
## December 2025
Incident has been resolved. | **December 5, 7:00 UTC - October 15, 8:40 UTC**
## September 2025
Incident has been resolved. | **September 10, 20:30 UTC - September 11, 04:30 UTC**
Incident has been resolved. | **September 10, 20:30 UTC - September 10, 22:00 UTC**
## August 2025
Incident has been resolved. | **August 12, 01:00 UTC - August 12, 13:30 UTC**
## May 2025
Incident has been resolved. | **June 26, 17:00 UTC - June 26, 17:45 UTC**
Incident has been [resolved](https://downdetector.com/status/google/). | **June 12, 15:00 UTC - June 12, 23:00 UTC**
Incident has been resolved. | **May 30, 20:20 UTC - May 30, 21:00 UTC**
Incident has been resolved. | **May 30, 18:45 UTC - May 30, 21:00 UTC**
Incident has been resolved. | **May 28, 17:00 UTC - May 28, 21:41 UTC**
Incident has been resolved. | **May 23, 17:35 UTC - May 27, 00:00 UTC**
Incident has been resolved. | **May 22, 18:00 UTC**
Incident has been resolved. | **May 09, 05:00 - May 09, 07:00 UTC**
## April 2025
Incident has been resolved. | **Apr 02, 17:10 - Apr 02, 20:30 UTC**
Incident has been resolved. | **Apr 02, 13:09 - Apr 02, 13:51 UTC**
## March 2025
Incident has been resolved. | **Mar 10, 12:00 - Mar 11, 00:00 UTC**
## February 2025
Incident is ongoing. | **Feb 6, 00:00**
Incident has been resolved. | **Feb 3, 17:30 - Feb 4, 01:00 UTC**
## January 2025
There are no past incidents.
## December 2024
There are no past incidents.
# X Developer Platform Livestreams
Source: https://docs.x.com/livestreams
Watch recordings of X Developer Platform livestreams, including product walkthroughs, technical deep dives, AMA sessions, and integration tutorials.
View recordings and replays of previous broadcasts about the X Developer Platform, designed to help the developer community learn and build with our tools.
These include deep dives, getting started guides, and more.
## Past broadcasts
# Make Your First Request
Source: https://docs.x.com/make-your-first-request
Send your first X API v2 request in minutes using cURL or Postman, including authentication, endpoint selection, and parsing the JSON response.
This guide walks you through making your first X API request. You'll need a [developer account with app credentials](/x-api/getting-started/getting-access) before starting.
***
## Quick start with cURL
The fastest way to test the API is with cURL. Let's look up a user:
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Replace `$BEARER_TOKEN` with your actual Bearer Token. You'll get a response like:
```json theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers"
}
}
```
***
## Step-by-step guide
In the [Developer Console](https://console.x.com), navigate to your app and copy the Bearer Token.
Start with one of these beginner-friendly endpoints:
| Endpoint | What it does |
| :------------------------------------------------ | :--------------------------------- |
| [User lookup](/x-api/users/lookup/introduction) | Get user profile by username or ID |
| [Post lookup](/x-api/posts/lookup/introduction) | Get post by ID |
| [Recent search](/x-api/posts/search/introduction) | Search posts from the last 7 days |
Use cURL, Postman, or your preferred HTTP client:
```bash theme={null}
# Look up a user by username
curl "https://api.x.com/2/users/by/username/xdevelopers" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Responses are JSON. The primary data is in the `data` field:
```json theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers"
}
}
```
***
## Request more data with fields
By default, endpoints return minimal fields. Use the `fields` parameter to request additional data:
```bash theme={null}
curl "https://api.x.com/2/users/by/username/xdevelopers?user.fields=created_at,description,public_metrics" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
Response:
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"id": "2244994945",
"name": "X Developers",
"username": "xdevelopers",
"created_at": "2013-12-14T04:35:55.000Z",
"description": "The voice of the X Developer Platform",
"public_metrics": {
"followers_count": 570842,
"following_count": 2048,
"tweet_count": 14052,
"listed_count": 1672
}
}
}
```
[Learn more about fields →](/x-api/fundamentals/fields)
***
## More examples
```bash theme={null}
curl "https://api.x.com/2/tweets/1460323737035677698?tweet.fields=created_at,public_metrics" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
```bash theme={null}
curl "https://api.x.com/2/tweets/search/recent?query=from:xdevelopers&tweet.fields=created_at" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
```bash theme={null}
curl "https://api.x.com/2/users/2244994945/tweets?max_results=5" \
-H "Authorization: Bearer $BEARER_TOKEN"
```
***
## Using code instead of cURL
```python theme={null}
import requests
bearer_token = "YOUR_BEARER_TOKEN"
url = "https://api.x.com/2/users/by/username/xdevelopers"
headers = {"Authorization": f"Bearer {bearer_token}"}
response = requests.get(url, headers=headers)
print(response.json())
```
```javascript theme={null}
const bearerToken = "YOUR_BEARER_TOKEN";
const url = "https://api.x.com/2/users/by/username/xdevelopers";
fetch(url, {
headers: { Authorization: `Bearer ${bearerToken}` }
})
.then(res => res.json())
.then(data => console.log(data));
```
For production use, we recommend the official SDKs:
* [Python SDK](/xdks/python/overview)
* [TypeScript SDK](/xdks/typescript/overview)
They handle authentication, pagination, and rate limiting automatically.
***
## Tools for testing
Visual API testing with our collection.
Examples in multiple languages.
Full endpoint documentation.
***
## Troubleshooting
* Check that your Bearer Token is correct
* Ensure the token hasn't been regenerated
* Verify the `Authorization` header format: `Bearer YOUR_TOKEN`
* Your app may not have access to this endpoint
* Some endpoints require user-context authentication (OAuth 1.0a or 2.0)
* Check your app's permissions in the Developer Console
* You've hit a rate limit
* Check the `x-rate-limit-reset` header for when to retry
* Implement exponential backoff in your code
[Full error reference →](/x-api/fundamentals/response-codes-and-errors)
***
## Next steps
Understand OAuth for user-context requests.
Discover what you can build.
Faster development with official libraries.
Ideas for what to create.
# Subscribe to developer news
Source: https://docs.x.com/newsletter
Subscribe to the X Developer Platform newsletter for product updates, new endpoints, deprecations, events, and other news for API developers.
Sign up for emails about the latest news, product updates, and events from the X Developer team.
# X Developer Platform
Source: https://docs.x.com/overview
Build, analyze, and innovate with X's real-time global data. Access posts, users, trends, and more through modern APIs with flexible pay-per-usage pricing.
## Products
Choose the access level that fits your needs.
Credit-based pricing with no commitments. Pay only for what you use.
High-volume endpoints, dedicated account management, and custom rate limits.
Earn free [xAI API](https://docs.x.ai) credits when you purchase X API credits — up to 20% back based on your spend. [Learn more](/x-api/getting-started/pricing#free-xai-api-credits)
***
## Get started
Owned Reads let you access your own data at reduced cost. Requests for your own posts, bookmarks, followers, likes, and more are priced at \$0.001 per resource.
Get your API keys and make your first request in minutes.
Explore endpoints for posts, users, spaces, DMs, lists, and more.
Official Python and TypeScript SDKs for faster development.
***
## Resources
Step-by-step guides for common use cases and integrations.
Official SDKs and community libraries for every language.
Get help from the community and X team.
llms.txt, skill.md, MCP servers, and resources for AI-powered development.
***
## Other products
Programmatically manage ad campaigns, targeting, creatives, and analytics.
# Success Stories
Source: https://docs.x.com/success-stories
Customer success stories from developers and businesses building with the X API, including case studies across marketing, research, healthcare, and finance.
Companies and individuals all over the world have used the X Developer Platform to creatively innovate, gain valuable insights, and shape the future.
## Browse success stories
# Banco Pichincha x X
Source: https://docs.x.com/success-stories/audiense-banco-pichincha
How Banco Pichincha used X advertising and Audiense audience intelligence to boost sponsorship results and engage Ecuadorian football fans.
## How enhanced targeting enhances success
Sponsorships are no longer just a tool to gain notoriety – when engaging audiences, they can also deepen connections between fans and brands through unique experiences.
This is the exact goal that Banco Pichincha had in mind when they developed *El Diez de la Trivia* and *Trivia de Oro* to enhance sponsorships with football teams such as *Liga Deportiva Universitaria de Quito*, *Barcelona SC*, and *Universidad Católica* and with the *Ecuadorian* cyclist Richard Carapaz, respectively.
Banco Pichincha is a leading Ecuadorian financial institution, controlling a 30% market share. It also has a presence in Spain, Colombia, Peru, Panama, and the United States.
The bank activates trivia quizzes during the Ecuadorian soccer championship and the great cycling tours to test fans on their knowledge. They offer a way for fans to experience unique moments through prizes that range from signed shirts to meetings with athletes to attendance at training sessions.
## Challenges and goals
These trivia quizzes have evolved since their inception, with many changes implemented to drive more participation: they adjusted the questions to make them easier and expanded the participation metric beyond Retweets to include Likes as a trigger.
They also added the option to share the trivia contest along with a predetermined text so they could encourage more people to participate.
However, Banco Pichincha’s initial audience target was too wide resulting in engagement tactics that weren’t reaching the right people.
## Solution
Banco Pichincha used [Audience Manager](https://help.audiense.com/knowledge/audience-manager), a network graph analysis function of [Audiense Connect](https://resources.audiense.com/blog/what-can-i-do-with-audiense-connect-twitter-marketing-plan), to create Custom Audiences of creators and amplifiers. This allowed them to focus their advertising with their unique audience more effectively.
> *“We talk to everyone: our brand audience and a whole lot more. But through media, we target only those creators and amplifiers that allow us to reach the audience we want.”*
>
> * Carlos Serra from Audiense
For the Richard Carapaz-themed trivia quiz, Banco Pichincha were able to create three distinct custom audiences:
1. An audience related to the sport i.e., people who are fond of cycling in Ecuador, people who are fans of Barcelona Universidad Catolica, etc.)
2. An audience of influencers for the first audience. These influencers helped with amplification through a bigger bid in the X ads campaign. This could only be done using graph segmentation and tailored audiences.
3. An audience of “followers of”: Utilizing the follower graph to identify relevant people in the world of cycling who were based in Ecuador. Audiense Connect helped them identify the 100 most relevant accounts and their followers, which they included in the following targeting.
Using the insights from Audiense, the banking institution was able to understand and analyze what their audience cared about to shape and evolve the trivia.
They identified the engagement metrics they could generate, which would allow them to take better advantage of sponsorships. This helped to generate a more meaningful connection with customers and fans of the team.
Banco Pichincha began running a paid campaign on X in August 2021. The campaign started on August 12, 2021 and involved 40,161 Tweets using the hashtags `#ElDiezDeLaTrivia` and `#LaTriviaDeOro` . Banco Pichincha used both the Retweet trigger and Likes trigger for engagement. From August 2021 to August 2022, the campaign saw almost 22,000 participants of the 28 trivia quizzes.
## Results
By increasing the relevance in targeting, Banco Pichincha was able to increase trivia participation by 10 times.
> *“Our ongoing data analysis, the formulation of growth hypotheses, and the execution of experiments to validate them, were key elements to maximize the power of the community, which is very active on X and follow our sponsored teams and athletes. The results of this exercise, along with a strategic segmentation, allowed us to grow from 366 unique users during the first trivia in August 2021, to 3291 in the last Richard Carapaz trivia, that took place last June 2022.”*
>
> * Patricia A. Villarruel Gordillo, Content Director at Banco Pichincha
From August 2021 to July 2022, they generated a total of 12,628,660 impressions at a CPM of €0.48 ($0.49 USD). They also collected 228,732 Tweet engagements at a cost per engagement of €0.11 ($0.11 USD), where engagements refer to the actions that fulfil the campaign objective. This may be an action such as watching a video in a promoted video views campaign.
### Conclusion
Whether it’s to drive more purchases or more trivia participation, conversions are the ultimate goal for any marketing campaign. To achieve this goal, you need to make sure that the right people come across your campaign. This is why fine-tuning segmentation to reach niche audiences, and why specific targeting, is so important for success.
Using a solution like Audiense Connect in combination with Twitter API can help you engage the right target with your content – to drive the success you’re looking for.
[Sign up today](https://dashboard.audiense.com/app/signup/connect) to build your tailored audiences.
# Canada Excellence Research Chair (CERC)
Source: https://docs.x.com/success-stories/cerc-academic-research
How researchers at the Canada Excellence Research Chair use the X API to study migration, refugees, and public discourse with full-archive social data.
Canada Excellence Research Chair (CERC)
Using Twitter’s API to fuel academic research
**Here's the tl;dr**
Learn how Stein Monteiro — research fellow for the Canada Excellence Research Chair (CERC) in Migration and Integration at Ryerson University — was able to use Twitter data to further his research on the relationship between the Indian diaspora and India during the farmers’ protests.
For Stein Monteiro, the farmers’ protests in India presented an interesting question: how would the Indian diaspora act during a time when major events took place in India? With the help of Twitter’s API, he was able to uncover the answer. Read about it here.
## Challenge
For Stein Monteiro — research fellow for the Canada Excellence Research Chair (CERC) in Migration and Integration at Ryerson University — work lies at the intersection of statistics, culture and current events. While his economics expertise set him up for success in academia, it was his own experience that fuelled a passion for migration studies.
Born and raised in India, Stein lived in Dubai during his high school years before heading to Canada for his undergraduate degree. For him, the feeling of being new to a country was deeply familiar. He was no stranger to the experience of navigating new social systems, climates and ways of life. The process of adjusting to new cultures and environments sparked his interest in the migrant integration journey. As he continued his studies in economics, the draw of these more personal experiences remained compelling — so he sought to combine both worlds. In order to obtain his PhD in economics, he focused his dissertation on migration studies literature.
While working on this dissertation, Stein taught himself how to code. When he later worked as a statistician for Humber College, he was able to put what he learned into practice. Coding enabled the process of automation — simplifying his work by organizing and crunching data.
By placing his work process into coding form, Stein was able to identify problems more easily and explain his work/thought process in a step-by-step manner to others. It opened up a whole new way of looking at a problem and building solutions. He was slowly realizing the unlimited potential of this skillset, and he took this knowledge with him to the Canada Excellence Research Chair (CERC).
While at CERC, Stein’s attention was captured by the online activism he witnessed all over social media, particularly around the Indian farmers’ protests (sparked by three controversial laws introduced in August, 2020). He could see connections between these protests and his work. This was an important moment: what was happening in real-time could reveal information about the migrant and diaspora experience as a whole.
As the conversation exploded around him, he wondered how online activism was affecting the activity of people in the Indian diaspora living in Canada, the UK, Australia, and the Gulf countries. How are social networks connecting migrants to the conversations in India?
It was time to get to work.
## Solution
In order to better understand the relationship between the Indian diaspora and their connection to the farmers’ protests, Stein knew he had to tune into the online conversation — so he set his sights on Twitter.
According to Stein, “these local events were able to cater to an international audience, not just because Twitter is an international phenomenon but also because people, just regular people, were able to speak to each other online, and they were able to connect with each other, just through a hashtag.” For him, with Twitter, “you can be a participant in the farmers' protests happening in India and not be Indian, or be Indian but be in a different part of the world.
Stein saw Twitter as the place involving the protestors, anti-protest rhetoric, pro-government entities, and unfiltered experiences of what was actually happening on the ground. And he wanted in on the action.
Absorbing the conversations, Stein needed to home in on a few things: when someone posts something online in India, how does that Tweet carry to the rest of the world? How does information flow through networks, hashtags etc.? And how is the diaspora responding to the Tweets coming in from India?
Stein was able to gain clarity with the help of Twitter’s API, which introduced the Academic Research product track, allowing access to historical data in addition to large volumes of Tweets and author information for further analysis.
To Stein, the power of the API was accessibility over a large period of time that would allow him to create a time dimension of conversations — who’s Retweeting what and who’s talking to whom.
With all this information at his disposal, he was shocked by what he found: there was an enormous level of activity from the Indian diaspora reacting to the situation in India. Stein says, “it wasn’t even delayed activity, it was almost immediate. So within the span of a day, I was seeing Retweets from people posting in India and then Retweets happening within the rest of the world.”
The data was clear: social media enables migrants and diasporas to stay connected to their home countries and play active roles in important conversations.
## Impact
Using Twitter’s open API, Stein was able to research a timely event that provided insight into the greater conversation of the migrant experience. Access to data and functions to filter and sort that data proved pivotal to this project.
More importantly, Stein recognized the importance of Twitter as a tool for academic research as a whole. For him, one of the biggest hurdles in research is that data needs to be gathered from across the globe. Fortunately, Twitter’s international presence provides this access to global information, without the need to spend lots of money on surveys and focus groups in various parts of the world.
Stein notes, “Twitter allows researchers and the academic community to access data for their own research purposes in a new way, to develop new methodologies, but also in a cost-efficient way.” He believes the conversations happening online were useful because “they were very unfiltered and they were unbiased conversations happening between people without the interference of the researcher in that conversation.”
Stein’s work proved that Twitter remains a tool for connection across the globe — while Twitter’s APIs can help gather large-scale insights that spring from that connection.
# Decoding Hate
Source: https://docs.x.com/success-stories/decoding-hate
How the Decoding Hate project used the X API to analyze personal experiences of hate incidents during COVID-19 and surface patterns for researchers.
## Situation
Following the outbreak of COVID-19, there was a rise in hate incidents directed towards Asian Americans and Pacific Islanders (AAPIs). While some of these incidents were covered in the news, thousands of individuals were filing reports with the national reporting center [Stop AAPI Hate](https://stopaapihate.org/), which responds to and addresses hate incidents through research, advocacy, and capacity-building. During this time, [The American Asian Foundation (TAAF)](https://www.taaf.org/) was founded. This organization became the driving force behind the team that decided to leverage X to provide a new window into how these incidents are personally affecting the people targeted.
## Solution
The small team of two engineers looked to X as their source for incident data. They chose this platform for two reasons: firstly, it contains rich and diverse information, such as news, people's ideas, thoughts, daily life events, and things happening in their communities. Because of this, X offers a unique, intimate sample of various populations. X is also the only platform with a truly open API where the TAAF developers could access data and has in-depth tools to collect and analyze that data.
Using the X API v2 search Tweets and Tweets lookup endpoints, the team was able to search post statuses and identify when people reported a hate incident (and even what hashtags they would use). This helped the team design a 1023-character search query that narrowed the billions of posts down to an amount the team could work with.
Next came the task of verifying that the posts were indeed about hate incidents. The team developed a tool with natural language processing to help sift through thousands of posts to find ones relevant to the project. After applying their trained machine learning model, the posts were then verified by a human to further increase accuracy.
In 2021, TAAF also co-authored the [Documenting Anti-AAPI Hate Codebook](https://stopaapihate.org/wp-content/uploads/2021/12/SAH-x-TAAF-Codebook-FINAL-2021-08-19.pdf) with the Stop AAPI Hate coalition. This resource includes draft standards and practices for community-based data collection which helped the team classify incidents that people were sharing over X.
From there, the next challenge was to present this data in a way that people could easily digest. TAAF created a data visualization tool, [Decoding Hate](https://decodinghate.taaf.org/), that displays their vast amount of data in an interactive way. With the help of a data visualization studio, they were able to take the annotated X data and turn thousands of posts into insightful stories that expose the truth behind what was happening within AAPI communities.
## Impact
The Decoding Hate project helped detect thousands of hate-related incidents that were otherwise going unreported and continues to do so today. This project has become an ongoing tool for spreading awareness of the individual experiences taking place within the AAPI community.
For the next phase of work, TAAF will be partnering with Stop AAPI Hate to pilot individual human responses to individuals who report hate incidents on X. During this phase, Stop AAPI Hate will actively engage with many of the people sending posts discussing the hate they have experienced and encourage them to report the incidents through the [Stop AAPI Hate Reporting Center](https://stopaapihate.org/). The more people who report to Stop AAPI Hate, the better the coalition and its partners can understand the nature of hate incidents that are taking place and advocate for the most effective policy solutions.
Along with exposing the hate-related incidents going on in AAPI communities, the project also shines a light on the value of X’s API. This case shows us that by leveraging the right data with the right tools, developers can use X to innovate for a good cause.
# Flocknet
Source: https://docs.x.com/success-stories/flocknet
How Flocknet uses the X API to help users discover and reconnect with people in their network, surfacing meaningful relationships across the platform.
**Here's the tl;dr**
Here’s how Aaron Ng—developer and creator— was able to use X’s API to build Flocknet, a search engine for your X network. People are using Flocknet to expand their networks, recruit talent, and source investment leads. Initially built for his own personal use, Flocknet is now helping people manage millions of contacts on X.
## Challenge
When Aaron Ng attended a design conference in New York, he wanted to connect and meet with others in his industry. But that’s when he realized connecting, even with his own designer friends on X, was more challenging than he thought. Much of his community was on X, especially his friends in the industry. Was there no way for him to see which of his friends would be in town? How could he catch up with industry connections, without knowing who would be around?
Aaron immediately saw this challenge as an opportunity. And as a result of his entrepreneurial spirit, Flocknet was born.
## Solution
In just one weekend, Aaron was able to build a product for searching, sorting, and keeping up with people, friends, and other professionals in his X network, even without seeing their Tweets. He chose to use X’s API for this project, “knowing there’s someone I can ask questions to, and \[knowing the X] team cares, makes it a much nicer experience.” Adding, “much of the community that motivated me to keep building was on X — which is why it’s become such an important place to me, and why I wanted to make some tooling to enhance my usage of it.”
With a mix of his own creativity, drive, and experience, Flocknet came to life—a search engine and contact management tool for finding people in your X network. Utilizing X’s follows endpoints and Python, Flocknet allows users to search through their followers by job, workplace, location, and numerous other attributes.
While initially meant for his own personal use, Flocknet generated so much public interest, that he knew it was meant to be shared. As such, he quickly shifted his efforts to scale up Flocknet to be what it is today.
## Impact
In just a few short months, Flocknet manages millions of contacts on behalf of its users. Tech professionals have found it especially useful, using it for everything from recruiting to investing, and anything in between. In fact, even Aaron has hired people through Flocknet!
But Aaron’s not done, just yet. By focusing on the incoming feature requests, Aaron continuously looks for ways to build out the product.
Ultimately, Aaron found a way to turn X into a meta-platform to enhance the experience of anyone whose community primarily exists on X. He says, “I just make a lot of stuff. And I love making things that I find useful and other people find useful”. And that’s exactly what he did.
# GSK x Meltwater
Source: https://docs.x.com/success-stories/gsk-meltwater
How GSK and Meltwater used X API data to identify and activate healthcare professionals as influencers, expanding reach in regulated medical communities.
**Here's the tl;dr**
We’re taking a closer look at how GSK Consumer Healthcare — a global British pharmaceutical company whose mission is to deliver better everyday health with humanity — was able to reach healthcare professionals active on X, in an effort to establish these professionals as influencers. This case study highlights how Meltwater helped GSK zero in on the necessary X data to make this endeavor possible.
## Situation
Both Influencer marketing and healthcare are ubiquitous in today’s society, but the two industries don’t often intersect. It was this gap that GSK — a British-based pharmaceutical company — sought to close.
As social media usage has continued to increase, healthcare companies are aware of the importance of meeting their audience where they are. And GSK saw the opportunity to tap into this new market to identify healthcare professionals for future collaborations and business opportunities. They also recognized X as the perfect social media platform for deeper insights.
The effort started with the online oral health space — GSK’s largest category at £2.7B in sales for fiscal year 2020. The goal was to capture interests among experts in the oral health space and determine the relationships between stakeholders. For example, during COVID-19, hygienists were more active and engaged on X than dentists. Due to the nature of their job, hygienists were at a much higher risk for infection — so they went online to give guidance on what was safe to do given the situation.
## Solution
The team at GSK knew that healthcare professions are well-represented on X. In order to tap into that data source, they turned to Meltwater — a platform with 10 years’ experience streamlining X’s breadth of information.
Using Meltwater’s search operators, GSK could specifically filter those who disclosed relevant professions in their bios and posts. Then, they expanded the search with specific keywords and phrases relevant to online dialogue in the field. Additional filters helped them zero in on organic conversations and trends across X, while cutting out irrelevant posts, reposts, and post replies.
## Impact
With the implementation of Meltwater's search operators, GSK saw a decrease in research turnaround time from 2 months to about 2-3 weeks. This report was formerly a time-intensive and bespoke process, which became more streamlined with the new operators. With less time spent on analysis, GSK was able to effectively reach 2.3K healthcare professionals.
Dentists and hygienists proactively post information for their followers and respond to individual questions, serving as the voice of reason for those inquiring about dental procedures. For this reason, positioning them as influencers provides people with a trustworthy source of healthcare knowledge.
The saved search library in Meltwater Explore was a vital tool that gave GSK precision data from an on-demand community of healthcare professionals on X. It allowed for them to gather leading insights from young and more digitally-savvy professionals as they move from their healthcare training to become the next big players in the real world. The result was a blueprint that they’ve successfully applied across their 20+ US brands to help create groups of healthcare professionals for potential business partnership opportunities.
*Source: Meltwater Explore, Jan 2020 - Feb 2021, retrieved March 2021.*
# ListenFirst boosts efficiency with X API v2
Source: https://docs.x.com/success-stories/listenfirst-x-improving-efficiency
How ListenFirst used X API v2 to streamline data aggregation, improve accuracy, and deliver unified social analytics to marketing clients.
## Situation
Historically, digital marketers have lacked a unified view of their data. There could be organic data in one system, paid data in another, and conversations coming from different places. But with clients and stakeholders asking questions like, “How many impressions did I receive yesterday?” followed by “What is the organic vs paid split?,” the need for a streamlined way to aggregate and interpret this data is more important than ever.
Looking to solve these questions, ListenFirst - a social analytics platform that has been built with the X Developer Platform for over 10 years – needed to create a tool to collect organic and paid X data from a single source of truth. Historically, this organic and paid data lived in separate silos across different platforms, APIs and endpoints; and was certainly never meant to be aggregated, sumed and/or blended together.
## Solution
In the quest to find more efficient ways to drive insights for their clients, ListenFirst adopted X’s v2 endpoints to streamline their translation of what users are talking about on X into their platform. ListenFirst’s team got to work with one clear goal in place: to create cleaner data.
> *“For us, utilizing v2 is about integration optimization. If there are fewer pieces we have to put together on our site, it makes our operations easier and allows us to scale our offering to even more brands, more content and better insights.”*
>
> * Jonathan Farb, Chief Product Officer, ListenFirst.
What drove the team to prioritize the adoption of X’s v2 API, and specifically the Tweets lookup endpoint, was the accuracy of the engagement and impressions numbers. By utilizing this endpoint, ListenFirst was able to generate more reliable metrics that were aligned with what their customers saw on native X analytics elsewhere.
## Impact
While still in its infancy, adopting v2 has impacted ListenFirst’s efficiency. Historically, ListenFirst had to piece together data from various sets of APIs, and the numbers weren’t aligned with what was seen in native analytics. Their usage of v2 brings ListenFirst’s numbers closer to parity with X’s native analytics, improving accuracy and customer trust. Now, ListenFirst can produce defensible and refined intelligence to help brands complete their marketing strategy on X. ListenFirst believes that further adoption of v2 will drive confidence in client metrics by improving accuracy and transparency.
# Publicis x YouScan
Source: https://docs.x.com/success-stories/publicis-youscan
How Publicis Sport & Entertainment used YouScan and X API visual listening to surface sports marketing insights from images and brand mentions.
## Situation
Sponsorships and marketing strategies are the driving force behind sports brands today. Understanding how they work is key to discovering what consumers need and how they behave towards their products. They're a way to get a realistic view of the audience turnout for each sport, what kind of engagement different sponsorship activities bring to their competitors, and whether there is any strong association between sports audiences and sports brands. Publicis stepped up to the plate to help a major sports brand decide if including sports sponsorship activities in their marketing strategies.
## Solution
For this research, Publicis teamed up with YouScan – a social media intelligence platform with image recognition capabilities. Its visual insight technology allows users to analyze visual brand mentions and obtain advanced analytics thanks to artificial intelligence and machine learning. The platform identifies more than 1,000 scenes, objects, and activities along with demographic information to provide brands with in-depth analytics.
Using YouScan, Publicis analyzed 1.9 million images, targeting X as one of the main sources with more than 150k images (mentions). X is special because customers share their unbiased opinions, life moments, feedback and thoughts with the X community, helping brands receive a comprehensive overview of consumer behavior.
The agency used visual data as a foundation for this research and collected images featuring Nike, Adidas, Puma and Reebok logos in the US, UK, and Canada (coming from accounts with disclosed geo-location) over a two-month period (May-June 2022).
From there, YouScan’s analysis showed that around 22% of the mentions did not contain a word or hashtag with the brand and only contained a visual representation – including the brand logo or the brand name spelled somewhere in the visual (text recognition).
## Impact
Publicis’ research using YouScan allowed a major sports brand to identify its strategy for 2023 sponsorship activities, receiving detailed analytics on the number of unique images, engagement, and distribution that each of their competitors has in major sports.
After analyzing 1.9M images, more than 150k on X, 462M engagements and 901k authors, YouScan’s’ top five findings of the research were:
* Nike’s logo appeared in publications about different types of sports significantly more frequently than other brands (77.2%).
* Nike is the brand that generates the highest engagement (38.9M).
* Football (soccer) generates the most engagement for almost all sports brands (Nike, Adidas, Puma), making it the most effective sponsorship activity in terms of visibility.
* The top logo on helmets was Nike (84%). Adidas appeared on shorts (22%) and shirts (32%).
* The number of men featured (86.3%) significantly outnumbers the number of women (13.7%), so it hints at a potential CSR problem and an opportunity at the same time.
This is a great example of how analyzing consumer opinions, discovering actionable insights and managing brand reputation can keep brands relevant in daily trend discussions while putting the customer experience at the heart of the business.
# PublicSonar X Municipality of The Hague
Source: https://docs.x.com/success-stories/publicsonar
How PublicSonar and the Municipality of The Hague use X API social monitoring to improve traffic flow, public safety, and emergency response in real time.
**Here's the tl;dr**
Here’s how the municipality of The Hague was able to increase mobility and safety of their roads through a partnership with PublicSonar — a company that helps organizations make informed decisions using AI-driven insights. Through leveraging social insights, PublicSonar provides additional information to help The Hague traffic control center act quickly and effectively to evolving road conditions.
## Challenge
Across continents and time zones, traffic is an unpredictable, chaotic facet of daily life. It’s an experience shared across the world, impacting the lives of many. Efforts to regain control of the roads are constantly underway, yet few places have taken matters more seriously than the municipality of The Hague.
The Hague traffic control center invested in technology and intelligence tools like CCTVs and underground sensors, with the goal of providing quick, safe solutions and responses to the traffic-related incidents that inevitably arise in a large city. However, one challenge remained: how could they get the right information, in real time, in order to make the best decisions?
Despite their advanced technological toolkit, The Hague traffic control center was still missing some key information. In order to help fill those gaps, they turned to PublicSonar — a company that helps organizations make informed decisions by using AI-driven insights.
## Solution
The biggest hurdle to increasing mobility and providing safety is the ability to gain information from the ground. Fortunately, by partnering with PublicSonar, the municipality of The Hague was able to uncover the missing puzzle piece to traffic control: social media.
Enter X. X’s real-time conversations were pivotal in providing insights for PublicSonar to fill in information gaps.
For PublicSonar, the way in which X data is offered, and the stability and support from X's API, is crucial for their work. Through the use of keywords, they were able to filter information for traffic-related topics, which they used to create an easily digestible online dashboard for the Municipality of the Hague to utilize. Their value is finding the balance that avoids too many false positives that will overload the traffic control center, while also ensuring no important information is missed.
## Results
Through social media monitoring, PublicSonar provides The Hague with insights that allow them to make appropriate decisions during planned events (i.e concerts), typical situations (i.e. busy beach days), and incidents (i.e. car accidents).
Ultimately, both technology and social insights work hand in hand to create a clearer picture, with social media providing more “eyes on the road.” These streams of information keep the fingers of the traffic control center on the pulse of what’s happening, so that they can continue to provide The Hague with safer and smoother driving conditions.
# Red Cloud Financial Services
Source: https://docs.x.com/success-stories/red-cloud-financial
How Red Cloud Financial Services uses X API data to track market sentiment, surface trading signals, and inform investment research workflows.
**Here's the tl;dr**
Trending towards success: When Red Cloud Financial Services was tasked with helping a mining company market their new green technology, it turned to Audiense’s targeting tools built on X analytics to mine the data and reach new audiences.
## Situation
Red Cloud Financial Services was tasked with helping its client, a publicly-traded mining company, raise awareness about new patent-pending technology they had developed with a brand new audience.
The company had to find a way to drive results for this new product in order to transition into new territories and effectively run a campaign that would reach those new customers.
The ask posed two key challenges:
1. **Reach a new audience**
Rather than focus on their existing mining customers, the client’s new technology appealed to a broader segment interested in green innovation and social responsibility. These were uncharted waters for Red Cloud, and nothing like the previous campaigns it had run.
2. **Provide a concrete ROI**
The client was not accustomed to doing paid campaigns. The expectation for Red Cloud to spell out the ROI of an awareness-based campaign and produce results with an audience it had limited firsthand experience with was a daunting task.
Red Cloud turned to Audiense to help reach current customers while researching prospective new ones. Audiense’s X marketing product specializes in delivering impactful X campaigns using its powerful audience targeting tools.
## Solution
Red Cloud began by setting expectations. Leveraging insights from Audiense to create campaign performance forecasts, Red Cloud was able to set the client’s expectations regarding the end-goals and associated KPIs of the campaign.
With help from Audiense, Red Cloud focused its research on X for mining company news and related stock information. Audiense’s platform made it easy to find potential correlations between the campaign and increased interest reflected by video views and increased website traffic.
A 3-tiered approach:
1. Build brand new audiences.
Taking direction from its client, Red Cloud Financial identified two primary audiences to focus the campaigns on: the first segment included mining and investment, the second clean tech, electric vehicles, ESG and responsible investing. X's data further helped Red Cloud align those audiences with future campaigns.
2. Segment the new audiences.
Although the new audiences covered a wide range of industries, there were plenty of common threads between them. Audiense helped Red Cloud Financial mine these new segments to identify influencers, content consumption habits and more. These insights also helped them determine which accounts to follow in hopes they would reciprocate and grow the Red Cloud and client audiences.
3. Determine which is most valuable.
Determine which is most valuable. Using Audiense’s [Targeting Pack feature](https://help.audiense.com/knowledge/what-is-a-targeting-pack), Red Cloud created laser-targeted paid X ad campaigns, while using the accumulated data for X segments for organic campaigns. Leveraging insights derived from the Targeting Pack feature, Audiense and Red Cloud created two unique videos targeting the two audiences. They were able to determine which video was consistently the top-performing campaign and stay on track with their targeting.
## Impact
Audiense’s platform and their X research helped Red Cloud find the right audiences, segment them, leverage them to grow followers and inform its overall social media strategy for both organic and paid content.
Red Cloud Financial exceeded its client’s expectations. In fact, the results of the campaigns were so positive, the client decided to move forward and ramp up another one.
* The combined campaigns garnered 3.5+ million impressions and 2.8+ million total views
* There was a rise in conversation volume related to the client’s new patent-pending technology
* They noticed a boost in website referral traffic, including 7,000 new visitors from the promoted article and press release about their new technology
This is a prime example of how audience analytics and targeting on X can help you tap into new audiences, refine marketing campaigns and deliver real results. It can be a golden opportunity to help build your clients’ brands and boost their business.
# SMASH x Audiense
Source: https://docs.x.com/success-stories/smash-and-audiense
How SMASH and Audiense leveraged X API audience intelligence to identify valuable followers and expand brand reach with data-driven targeting.
**Here's the tl;dr**
We’re taking a closer look at how SMASH was able to spread the word about its cause and reach key influencers, in an effort to raise \$500,000 to provide students of color with access to college and career resources. This case study highlights how Audiense helped SMASH to utilize X data to reach the most relevant audiences for this cause.
## Situation
Following a wave of social justice activism in the summer of 2020, SMASH – a nonprofit organization dedicated to helping provide students of color access to college and career readiness resources – saw the opportunity to ramp up fundraising and spread the word about its cause.
SMASH created #SMASHmatch, a six-week campaign during June - July 2020 with the goal to raise \$500,000 through a 1:1 match from a SMASH donor.
The goals of the organization’s social media push and #SMASHmatch campaign were two-fold:
1. Build greater awareness of SMASH and how the organization is looking to develop the next generation of socially conscious STEM leaders, providing corporate donors a meaningful cause to support in the fight against systemic racism.
2. Raise money from new and existing SMASH donors.
With such a large goal, SMASH acknowledged that they’d need to take a direct approach to outreach.
SMASH turned to Audiense, whose X Marketing product specializes in delivering impactful X campaigns thanks to its powerful audience targeting, to determine who their best outreach candidates were and how many potential donors were fair game based on their existing X followers.
Rather than SMASH combing through their follower list by hand, Audiense did the heavy lifting. Their platform made it easy to sort X followers based on their reach, follower count, and other parameters relevant to the campaign.
## Solution
SMASH took a three-point approach to raise funds and build awareness:
1. Use X to promote the campaign and reach out to specific influencers for donations.
2. Promote the \$500,000 donor match to inspire existing donors to renew their gift.
3. Motivate corporate donors to partner with SMASH to double their impact throughout the campaign.
Below are the steps SMASH took and how they used Audiense’s analytics platform to build their fundraising campaign.
1. **Identify their engaged, verified social media influencers**
Thanks to Audiense, SMASH streamlined its campaign by knowing exactly who its most engaged followers were and which ones had the most reach via X verification. These would become prime outreach candidates not only for securing donations but also for spreading the word through Retweets.
2. **Engage with their target audience directly and track results**
With Audiense’s data, SMASH was able to confidently approach its outreach candidates through Direct Tweets that requested donations and Retweets.
They managed to secure a $10,000 donation during the first day and received a staggering $500,000 donation to meet their original funder goal by day three. The campaign continued to rack up donations and Retweets with no signs of slowing down.
3. **Keep the momentum going by identifying new donors to target**
Using Audiense, the organization managed to explore relevant outreach candidates beyond their own followers and immediate network. The fresh outreach resulted in more verified Retweets and support for the campaign which came from athletes, actors, entertainers, political commentators, and other celebrities
## Impact
SMASH and Audiense’s efforts resulted in achievements far beyond their initial goals:
* The campaign raised more than \$1M during its six-week run.
* SMASH garnered over 20 million X impressions and 1,100 new followers (including some of the verified influencers that interacted with the campaign.
* Interactions with over 1,000 influencers.
* Shout-outs and Retweets from NFL and NBA players including Ezekiel Elliott, Alshon Jeffery, Baron Davis, and Isaiah Thomas.
When done effectively, audience targeting on X can help companies reach people – and goals – they otherwise thought wouldn’t be possible.
# Typefully x Raycast
Source: https://docs.x.com/success-stories/typefully
How Typefully and Raycast use the X API to help creators and companies draft, schedule, and optimize Posts and threads from a streamlined workflow.
[Typefully](https://typefully.com/) is very popular among creators, agencies, and teams for its minimal yet powerful interface, with more than 200k registered users. Among social media scheduling app, it’s the one that offers the simplest and most complete publishing and scheduling experience for X, and also the one with the best high-fidelity preview of how the content looks after publishing.
## The Challenge
Typefully was born a tool to write threads on Twitter, before it was rebranded as X. As users of the X API for many years now, they’ve always followed and updated X API developments closely to provide the best possible experience to their users, and adopt the latest features very quickly. By having a close relationship with X, Typefully has been able to support new X features quickly and offer a very complete publishing experience to their users.
## The Solution
[Typefully](https://typefully.com/) leverages several key features of the X API to power their core functionality, ensuring seamless publishing, analytics, and scheduling for their users.
For **post publishing and scheduling**, we rely on POST /2/tweets to support all post types—text, media, polls, and long-form posts—along with advanced thread management, auto-retries, and quote tweet handling. Typefully’s scheduling system integrates deeply with X, enabling timezone-aware posting, queue management, and automation features like auto-retweets and follow-ups.
**Analytics** is another key pillar, utilizing GET /2/tweets to provide real-time engagement tracking, historical data imports, and insights such as impressions, engagement rates, and link clicks. This data — 1M+ posts processed per month — feeds into their advanced analytics tools, helping users optimize their content strategy.
On the account management side, OAuth 2.0 and real-time verification ensure seamless multi-account support, with robust rate limit handling and token refresh mechanisms.
It’s exciting, as Typefully is a small team of just 5 people, to empower creators and companies via the X API to publish more than 130,000 posts every month.
## The Results
*Typefully*'s tight integration with the X API has made a real difference in how their users publish and manage their content — making Typefully one of the most dependable X publishing tools available. Their users particularly value the high-fidelity preview that accurately shows how content will appear after publishing, eliminating surprises after publishing.
[**A prime example is the Raycast whose team uses Typefully to manage multiple X accounts**](https://www.raycast.com/) - both their company profile and team members' personal accounts.
Their social media workflow is streamlined through our **collaboration features**, allowing team members to **share draft posts, leave feedback comments, and organize them with tags.** This coordinated approach has been particularly valuable for perfectly timing announcements and news about Raycast products and features.
The collaboration tools have eliminated communication silos for teams like Raycast, **reducing the time spent on social media management while improving content quality through close feedback loops**.
By leveraging the X API through Typefully, companies maintain a consistent and engaging social presence without the complexity typically associated with multi-account management. Teams can focus on creating quality content rather than dealing with publishing logistics, resulting in more effective communication on X.
# Developer Support
Source: https://docs.x.com/support
Find support channels for the X API, including the developer community forum, Stack Overflow, GitHub issues, status page, and contact options.
Whether you're troubleshooting an issue, looking for guidance, or want to connect with other developers, we've got you covered.
***
## Community and help
Ask questions, share your projects, and get help from the X developer community and team. This is the best place to get support for technical questions.
Check the current operational status of X API v2, Enterprise APIs, and the Developer Console.
***
## Contact and forms
Interested in enterprise-level API access? Submit your interest and our team will reach out.
Get help with billing questions for Self-serve and Enterprise API subscriptions.
Questions about policies, compliance, or need approval for specific use cases? Contact our policy team.
***
## Documentation and resources
New to the X API? Start here to get your API keys and make your first request.
Complete reference for all X API v2 endpoints, parameters, and response formats.
Learn about OAuth 1.0a, OAuth 2.0, and how to authenticate your API requests.
Official Python and TypeScript SDKs to speed up your development.
Understand rate limits and how to handle them in your application.
Reference for API error codes and how to resolve common issues.
***
## Policies and guidelines
Practical guide to what's allowed and what's not when building with the X API.
The binding legal terms for X API access.
Rules and expectations for building on X.
Activities that are prohibited or require special approval.
***
## Troubleshooting tips
* Double-check your API keys and tokens are correct
* Ensure you're using the right authentication method for the endpoint (OAuth 1.0a vs OAuth 2.0)
* Verify your app has the required permissions (read, write, DM access)
* Check that your tokens haven't expired—regenerate if needed
* Check the `x-rate-limit-*` headers in API responses to monitor your usage
* Implement exponential backoff when you receive 429 errors
* Cache responses where possible to reduce API calls
* Consider upgrading your access tier for higher limits
* See the [Rate Limits guide](/x-api/fundamentals/rate-limits) for detailed information
* Review the [Developer Guidelines](/developer-guidelines) to understand what may have caused the suspension
* Check your email for any communication from X about the suspension
* Submit an appeal through the [Policy Support form](https://help.x.com/forms/platform)
* Common causes: automated likes, unsolicited DMs/mentions, scraping, rate limit abuse
* Review the [pricing tiers](/x-api/getting-started/pricing) to find the right plan
* For enterprise needs, submit the [Enterprise API Interest form](/forms/enterprise-api-interest)
* For access upgrades, use the [Use Case Upgrade form](/forms/use-case/upgrade)
* Browse the full [API Reference](/x-api/introduction)
* Check if the functionality exists in [v1.1 endpoints](/x-api/migrate/overview) that may not be in v2 yet
* Ask in the [Developer Forums](https://devcommunity.x.com) if you're unsure
***
## Stay updated
Latest API updates, new features, and changes.
Follow for announcements and developer news.
History of past incidents and their resolutions.
# Tools & Libraries
Source: https://docs.x.com/tools-and-libraries
Official X API SDKs in Python and TypeScript, CLI tools like xurl, the playground server, MCP servers for AI, and community client libraries.
Speed up your development with official SDKs, developer tools, and community libraries.
***
## Official SDKs
Async support, type hints, and automatic token refresh. Perfect for data analysis and automation.
Full type safety and ESM support. Works in Node.js and modern bundlers.
### Quick start
```bash theme={null}
pip install xdk
```
```python theme={null}
from xdk import Client
client = Client(bearer_token="YOUR_BEARER_TOKEN")
for page in client.posts.search_recent(query="api", max_results=10):
if page.data and len(page.data) > 0:
print(page.data[0].text)
break
```
```bash theme={null}
npm install @xdevplatform/xdk
```
```typescript theme={null}
import { Client } from '@xdevplatform/xdk';
const client = new Client({ bearerToken: 'YOUR_BEARER_TOKEN' });
const userResponse = await client.users.getByUsername('XDevelopers');
console.log(userResponse.data?.username);
```
***
## Developer tools
Interactive API testing for all v2 endpoints.
curl-like CLI for the X API with built-in OAuth authentication. No manual token management.
Local mock server for testing X API v2 endpoints without using real credits.
XMCP, llms.txt, skill.md, docs MCP server, and resources for AI-powered development.
### Other tools
| Tool | Description |
| :------------------------------------------------------ | :---------------------------------------------------------- |
| [OpenAPI Spec](https://api.x.com/2/openapi.json) | Machine-readable API specification |
| [twitter-text](https://github.com/twitter/twitter-text) | Parse and validate post text, count characters |
| [Embed Generator](https://publish.x.com/#) | Build embeddable posts, timelines, or buttons for your site |
***
## Community libraries
Community-maintained libraries with X API v2 support. Check each library's documentation for current coverage.
| Library | Description |
| :----------------------------------------------------------- | :------------------------------------- |
| [tweepy](https://github.com/tweepy/tweepy) | Popular Python library with v2 support |
| [twarc](https://twarc-project.readthedocs.io/) | CLI and library for data collection |
| [python-twitter](https://github.com/sns-sdks/python-twitter) | Simple Python wrapper |
| [TwitterAPI](https://github.com/geduldig/TwitterAPI) | Minimal Python wrapper |
| Library | Description |
| :------------------------------------------------------------------- | :------------------------------------------- |
| [node-twitter-api-v2](https://github.com/PLhery/node-twitter-api-v2) | Strongly-typed, full-featured Node.js client |
| [twitter.js](https://github.com/twitterjs/twitter.js) | Object-oriented Node.js library |
| [twitter-v2](https://github.com/HunterLarco/twitter-v2) | Async client library |
| Library | Description |
| :-------------------------------------------------------------- | :---------------------- |
| [go-twitter](https://github.com/g8rswimmer/go-twitter) | Go library for v2 API |
| [gotwi](https://github.com/michimani/gotwi) | Go wrapper for v2 |
| [twitter-stream](https://github.com/Fallenstedt/twitter-stream) | Filtered stream wrapper |
| Library | Description |
| :---------------------------------------------------- | :--------------------- |
| [twittered](https://github.com/redouane59/twittered) | Java client for v2 |
| [twitter4j-v2](https://github.com/takke/twitter4j-v2) | Twitter4J v2 wrapper |
| [KTweet](https://github.com/ChromasIV/KTweet) | Kotlin v2 library |
| [Tweedle](https://github.com/tyczj/Tweedle) | Kotlin Android library |
| Library | Description |
| :---------------------------------------------------------------- | :-------------------- |
| [twitter-api-v2-php](https://github.com/noweh/twitter-api-v2-php) | PHP v2 client |
| [bird-elephant](https://github.com/danieldevine/bird-elephant) | PHP v2 library |
| [twitteroauth](https://github.com/abraham/twitteroauth) | Popular OAuth library |
| Library | Description |
| :---------------------------------------------------------------- | :---------------- |
| [tweetkit](https://github.com/julianfssen/tweetkit) | Ruby v2 client |
| [twitter\_oauth2](https://github.com/nov/twitter_oauth2) | OAuth 2.0 library |
| [omniauth-twitter2](https://github.com/unasuke/omniauth-twitter2) | OmniAuth strategy |
| Language | Library |
| :------------- | :--------------------------------------------------------------------------------------------------------- |
| **C#/.NET** | [Tweetinvi](https://github.com/linvi/tweetinvi), [LinqToTwitter](https://github.com/JoeMayo/LinqToTwitter) |
| **Rust** | [twitter-v2](https://github.com/jpopesculian/twitter-v2-rs) |
| **Swift** | [Twift](https://github.com/daneden/Twift/), [TwitterAPIKit](https://github.com/mironal/TwitterAPIKit) |
| **R** | [academictwitteR](https://github.com/cjbarrie/academictwitteR) |
| **PowerShell** | [BluebirdPS](https://github.com/thedavecarroll/BluebirdPS) |
Community libraries are not maintained by X. Check their repositories for support and current status.
***
## Code samples
* [X API v2 Sample Code](https://github.com/xdevplatform/Twitter-API-v2-sample-code) — Examples in Python, JavaScript, Ruby, and more
* [Code Samples Repo](https://github.com/xdevplatform/samples) — Examples using the official XDKs
* [X Developer GitHub](https://github.com/xdevplatform) — Official repos and tools
***
## X Ads API libraries
For tools and libraries specific to the X Ads API, see the [Ads API tools and libraries](/x-ads-api/tools-and-libraries) page.
# Agent Resources
Source: https://docs.x.com/tools/ai
Resources for AI agents using the X API, including llms.txt, skill.md, MCP servers, OpenAPI specs, and integration guides for Grok, Cursor, and Windsurf.
Resources for connecting AI tools to the X API and its documentation.
***
## Use the X API from AI tools
Give your AI agent the ability to call X API endpoints directly.
**MCP Servers** — XMCP exposes 200+ X API endpoints as callable MCP tools. Docs MCP lets agents search and read these docs on the fly.
**OpenAPI Spec** — Machine-readable API definition ([https://api.x.com/2/openapi.json](https://api.x.com/2/openapi.json)) for auto-generating clients or feeding into agents.
| Resource | What it does | URL |
| :--------------- | :------------------------------------------------------------------------------- | :----------------------------------------------------------- |
| **X MCP** | Hosted MCP server — agents can search, look up users, manage bookmarks, and more | [docs.x.com/tools/mcp](/tools/mcp) |
| **OpenAPI Spec** | Machine-readable API definition for code generation and agent tooling | [api.x.com/2/openapi.json](https://api.x.com/2/openapi.json) |
***
## Read X API docs from AI tools
Give your AI agent context on how the X API works.
**llms.txt / llms-full.txt** — Documentation index and full-content Markdown files for LLMs to ingest.
**skill.md** — Capability summary (agentskills.io) that tells agents exactly what actions, parameters, and constraints exist.
**Docs MCP** — Search and read any documentation page directly from your AI assistant via MCP.
| Resource | What it does | URL |
| :---------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| **llms.txt** | Documentation index — page titles, URLs, and descriptions | [docs.x.com/llms.txt](https://docs.x.com/llms.txt) |
| **llms-full.txt** | Complete docs in a single file for full-context loading | [docs.x.com/llms-full.txt](https://docs.x.com/llms-full.txt) |
| **skill.md** | Capability summary — actions, inputs, and constraints | [docs.x.com/skill.md](https://docs.x.com/skill.md) |
| **Docs MCP** | MCP server — agents can search and read doc pages on the fly | [docs.x.com/mcp](https://docs.x.com/mcp) |
# llms.txt & llms-full.txt
Source: https://docs.x.com/tools/llms-txt
Use llms.txt and llms-full.txt to give AI tools like Cursor, Windsurf, and Grok structured access to X API documentation for accurate code generation.
**llms.txt** — A structured index of all documentation pages (titles, URLs, short descriptions). Gives AI tools a map of what's available.
**llms-full.txt** — The complete documentation in a single Markdown file for maximum context.
The [`llms.txt` standard](https://llmstxt.org) is like a sitemap for AI. It helps LLMs understand your documentation structure and find relevant content — similar to how `sitemap.xml` helps search engines.
| File | What it contains | Best for |
| :-------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------- | :------------------------------------------- |
| [`llms.txt`](https://docs.x.com/llms.txt) | Curated root index + links to section indexes | Quick overview and agent entry point |
| [`x-api/llms.txt`](https://docs.x.com/x-api/llms.txt) | 370+ X API v2 reference pages | Posts, Users, DMs, Streams, Compliance, etc. |
| [`enterprise-api/llms.txt`](https://docs.x.com/enterprise-api/llms.txt) | Enterprise, Account Activity, GNIP, Webhooks | Historical + real-time enterprise data |
| [`x-ads-api/llms.txt`](https://docs.x.com/x-ads-api/llms.txt) | Ads API (campaigns, creatives, audiences, analytics) | Advertising and measurement |
| [`xdks/python/llms.txt`](https://docs.x.com/xdks/python/llms.txt) + [`xdks/typescript/llms.txt`](https://docs.x.com/xdks/typescript/llms.txt) | Full SDK client & model references | Python and TypeScript/JavaScript developers |
| [`llms-full.txt`](https://docs.x.com/llms-full.txt) | Entire docs as one Markdown file | Maximum context for deep reasoning |
These files (plus section-specific indexes under `/x-api/llms.txt`, `/enterprise-api/llms.txt`, `/x-ads-api/llms.txt`, and the XDKs) are available at the root and under `/.well-known/`. Every documentation page supports the `.md` suffix for clean Markdown (example: `https://docs.x.com/x-api/posts/get-post-by-id.md`).
***
## How to use it
**Strongly recommended for agents:** Start by reading [AGENTS.md](https://docs.x.com/AGENTS.md) (or AGENT.md) for explicit usage guidance.
Most AI tools accept URLs directly. Just provide the URL and the tool will fetch and parse the content:
* **Grok**: Paste `https://docs.x.com/llms-full.txt` into the chat and ask questions about the X API
* **Cursor / Windsurf**: Add `https://docs.x.com/llms-full.txt` as documentation context for your project
* **Custom agents**: Fetch the file programmatically and include it in your system prompt or context window
```bash theme={null}
# Fetch the documentation index
curl https://docs.x.com/llms.txt
# Fetch the complete documentation
curl https://docs.x.com/llms-full.txt
# Fetch any individual page as Markdown
curl https://docs.x.com/tools/llms-txt.md
```
# MCP servers for the X API and X developer docs
Source: https://docs.x.com/tools/mcp
Connect Grok, Cursor, and other AI tools to the X API and X developer docs through hosted Model Context Protocol servers using xurl and docs search.
Two [MCP](https://modelcontextprotocol.io) (Model Context Protocol) servers are available for working with X from AI tools:
| Server | What it does | URL |
| :----------- | :---------------------------------------------------------------------------------------------- | :------------------------------------------------------- |
| **X MCP** | Call X API endpoints (search posts, look up users, bookmarks, trends, news, Articles, and more) | `https://api.x.com/mcp` (hosted; connect via `xurl mcp`) |
| **Docs MCP** | Search and read X API documentation | `https://docs.x.com/mcp` (hosted) |
***
## X MCP — X API
Connect any MCP-compatible AI tool (Grok Build, Cursor, Claude, VS Code, and others) directly to the **X API**. The model can then search the full archive, look up users, manage bookmarks, fetch trends and news, and draft Articles — all with your own X account's permissions.
The X API exposes a hosted **Streamable HTTP** MCP server at **`https://api.x.com/mcp`** (protocol `2025-06-18`, `serverInfo: xmcp`). You reach it through the open-source **`xurl mcp`** bridge, which handles OAuth for you and injects a fresh Bearer token on every call.
### Capabilities at a glance
| Category | What the model can do |
| ----------------- | --------------------------------------------------------------------------------------------- |
| **Posts** | Fetch posts, see likers / reposters / quoters, recent counts |
| **Search** | Full-archive post search, user search, news search |
| **Users** | Resolve the current user, look up by id / handle, read a user's posts, timeline, and mentions |
| **Bookmarks** | List / add / remove bookmarks and manage bookmark folders |
| **News & Trends** | Get news stories, get trends for a location (WOEID) |
| **Articles** | Create draft Articles and publish them |
### How it works
X's OAuth requires *your own* developer app. There is no dynamic client registration, and `api.x.com/mcp` does not advertise native MCP OAuth discovery. Instead of pointing your client at the URL directly, you run a tiny local bridge. The bridge owns the app identity, performs the one-time login, and keeps the token fresh.
```mermaid theme={null}
flowchart LR
A["MCP client (Grok Build, Cursor, …)"] -- "stdio JSON-RPC" --> B["xurl mcp (local bridge)"]
B -- "HTTPS + Authorization: Bearer" --> C[("api.x.com/mcp")]
B <-- "OAuth2 PKCE login + auto-refresh" --> D["X OAuth"]
```
* The bridge runs via the **npm launcher** (`npx`), so there is **no separate install step**.
* On **first run with no cached token**, it opens your browser for a one-time OAuth2 login, then caches and **auto-refreshes** the token forever after.
* All diagnostics go to **stderr**; **stdout stays a clean JSON-RPC channel**.
### Getting started
Pick one of two routes:
* **Simple — App-only Bearer.** Paste your app's Bearer token into an `Authorization` header on the MCP client. No bridge, no browser login. Read-only endpoints; no user context (can't act as you). Works with clients that support remote MCP with custom headers.
* **Full — `xurl mcp` bridge (OAuth 2.0 user context).** A local bridge handles the OAuth 2.0 PKCE login and auto-refreshes tokens, so the model acts with your account's scopes. Required for writes (bookmarks, Articles) and any user-context tool.
#### Simple route (app-only Bearer)
1. **Create an X app** in the [X Developer Portal](https://developer.x.com).
2. **Copy your App-only Bearer token** from the app's "Keys and tokens" page.
3. Point your client at `https://api.x.com/mcp` with the token as an `Authorization` header — see [App-only (direct URL, no bridge)](#app-only-direct-url-no-bridge) below for the snippet.
#### Full route (xurl bridge)
1. **Create an X app** with **OAuth 2.0** enabled.
2. **Register the redirect URI** `http://localhost:8080/callback` on the app (required for the first-run browser login). To use a different one, set `REDIRECT_URI` and register that instead.
3. **Copy your `CLIENT_ID` and `CLIENT_SECRET`** — you'll put them in the client config. If you ever run `xurl auth oauth2` manually (e.g., the headless flow below), export them as environment variables in that shell first — the login fails in the browser without them.
4. **Have Node.js installed** (for `npx`).
5. We recommend you **install [xurl](https://github.com/xdevplatform/xurl)**:
```bash theme={null}
brew install --cask xdevplatform/tap/xurl # Homebrew
npm install -g @xdevplatform/xurl # npm (global)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash
```
**First login needs a browser.** On a headless/remote box, authenticate out-of-band first with `xurl auth oauth2 --headless` (paste-a-code flow), then the bridge just reuses the cached token. See [Headless](/tools/mcp#headless--remote-machines).
### Connect your client
#### 1. Grok Build
```toml xurl bridge (~/.grok/config.toml) theme={null}
[mcp_servers.xapi]
command = "npx"
args = ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"]
enabled = true
startup_timeout_sec = 300 # give the first-run browser login time
[mcp_servers.xapi.env]
CLIENT_ID = "YOUR_X_APP_CLIENT_ID"
CLIENT_SECRET = "YOUR_X_APP_CLIENT_SECRET"
```
```toml App-only Bearer (~/.grok/config.toml) theme={null}
[mcp_servers.xapi]
url = "https://api.x.com/mcp"
enabled = true
[mcp_servers.xapi.headers]
Authorization = "Bearer YOUR_APP_ONLY_BEARER_TOKEN"
```
Or add the xurl bridge with one command (the `-e` flags become the server's environment, args after `--` go to `npx`):
```bash theme={null}
grok mcp add xapi npx \
-e CLIENT_ID=YOUR_X_APP_CLIENT_ID \
-e CLIENT_SECRET=YOUR_X_APP_CLIENT_SECRET \
-- -y @xdevplatform/xurl mcp https://api.x.com/mcp
```
Verify and list:
```bash theme={null}
grok mcp doctor xapi # ✓ server started, ✓ handshake OK, ✓ tools discovered
grok mcp list
```
The first time a tool is invoked (or on `doctor`), your browser opens for the X login — complete it once and you're set.
#### 2. Cursor
Create `~/.cursor/mcp.json` (global, all projects) or `.cursor/mcp.json` (this project only):
```json title="xurl bridge" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"mcpServers": {
"xapi": {
"command": "npx",
"args": ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"],
"env": {
"CLIENT_ID": "YOUR_X_APP_CLIENT_ID",
"CLIENT_SECRET": "YOUR_X_APP_CLIENT_SECRET"
}
}
}
}
```
```json App-only Bearer theme={null}
{
"mcpServers": {
"xapi": {
"url": "https://api.x.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_APP_ONLY_BEARER_TOKEN"
}
}
}
}
```
Then open **Cursor → Settings → MCP**, confirm **xapi** shows a green dot and its tools. On first use Cursor spawns the bridge and your browser opens for login; the tool list populates once the handshake completes.
#### 3. Claude Desktop
Edit `claude_desktop_config.json` (macOS: `~/Library/Application Support/Claude/`, Windows: `%APPDATA%\Claude\`):
```json xurl bridge theme={null}
{
"mcpServers": {
"xapi": {
"command": "npx",
"args": ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"],
"env": { "CLIENT_ID": "YOUR_X_APP_CLIENT_ID", "CLIENT_SECRET": "YOUR_X_APP_CLIENT_SECRET" }
}
}
}
```
```json App-only Bearer theme={null}
{
"mcpServers": {
"xapi": {
"url": "https://api.x.com/mcp",
"headers": { "Authorization": "Bearer YOUR_APP_ONLY_BEARER_TOKEN" }
}
}
}
```
Restart Claude Desktop; the X tools appear in the tools (🔌) menu.
#### 4. VS Code (GitHub Copilot / Agent mode)
Add to `.vscode/mcp.json`:
```json xurl bridge theme={null}
{
"servers": {
"xapi": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"],
"env": { "CLIENT_ID": "YOUR_X_APP_CLIENT_ID", "CLIENT_SECRET": "YOUR_X_APP_CLIENT_SECRET" }
}
}
}
```
```json App-only Bearer theme={null}
{
"servers": {
"xapi": {
"type": "http",
"url": "https://api.x.com/mcp",
"headers": { "Authorization": "Bearer YOUR_APP_ONLY_BEARER_TOKEN" }
}
}
}
```
#### 5. Any MCP client
**xurl bridge (stdio):**
| Field | Value |
| --------------- | -------------------------------------------------------------- |
| `command` | `npx` |
| `args` | `["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"]` |
| `env` | `CLIENT_ID`, `CLIENT_SECRET` |
| startup timeout | **≥ 300s** (so the first-run login can finish) |
If you installed `xurl` natively, replace `command`/`args` with `"command": "xurl", "args": ["mcp", "https://api.x.com/mcp"]`.
**App-only Bearer (remote HTTP):**
| Field | Value |
| ----------------------- | ----------------------------------- |
| `url` | `https://api.x.com/mcp` |
| `headers.Authorization` | `Bearer YOUR_APP_ONLY_BEARER_TOKEN` |
### Authentication
#### OAuth 2.0 user context (default)
The bridge authenticates as **you** (PKCE flow), so tools act with your account's scopes. Resolution order for credentials: **`CLIENT_ID`/`CLIENT_SECRET` env vars → the active app in `~/.xurl`**. The bridge caches tokens in `~/.xurl` and refreshes them automatically (including a forced refresh after a `401`).
#### First-run browser login
With no cached token, the bridge prints to stderr and opens your browser:
```json theme={null}
[xurl mcp] no valid OAuth2 token; opening the browser to sign in -- complete the login to start the bridge...
[xurl mcp] authentication complete; starting bridge
```
The MCP handshake is held until you finish — that's why clients need a generous `startup_timeout_sec`.
#### Headless / remote machines
No reachable browser? Authenticate once out-of-band, then start the client:
```bash theme={null}
# Required: the env block in your client config only applies to the bridge,
# not to manual xurl runs — export the credentials in this shell first.
export CLIENT_ID="YOUR_X_APP_CLIENT_ID"
export CLIENT_SECRET="YOUR_X_APP_CLIENT_SECRET"
xurl auth oauth2 --headless # prints an auth URL; you paste back the redirect URL/code
xurl auth oauth2 --app my-app --headless # for a specific app
```
#### App-only (direct URL, no bridge)
For read endpoints, you can skip the bridge and point a client straight at the URL with a **static App-only Bearer token**. This is useful for clients that support remote MCP with custom headers:
```toml theme={null}
# ~/.grok/config.toml
[mcp_servers.xapi_direct]
url = "https://api.x.com/mcp"
enabled = true
[mcp_servers.xapi_direct.headers]
Authorization = "Bearer YOUR_APP_ONLY_BEARER_TOKEN"
```
Trade-off: no auto-refresh and no user context (no actions as you). The bridge is recommended for full functionality.
#### Multiple apps & accounts
The OAuth login authorizes **whichever X account is logged in when the browser opens** — not necessarily the account that owns the app. If you're posting on behalf of a secondary/bot account, switch to that account in your browser before completing the login (or use `-u` to pick a previously authorized user).
```bash theme={null}
xurl --app my-app mcp # bridge using a specific registered app
xurl mcp -u alice https://api.x.com/mcp # act as a specific OAuth2 user
```
In a client config, add `"--app", "my-app"` or `"-u", "alice"` to `args`.
### Configuration reference
| Setting | Where | Notes |
| ----------------------------- | ------------- | ----------------------------------------------------------------------------------------------- |
| `CLIENT_ID` / `CLIENT_SECRET` | `env` | Your X app credentials (or rely on a registered app in `~/.xurl`) |
| `REDIRECT_URI` | `env` | Overrides the callback; must be registered on the app. Default `http://localhost:8080/callback` |
| `startup_timeout_sec` | client config | Set **≥ 300** so first-run login can complete |
| `[URL]` positional | `args` | Defaults to `https://api.x.com/mcp` |
| `--app NAME` | `args` | Use a specific registered app |
| `-u, --username` | `args` | Act as a specific OAuth2 user |
Advanced env overrides (rarely needed): `AUTH_URL`, `TOKEN_URL`, `API_BASE_URL`, `INFO_URL`.
### Verify & troubleshoot
```bash theme={null}
grok mcp doctor xapi # Grok Build: end-to-end check
# or test the bridge by hand (Ctrl-C to exit):
npx -y @xdevplatform/xurl mcp https://api.x.com/mcp
```
| Symptom | Cause / Fix |
| --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Client times out on startup | Raise `startup_timeout_sec` to 300+; the bridge is waiting on your browser login |
| Browser never opens | No display (headless) → run `xurl auth oauth2 --headless` first; ensure `npx` resolves |
| `401` / `token refresh failed` | App credentials wrong, or refresh token revoked → re-run the login (`xurl auth oauth2 [--app NAME]`) |
| Browser shows "Something went wrong — You weren't able to give access to the App" | `CLIENT_ID`/`CLIENT_SECRET` not set where `xurl` runs → put them in the client's `env` block, or `export` them in your shell before running `xurl auth oauth2` manually |
| Redirect/callback error in browser | `http://localhost:8080/callback` not registered on the app (or `REDIRECT_URI` mismatch) |
| `client-not-enrolled` after login | App isn't in the right X package/environment → in the portal move it to **Pay-per-use** + **Production** |
| `npx` pulls a stale version | A private registry mirror is default → pin `--registry=https://registry.npmjs.org/` in `args` |
| Empty/garbled tool output | Don't run the client with `--verbose`; stdout must stay a clean JSON-RPC channel |
### Security & best practices
* **Treat `~/.xurl` and access tokens as secrets** — don't paste them into chats, logs, or shared configs. Prefer per-project `.mcp.json`/`.grok/config.toml` that reference env vars over committing raw secrets.
* **Use a dedicated app** for MCP with only the scopes you need.
* **Writes count against rate limits** (bookmarks, `article_publish`) and are stricter than reads; expect occasional `429`s and back off.
* **The bridge is local** — your credentials never leave your machine except as a Bearer token sent over TLS to `api.x.com`.
***
## Docs MCP — documentation search
X hosts an MCP server for the X API documentation at `https://docs.x.com/mcp`. Connect it to your AI tool to search and read documentation pages without leaving your workflow.
### Available tools
| Tool | Description |
| :----------- | :---------------------------------------------------------------------------------------------------- |
| `search_x` | Search across the X documentation for relevant information, code examples, API references, and guides |
| `get_page_x` | Retrieve the full content of a specific documentation page by its path |
### Configuration
Add the docs MCP server to your MCP client configuration:
```json theme={null}
{
"mcpServers": {
"x-docs": {
"url": "https://docs.x.com/mcp"
}
}
}
```
This is useful when you're building with the X API and want your AI assistant to look up endpoint details, authentication guides, or code examples on the fly.
***
## Using both servers together
You can connect both MCP servers simultaneously. This gives your AI assistant the ability to both look up documentation *and* call the API.
**Grok Build** (`~/.grok/config.toml`):
```toml title="Example" lines wrap icon="file-lines" theme={null}
[mcp_servers.xapi]
command = "npx"
args = ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"]
enabled = true
startup_timeout_sec = 300
[mcp_servers.xapi.env]
CLIENT_ID = "YOUR_X_APP_CLIENT_ID"
CLIENT_SECRET = "YOUR_X_APP_CLIENT_SECRET"
[mcp_servers.x-docs]
url = "https://docs.x.com/mcp"
enabled = true
```
**Cursor / Claude-style** (`mcp.json`):
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"mcpServers": {
"xapi": {
"command": "npx",
"args": ["-y", "@xdevplatform/xurl", "mcp", "https://api.x.com/mcp"],
"env": {
"CLIENT_ID": "YOUR_X_APP_CLIENT_ID",
"CLIENT_SECRET": "YOUR_X_APP_CLIENT_SECRET"
}
},
"x-docs": {
"url": "https://docs.x.com/mcp"
}
}
}
```
***
## OpenAPI specification
The machine-readable API specification for all X API v2 endpoints.
| Resource | URL |
| :---------------------- | :--------------------------------------------------------------------- |
| **OpenAPI Spec (JSON)** | [`https://api.x.com/2/openapi.json`](https://api.x.com/2/openapi.json) |
```bash theme={null}
curl https://api.x.com/2/openapi.json -o openapi.json
```
You can use it to auto-generate API clients, import into [Postman](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80), feed into custom AI agents, or validate request/response schemas.
# API Playground
Source: https://docs.x.com/tools/playground
Run a local mock server to test X API v2 endpoints during development without consuming API credits, plus example requests and response payloads.
The [API Playground](https://github.com/xdevplatform/playground) is a local mock server that simulates the full X API v2. Test endpoints, build prototypes, and explore the API without consuming real API credits.
Source code, releases, and full documentation.
***
## Features
All endpoints supported with request validation via OpenAPI specs and realistic error responses.
Visual endpoint explorer at `http://localhost:8080/playground` for testing in the browser.
Everything runs locally with mock data — no API keys or billing required.
In-memory state with optional file persistence. Create posts, then look them up.
***
## Installation
Requires Go 1.21+. Install from source or download a pre-built binary from [releases](https://github.com/xdevplatform/playground/releases).
```bash theme={null}
go install github.com/xdevplatform/playground/cmd/playground@latest
playground start
```
```bash theme={null}
git clone https://github.com/xdevplatform/playground.git
cd playground
go build -o playground ./cmd/playground
./playground start
```
The server starts at `http://localhost:8080` by default.
***
## Quick start
Make requests just like you would to the real API — use `test_token` as your bearer token:
```bash title="me" lines wrap icon="terminal" theme={null}
# Look up a user
curl -H "Authorization: Bearer test_token" \
http://localhost:8080/2/users/me
# Create a post
curl -X POST -H "Authorization: Bearer test_token" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from the playground!"}' \
http://localhost:8080/2/tweets
# Search posts
curl -H "Authorization: Bearer test_token" \
"http://localhost:8080/2/tweets/search/recent?query=hello"
```
Open `http://localhost:8080/playground` in your browser for the interactive UI.
***
## What's included
| Feature | Description |
| :--------------------- | :---------------------------------------------- |
| **Request validation** | Validates requests against the OpenAPI spec |
| **Realistic errors** | Returns proper error codes and messages |
| **Streaming support** | Simulated streaming endpoints |
| **Rate limiting** | Configurable rate limit simulation |
| **CORS support** | Works with browser-based applications |
| **Usage tracking** | Simulated billing and credit tracking endpoints |
| **State persistence** | Optional file persistence in `~/.playground/` |
***
## Related
CLI tool for the real X API with built-in authentication.
Ready for the real API? Make your first request.
# Python XDK
Source: https://docs.x.com/tools/python-xdk
Install and use the official Python XDK client library for the X API v2, including authentication setup, paginated requests, and streaming examples.
The [Python XDK](https://github.com/xdevplatform/xdk-python) is the official client library for the X API v2. It handles authentication, pagination, and streaming so you can focus on building.
Source code, issues, and releases.
***
## Installation
```bash theme={null}
pip install xdk
```
Requires Python 3.8+.
***
## Quick start
```python theme={null}
from xdk import Client
client = Client(bearer_token="YOUR_BEARER_TOKEN")
# Search for posts
for page in client.posts.search_recent(query="X API", max_results=10):
if page.data and len(page.data) > 0:
print(page.data[0].text)
break
```
***
## Key features
| Feature | Description |
| :----------------------- | :-------------------------------------------------------------------- |
| **OAuth support** | Bearer Token, OAuth 2.0 with PKCE, and OAuth 1.0a |
| **Automatic pagination** | Iterate through results without manual `next_token` handling |
| **Streaming** | Real-time data via persistent connections (filtered stream, etc.) |
| **Full API coverage** | All X API v2 endpoints — search, timelines, filtered stream, and more |
***
## Authentication
```python theme={null}
from xdk import Client
client = Client(bearer_token="YOUR_BEARER_TOKEN")
```
```python title="Example" lines wrap icon="python" theme={null}
from xdk import Client
from xdk.oauth2_auth import OAuth2PKCEAuth
auth = OAuth2PKCEAuth(
client_id="YOUR_CLIENT_ID",
redirect_uri="YOUR_CALLBACK_URL",
scope="tweet.read users.read offline.access"
)
auth_url = auth.get_authorization_url()
tokens = auth.fetch_token(authorization_response=callback_url)
client = Client(bearer_token=tokens["access_token"])
```
```python theme={null}
from xdk import Client
from xdk.oauth1_auth import OAuth1
oauth1 = OAuth1(
api_key="YOUR_API_KEY",
api_secret="YOUR_API_SECRET",
access_token="YOUR_ACCESS_TOKEN",
access_token_secret="YOUR_ACCESS_TOKEN_SECRET"
)
client = Client(auth=oauth1)
```
***
## Common methods
| Category | Method |
| :--------- | :----------------------------- |
| **Posts** | `client.posts.search_recent()` |
| **Users** | `client.users.get_me()` |
| **Spaces** | `client.spaces.get()` |
| **Lists** | `client.lists.get()` |
| **DMs** | `client.direct_messages.get()` |
***
## Learn more
Development install, prerequisites, and verification.
Step-by-step first request walkthrough.
Detailed guide for all auth methods.
Automatic pagination and iterators.
Real-time data via filtered stream.
Complete client and model reference.
For code examples, see the [samples repo](https://github.com/xdevplatform/samples/tree/main/python).
# skill.md
Source: https://docs.x.com/tools/skill-md
skill.md is a structured capability summary that describes what AI agents can do with the X API, used by tools like agentskills.io to enable workflows.
The [`skill.md`](https://docs.x.com/skill.md) file follows the [agentskills.io specification](https://agentskills.io/specification) and describes what AI agents can *do* with the X API. While [`llms.txt`](/tools/llms-txt) is a directory of pages, `skill.md` is a capability summary — it lists specific actions, required inputs, and constraints so agents can use the API more reliably.
***
## What's included
* **Capabilities** — what agents can accomplish (search posts, create posts, manage users, etc.)
* **Skills** — specific actions organized by category with required parameters
* **Workflows** — step-by-step procedures for common tasks
* **Context** — background on authentication, rate limits, and architecture
```bash theme={null}
# Fetch the skill file
curl https://docs.x.com/skill.md
```
***
## Discovery endpoints
Agents can discover skill files programmatically via the well-known endpoints:
```bash theme={null}
# Discovery endpoint (agent-skills 0.2.0 spec)
curl https://docs.x.com/.well-known/agent-skills/index.json
# Original discovery format
curl https://docs.x.com/.well-known/skills/index.json
```
You can add X API capabilities to any agent that supports the [skills CLI](https://www.npmjs.com/package/skills):
```bash theme={null}
npx skills add https://docs.x.com
```
# TypeScript XDK
Source: https://docs.x.com/tools/typescript-xdk
Install and use the official TypeScript XDK client library for the X API v2, with authentication, typed responses, pagination, and streaming examples.
The [TypeScript XDK](https://github.com/xdevplatform/twitter-api-typescript-sdk) is the official client library for the X API v2. Full type safety, automatic pagination, and event-driven streaming.
Source code, issues, and releases.
***
## Installation
```bash npm theme={null}
npm install @xdevplatform/xdk
```
```bash yarn theme={null}
yarn add @xdevplatform/xdk
```
```bash pnpm theme={null}
pnpm add @xdevplatform/xdk
```
Requires Node.js 16+ and TypeScript 4.5+ (if using TypeScript).
***
## Quick start
```typescript theme={null}
import { Client } from '@xdevplatform/xdk';
const client = new Client({ bearerToken: 'YOUR_BEARER_TOKEN' });
const userResponse = await client.users.getByUsername('XDevelopers');
console.log(userResponse.data?.username);
```
***
## Key features
| Feature | Description |
| :----------------------- | :--------------------------------------------------------------- |
| **Type safety** | Complete TypeScript definitions for all endpoints and parameters |
| **Authentication** | Bearer Token, OAuth 2.0 with PKCE, and OAuth 1.0a |
| **Automatic pagination** | Async iteration support for paginated endpoints |
| **Streaming** | Event-driven streaming with automatic reconnection |
| **Full API coverage** | Users, Posts, Lists, Bookmarks, Communities, and more |
***
## Authentication
```typescript theme={null}
import { Client } from '@xdevplatform/xdk';
const client = new Client({ bearerToken: 'YOUR_BEARER_TOKEN' });
```
```typescript title="Example" lines wrap icon="square-js" theme={null}
import { Client, OAuth2, generateCodeVerifier, generateCodeChallenge } from '@xdevplatform/xdk';
const oauth2 = new OAuth2({
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'https://your-app.com/callback',
scope: ['tweet.read', 'users.read', 'offline.access'],
});
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
oauth2.setPkceParameters(codeVerifier, codeChallenge);
const authUrl = await oauth2.getAuthorizationUrl('state');
const tokens = await oauth2.exchangeCode(authCode, codeVerifier);
const client = new Client({ accessToken: tokens.access_token });
```
```typescript theme={null}
import { Client, OAuth1 } from '@xdevplatform/xdk';
const oauth1 = new OAuth1({
apiKey: 'YOUR_API_KEY',
apiSecret: 'YOUR_API_SECRET',
accessToken: 'YOUR_ACCESS_TOKEN',
accessTokenSecret: 'YOUR_ACCESS_TOKEN_SECRET'
});
const client = new Client({ oauth1: oauth1 });
```
***
## Common methods
| Category | Method |
| :--------- | :------------------------------- |
| **Posts** | `client.posts.search()` |
| **Users** | `client.users.getMe()` |
| **Spaces** | `client.spaces.findSpaceById()` |
| **Lists** | `client.lists.getList()` |
| **DMs** | `client.directMessages.lookup()` |
***
## Learn more
Package managers, TypeScript setup, and requirements.
Detailed guide for all auth methods.
Async iteration and paginated responses.
Event-driven streaming with reconnection.
Complete client, interface, and type reference.
For code examples, see the [samples repo](https://github.com/xdevplatform/samples/tree/main/javascript).
# xurl — curl-style command line client for the X API
Source: https://docs.x.com/tools/xurl
Install and use xurl, a curl-style CLI for the X API with built-in OAuth that lets you test endpoints, sign requests, and prototype from the terminal.
[xurl](https://github.com/xdevplatform/xurl) is a curl-like command-line tool for the X API. It handles OAuth authentication automatically so you can make API requests without manually managing tokens or signing requests.
Source code, releases, and documentation.
***
## Installation
Install with Go, or download a pre-built binary from [releases](https://github.com/xdevplatform/xurl/releases).
```bash theme={null}
go install github.com/xdevplatform/xurl@latest
```
***
## Setup
### 1. Create an X app
xurl authenticates using your own developer app. In the [X Developer Portal](https://developer.x.com):
1. Create (or open) an app with **OAuth 2.0** enabled.
2. Register the redirect URI `http://localhost:8080/callback` on the app.
3. Copy the app's **Client ID** and **Client Secret** from the "Keys and tokens" page.
### 2. Set your credentials
Export the credentials in the same shell you'll run xurl from:
```bash theme={null}
export CLIENT_ID="your-x-app-client-id"
export CLIENT_SECRET="your-x-app-client-secret"
```
### 3. Authorize
```bash theme={null}
xurl auth oauth2
```
This opens a browser-based OAuth flow. Once authorized, xurl stores your tokens locally in `~/.xurl` so you don't need to authenticate again.
If the browser shows **"Something went wrong — You weren't able to give access to the App"**, xurl started the login without valid credentials. Make sure `CLIENT_ID` and `CLIENT_SECRET` are exported in the shell where you ran `xurl auth oauth2`, and that `http://localhost:8080/callback` is registered as a redirect URI on your app.
***
## Usage
### Raw API requests
Use xurl like curl — it handles auth headers automatically:
```bash theme={null}
# Look up a user
xurl /2/users/by/username/xdevelopers
# Search recent posts
xurl "/2/tweets/search/recent?query=from:xdevelopers&max_results=10"
# Create a post
xurl -X POST /2/tweets -d '{"text": "Hello from xurl!"}'
```
### Shortcut commands
xurl includes built-in shortcuts for common operations:
```bash theme={null}
# Look up a user by username
xurl user xdevelopers
# Search recent posts
xurl search "X API"
# Post a tweet
xurl post "Hello from xurl!"
```
***
## Why use xurl?
| Feature | curl | xurl |
| :------------------- | :-------------------------- | :------------------------------------ |
| **Authentication** | Manual OAuth header setup | Automatic — just run `xurl auth` once |
| **Token management** | You handle refresh/rotation | Built-in token storage and refresh |
| **API shortcuts** | Full URL required | Shorthand commands for common tasks |
| **Request signing** | Manual OAuth 1.0a signing | Automatic for all requests |
***
## Using xurl with AI agents
xurl includes a [`SKILL.md`](https://github.com/xdevplatform/xurl/blob/main/SKILL.md) file that describes its capabilities in a machine-readable format. AI agents can use this to understand how to invoke xurl commands on your behalf.
```bash theme={null}
npx skills add https://github.com/xdevplatform/xurl
```
***
## Related
Get started with the X API using cURL or SDKs.
Test endpoints locally with mock data — no API credits needed.
# Tutorials
Source: https://docs.x.com/tutorials
X API tutorials covering Postman, Python, R, filtered streaming, full-archive search, webhooks, OAuth authentication, and other common workflows.
Learn how to explore a user's Posts and mentions using the user Post timeline and user mention timeline endpoints from the last 7 days.
[**View tutorial**](/tutorials/explore-a-users-posts)
Learn how to start using Postman to make requests to the X API and X Ads API.
[**View tutorial**](/tutorials/postman-getting-started)
Learn about using R to connect to the user lookup endpoint and how to work with JSON returned from X API v2.
[**View tutorial**](/tutorials/getting-started-with-r-and-v2-of-the-x-api)
Learn to use the full-archive search endpoint to search the complete history of public X data, build a dataset of geo-tagged Posts, and paginate through results for a query.
[**View tutorial**](/tutorials/getting-historical-posts-using-the-full-archive-search-endpoint)
Get a high-level overview of how to ingest Posts at scale and use metadata to slice them into specific categories or sub-categories.
[**View tutorial**](/tutorials/post-processing-x-data-with-the-google-cloud-platform)
# Explore a user's Posts and mentions with the X API v2
Source: https://docs.x.com/tutorials/explore-a-users-posts
The user Post timeline and user mention timeline endpoints allow developers to retrieve the public Posts composed by, or mentioning a user.
## Introduction
While the [recent search endpoint](/x-api/posts/search/introduction) allows you to only get Posts published in the last 7 days, the user Post timeline and user mention timeline endpoints allow you to retrieve Posts and mentions that are older than the last 7 days, for an authorized user (using the user ID). Developers can use these endpoints to study topics, entities and sentiment of Posts from a user’s timeline or mentions. In this tutorial, we will show you how to explore a user’s Posts and mentions using the user Tweet timeline and user mention timeline endpoints.
## Prerequisites
* In order to use the user Tweet timeline and user mention timeline endpoints, you will need to have a valid developer account.
* You will also need a [Project](/resources/fundamentals/developer-apps) created.
* You must have [signed up](https://developer.x.com/en/portal/petition/essential/basic-info) for a developer account, and have activated the [new Developer Console experience](https://developer.x.com/en/portal/opt-in.html).
* Access is available with active keys and tokens for a developer App that is attached to a [Project](/resources/fundamentals/developer-apps) created in the [Developer Console](/resources/fundamentals/developer-portal).
* A Bearer Token from your App in the [X Developer Console](/resources/fundamentals/developer-portal).
* If you do not have an approved developer account, you can [apply for one](https://developer.x.com/en/apply-for-access).
## Approved developer account
If you do not have one yet, you can [apply for one](https://developer.x.com/en/apply-for-access).
## Create a Project and connect an App
In the [Developer Console](https://developer.x.com/en/portal/dashboard), click create a new App.
Give it a name, select the appropriate use-case, and provide a Project description. Next, you can either create a new App, or connect an existing [App](/resources/fundamentals/developer-apps) (an App is a container for your API keys that you need in order to make an HTTP request to the X API).
Click ‘create a new App instead’ and give your App a name in order to create a new App.
Once you click complete, you will get your API keys and the bearer token that you can then use to connect to the new endpoints in the X API v2.
Click the (+) next to API key, API secret key and Bearer token and copy these values to a safe place on your local machine. You will need these to make the API calls in the next step.
Note: The keys in the screenshot above are hidden, but in your own Developer Console, you will be able to see the actual values for the API key, API secret key and Bearer token.
## How to get the user ID for a user to use in the user Tweet timeline and user mention timeline endpoints
The user Tweet timeline and user mention timeline endpoints allow you to get Posts using the user ID. In order to get the user ID from a username, you can use the new [user lookup endpoint v2](/x-api/users/lookup/quickstart/user-lookup). Replace the USER\_NAME with the username of your choice and XXXX with your own bearer token that you obtained above
```bash theme={null}
curl --request GET 'https://api.x.com/2/users/by/username/USER_NAME --header 'Authorization: Bearer XXXXXX'
```
You will see the user ID in response as shown below:
```json theme={null}
{
"data": {
"id": "2244994945",
"name": "Developers",
"username": "XDevelopers"
}
}
```
## Connecting to the user Tweet timeline and user mention timeline endpoints
In order to get the user Tweet timeline for a user, run the following curl command in your terminal (make sure to replace the USER\_ID with the user ID of your choice and XXXX with your own bearer token that you obtained above)
```bash theme={null}
curl --request GET 'https://api.x.com/2/users/USER_ID/tweets' --header 'Authorization: Bearer XXXXXX'
```
You will see that the JSON response for these requests contains the ID and text for the Posts by default (example below).
```yaml theme={null}
{
"id": "1334200897081987072",
"text": "👀 If you are new to the X API v2, check out this step-by-step guide to making your first request https://t.co/4rZqThpSbp"
}
```
If you want additional fields returned as part of the response (such as user information, additional Tweet fields such as context annotations etc.) then you will need to specify those fields explicitly in your response. Learn how to do this from the [guide on using fields and expansions](/x-api/fundamentals/data-dictionary/reference#how-to-use-fields-and-expansions).
You can also get these Posts using programming languages of your choice. Check out our sample code in Python, Node (JavaScript), Java and Ruby for the user Tweet timeline and user mention timeline endpoints on our [Github repository](https://github.com/xdevplatform/Twitter-API-v2-sample-code).
## Exploring the user’s Posts
Once you know how to get Posts using the user Tweet timeline and user mention timeline endpoints, you can start to explore their Posts. For example, if you wanted to identify common named entities present in a user’s mentions, you can do the following:
In the API request, specify that you want the context\_annotations object returned in the Tweet responses:
```bash theme={null}
curl --request GET 'https://api.x.com/2/users/USER_ID/mentions?tweet.fields=context_annotations' --header 'Authorization: Bearer XXXXXX'
```
In the response, you will see if any named entities are present in the mentions. Here is an example:
```json theme={null}
{
"domain": {
"id": "47",
"name": "Brand",
"description": "Brands and Companies"
},
"entity": {
"id": "783214",
"name": "X"
}
}
```
If you wanted to see which popular entities appear in your mentions, you could keep a count of popular entities by parsing each Tweet in the mentions.
If you wanted to explore the preview image URL for all Posts in your timeline that contain media, you can do the following:
In the API request, specify that you want the preview\_image\_url in the tweet.media fields, and the attachments.media\_keys expansions
```bash theme={null}
curl --request GET 'https://api.x.com/2/users/2244994945/mentions?max_results=100&media.fields=preview_image_url&expansions=attachments.media_keys' --header 'Authorization: Bearer XXXXXX'
```
In the response, you will see the preview\_image\_url in the includes object as shown below:
```json theme={null}
{
"includes": {
"media": [
{
"media_key": "16_1334657439640121344",
"preview_image_url": "https://pbs.twimg.com/tweet_video_thumb/EoWn3rqU8AAtFWL.jpg",
"type": "animated_gif"
}
]
}
}
```
Once you have an understanding of how to navigate a user’s Posts, you can also use other APIs and services to do more with the Posts. Below are some resources to keep handy when using the user Tweet timeline and user mention timeline endpoints.
## Resources
* Learn more about the [user Tweet timeline and the user mention timeline endpoints](/x-api/posts/timelines/introduction).
* Check out the [API reference for the user Tweet timeline endpoint](/x-api/users/get-posts) to learn more about what’s available.
* Check out the [API reference for the user mention timeline endpoint](/x-api/users/get-mentions) to learn more about what’s available.
* Get inspired by reading our other [tutorials](/tutorials).
# Get historical Posts with full-archive search
Source: https://docs.x.com/tutorials/getting-historical-posts-using-the-full-archive-search-endpoint
Step-by-step tutorial for retrieving historical Posts back to 2006 using the X API v2 full-archive search endpoint, query operators, and pagination.
## Introduction
The [Search Posts endpoints](/x-api/posts/search/introduction)
in the v2 world enable you to receive Posts related to topics of interest,
based on a search query that you produce. We have two different endpoints
available with v2 Search Posts: recent search, which is available to all
developers with an approved account and can search for Posts up to seven days
old, and full-archive search, which is only available to
researchers approved for the
[Academic Research product track](https://developer.x.com/en/products/x-api/early-access/guide#na_2),
and can search through the entire archive of Posts dating back to March 2006.
You can see our full search offering on our
[search overview page](/x-api/posts/search/introduction).
These Search Posts endpoints address one of the most common use cases for
academic researchers, who might use this for longitudinal studies, or analyzing
a past topic or event.
This tutorial provides a step-by-step guide for researchers who wish to use the
full-archive search endpoint to search the complete history of public X
data. It will also demonstrate the different ways to build a dataset, such as by
retrieving geo-tagged Posts, and how to page through the available Posts for a
query.
### Prerequisites
Currently, this endpoint is only available as part of the
[Academic Research product track](https://developer.x.com/en/solutions/academic-research/products-for-researchers).
In order to use this endpoint, you must
[apply for access](https://developer.x.com/en/portal/petition/academic/is-it-right-for-you).
Learn more about the
[application and requirements for this track](https://developer.x.com/en/solutions/academic-research/application-info).
### Connect an app to the academic project
Once you are approved to use the Academic Research product track, you will see
your Academic [Project](/resources/fundamentals/developer-apps) in the
[Developer Console](https://developer.x.com/en/portal/dashboard). From the
"Apps" section, click on "Add App" to connect your
[X App](/resources/fundamentals/developer-apps) to the Project.
[](https://res.cloudinary.com/practicaldev/image/fetch/s--gHFOyuDc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gb7aevhqyfvfjznd0pnd.png)

Then, you can either choose an existing App and connect it to your project (as
shown below).

Or you can create a new App, give it a name and click complete, to connect a new
App to your Academic Project.

This will give you your API keys and
[Bearer Token](/resources/fundamentals/authentication#using-and-generating-an-app-only-bearer-token) that you can
then use to connect to the full-archive search endpoint.

**Please note**
The keys in the screenshot above are hidden, but in your own Developer Console,
you will be able to see the actual values for the API Key, API Secret Key, and
Bearer Token. Save these keys and the Bearer Token because you will need those
for calling the full-archive search endpoint.
### Connecting to the full-archive search endpoint
The cURL command below shows how you can get historical Posts from @XDevelopers
handle. Replace the \$BEARER\_TOKEN with your own Bearer Token, paste the full
request in your terminal, and press "return".
```bash theme={null}
curl --request GET 'https://api.x.com/2/tweets/search/all?query=from:xdevelopers' --header 'Authorization: Bearer $BEARER_TOKEN'
```
You will see the response JSON.
By default, only the 10 most recent Posts will be returned. If you want more
than 10 Posts per request, you can use the max\_results parameter and set it to
a maximum of 500 Posts per request, as shown below:
```bash theme={null}
curl --request GET 'https://api.x.com/2/tweets/search/all?query=from:xdevelopers&max_results=500' --header 'Authorization: Bearer $BEARER_TOKEN'
```
### Building queries
As you can see in the example calls above, using the query parameter, you can
specify the data that you want to search for. As an example, if you wanted to
get all Posts that contain the word *covid* or the word *coronavirus*, you can
use the OR operator within brackets, and your query can be
`(covid OR coronavirus)` and thus your API call will look like the following:
```bash theme={null}
curl --request GET 'https://api.x.com/2/tweets/search/all?query=(covid%20OR%20coronavirus)&max_results=500' --header 'Authorization: Bearer $BEARER_TOKEN'
```
Similarly, if you want all Posts that contain the words *covid19* that are not
reposts, you can use the is:retweet operator with the logical NOT (represented
by -), so your query can be covid19 -is:retweet and your API call will be:
```bash theme={null}
curl --request GET 'https://api.x.com/2/tweets/search/all?query=covid19%20-is:retweet&max_results=500' --header 'Authorization: Bearer $BEARER_TOKEN'
```
Check out
[this guide for a complete list of operators](/x-api/posts/search/integrate/build-a-query)
that are supported in the full-archive search endpoint.
### Using the start\_time and end\_time parameters to get historical Posts
When using the full-archive search endpoint, by default Posts from the last 30
days will be returned. If you want to get Posts that are older than 30 days,
you can use the start\_time and end\_time parameters in your API call. These
parameters must be in a valid RFC3339 date-time format, for example
2020-12-21T13:00:00.00Z. Thus, if you want to get all Posts from the XDevelopers
account for the month of December 2020, your API call will be:
```bash theme={null}
curl --request GET 'https://api.x.com/2/tweets/search/all?query=from:XDevelopers&start_time=2020-12-01T00:00:00.00Z&end_time=2021-01-01T00:00:00.00Z' --header 'Authorization: Bearer $BEARER_TOKEN'
```
### Getting geo-tagged historical Posts
Geo-tagged Posts are Posts that have geographic information associated with
them such as city, state, country etc.
#### Using has:geo operator
If you want to get Posts that have geo data, you can use the has:geo operator.
For example, the following cURL request will get only those Posts from the
@XDevelopers handle that have geo data:
```bash theme={null}
curl --request GET
'https://api.x.com/2/tweets/search/all?query=from:xdevelopers%20has:geo' --header
'Aubashthorization: Bearer $BEARER_TOKEN'
```
#### Using place\_country operator
Similarly, you can limit Posts that have geo data, to a specific country, using
the place\_country operator. The cURL command below will get all Posts from the
@XDevelopers handle from the United States:
```bash theme={null}
curl --request GET
'https://api.x.com/2/tweets/search/all?query=from:xdevelopers%20place_country:US'
--hbasheader 'Authorization: Bearer XXXXX'
```
The country is specified above using the ISO alpha-2 character code. Valid ISO
codes can be found [here](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
### Getting more than 500 historical Posts using the next\_token
As mentioned above, by default you can only get up to 500 Posts per request for
a query to the full-archive search endpoint. If there are more than 500 Posts
available for your query, your json response will include a next\_token which you
can append to your API call in order to get the next available Posts for this
query. This next\_token is available in the meta object of your JSON response,
which looks something:
```json theme={null}
{ "newest_id": "12345678...", "oldest_id": "12345678...", "result_count": 500,
"nebashxt_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
```
Hence, to get the next available Posts, use the next\_token value from this meta
object and use the value as the value for the next\_token in your API call to the
full-archive search endpoint as shown below (You will use your own Bearer Token
and the value that you get for the Next Token for your previous API call).
```bash theme={null}
curl --request GET
'https://api.x.com/2/tweets/search/all?max_results=500&query=covid&next_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
--header 'Authorization: Bearer $BEARER_TOKEN'
```
This way, you can keep checking if a next\_token is available and if you have not
reached your desired number of Posts to be collected, you can keep calling the
full-archive endpoint with the new next\_token for each request.
Below are some resources that can help you when using the full-archive search
endpoint. We would love to hear your feedback. Reach out to us on
[@XDevelopers](https://x.com/XDevelopers) or on our
[community forums](https://devcommunity.x.com/) with questions about this
endpoint.
### Additional resources
* [Full-archive search endpoint API reference](/x-api/posts/full-archive-search)
* [Learn the basics of building a search query](/x-api/posts/search/integrate/build-a-query)
# Getting started with R and v2 of the X API
Source: https://docs.x.com/tutorials/getting-started-with-r-and-v2-of-the-x-api
Tutorial for calling the X API v2 user lookup endpoint from R using httr and jsonlite, including bearer token setup and parsing JSON responses in R.
## Introduction
This tutorial will walk through what you need to get started with the
programming language R and the X API v2. Using R to connect to the
[user lookup](/x-api/users/lookup/introduction) endpoint, I'll show how to work
with JSON returned from the X API. User lookup is a GET method and returns
information about a user or group of users, specified by a user ID or a
username.
If you aren't familiar, R is one of the most popular languages for common Data
Science tasks like time-series analysis, modeling, visualization, and other data
analysis, and is often used in conjunction with the X API. With the user
lookup endpoint, you can use the
[user object](/x-api/fundamentals/data-dictionary/reference#user) to
determine a correlation between the number of followers a person has and the
sentiment score of their bio. The user object may also be used to map a group of
accounts based on the location publicly listed in their profiles.
### Getting started with the X API
Before you can use the X API v2, you will need to
[sign up](https://developer.x.com/en/portal/petition/essential/basic-info)
for a developer account.
Once you have an approved developer account, you will need to first create a
[Project](/resources/fundamentals/developer-apps). Projects allow you to organize your work
based on how you intend to use the X API, so you can effectively manage
your access to the API, and monitor your usage.
Each Project contains an [App](/resources/fundamentals/developer-apps), with which you can
generate the credentials required to use the X API. You can learn more
about how to get started with the X API, in the
[getting started](/x-api/getting-started/about-x-api) section of our
documentation.
### Getting your R environment set up
First, you need to [download R](https://cloud.r-project.org/) which you can do
on the [cran website.](https://cran.r-project.org/)
After, to set up an environment to work with R, you can use
[R studio](https://www.rstudio.com/), the R extension pack for
[Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=Ikuyadeu.r-pack),
or a
[Jupyter notebook](https://docs.anaconda.com/anaconda/navigator/tutorials/r-lang/)
if you come from the Python world.
### Setting up your environment variable
For the code examples, I'm going to be showing today, you will want to create an
environment variable for your bearer token. The Bearer Token is what allows you
to authenticate to the X API and start making requests. First, replace
“your-bearer-token” with your own bearer token, which can be obtained from the
keys and tokens section of your App in the Developer Console. You'll need to run
this line of code in the console before you start writing a script.
```r theme={null}
Sys.setenv(BEARER_TOKEN = "your-bearer-token")
```
### Making your request
You can use the package
[httr](https://cran.r-project.org/web/packages/httr/index.html) to make HTTP
requests to the X API. If you haven't already installed this, please
install the package in your console. You will also need to install
[jsonlite](https://cran.r-project.org/web/packages/jsonlite/index.html) to work
with our JSON object and [dplyr](https://dplyr.tidyverse.org/) for data
manipulation.
```r theme={null}
install.packages("httr")
install.packages("jsonlite")
install.packages("dplyr")
```
You can now begin writing your R script to connect to the API. At the top of the
file, call the packages httr, jsonlite, and dplyr.
```r theme={null}
require(httr)
require(jsonlite)
require(dplyr)
```
The first step in your code sample is to get set up to authenticate to the
X API. Grab the
[Bearer Token](/resources/fundamentals/authentication#using-and-generating-an-app-only-bearer-token) you pulled from
your App, and pass that into your headers for authentication. In the below
example, replace \$BEARER\_TOKEN with your token.
```r theme={null}
bearer_token <- Sys.getenv("$BEARER_TOKEN")
headers <- c(`Authorization` = sprintf('Bearer %s', bearer_token))
```
Once you got your authentication set up, define the parameters of your request.
By default, you will get back the id, name, and username of each user you get
back. You can make adjustments to this payload by adding additional
[fields](/x-api/fundamentals/fields) and
[expansions](/x-api/fundamentals/expansions). For this example, you will want
the profile bio of the user which is requested using user.fields=description,
and an expansion that contains the pinned Post of the user.
```r theme={null}
params <- list(`user.fields` = 'description', `expansions` = 'pinned_tweet_id')
```
Now you are ready to format your URL with the X handle, also known as
account, you are looking to get more information about. Use the readline method
to allow this sample to be reusable. After you type the handle you want to look
at, format your URL to contain the handle you define by replacing \$USERNAME with
the desired X handle.
```r theme={null}
handle <- readline('$USERNAME')
url_handle <- sprintf('https://api.x.com/2/users/by?usernames=%s', handle)
```
At this point, use the httr package to make a GET request to the URL you just
created, pass in our authentication credential via the header, and pass in the
parameters you defined. You can save the response as a text object in the
variable obj and print this out to view the result of the request you made.
```r theme={null}
response <-
httr::GET(url = url_handle,
httr::add_headers(.headers = headers),
query = params)
obj <- httr::content(response, as = "text")
print(obj)
```
### Working with our JSON payload
One of my favorite ways to work with a JSON is to use a data frame, which allows
you to easily access complex nested data. To do this, use the fromJSON method of
the jsonlite package to flatten your file to allow the fields to be in the same
object. Then, pass that object into a data frame. Now you are ready to view this
data frame.
```
json_data <- fromJSON(obj, flatten = TRUE) %>% as.data.frame View(json_data)
```
You can access the fields of the data from the data frame and pass them into a
string that has the handle, the username, and bio.
```r theme={null}
final <-
sprintf(
"Handle: %s\nBio: %s\nPinned Post: %s",
json_data$data.username,
json_data$data.description,
json_data$includes.tweets.text
)
```
Use cat instead of print to view the object with newlines between each field you
are pulling.
```r theme={null}
cat(final)
```
If you had multiple handles you made requests for, you could easily use a loop
to access each data frame element.
### Conclusion
Hopefully, this tutorial can be a starting place to work with R and the X
API. As a next step, you may want to look at our R samples for recent search,
Post lookup and user lookup in our
[v2 sample code](https://github.com/xdevplatform). Be sure to let us know on the
[forums](https://devcommunity.x.com/) if you run into any troubles along the
way or Post us at [@XDevelopers](https://x.com/XDevelopers) if this
tutorial inspires you to create anything.
# Post-processing X data with the Google Cloud Platform
Source: https://docs.x.com/tutorials/post-processing-x-data-with-the-google-cloud-platform
Post-processing X data with the Google Cloud Platform. Documentation for the X developer platform covering post processing x data with the google cloud.
# Getting started with Postman
Source: https://docs.x.com/tutorials/postman-getting-started
Get started with Postman for the X API, including installing Postman, importing the X API collection, configuring OAuth, and sending your first request.
## Introduction
Postman is a desktop and web application that lets you make requests to an API from a graphical user interface. We recommend using Postman with the X API, X Ads API, and Labs endpoints when you explore API functionality or troubleshoot issues with your application.
We currently have two Postman collections available:
### Prerequisites
Before you start with X's Postman collections, make sure you have the right access and credentials for the X developer platform tool you plan to use. See the [Getting started](/overview) page for more on access.
You'll need the following before you continue:
* A [developer account](https://developer.x.com/en/portal/petition/essential/basic-info).
* A [developer App](/resources/fundamentals/developer-apps).
* A set of [authentication](/resources/fundamentals/authentication) keys and tokens.
* An environment configured to make requests to the API you plan to use.
## Getting started with X's Postman collections
### Step one: Add one of the X Postman collections to your account
You could build out specific endpoints in Postman yourself, but we've done the heavy lifting for you. Select one of the links in the [Postman collections](#introduction) section above and a ready-to-use collection with all of the endpoints for the selected API is added to your Postman app. These collections are also available in the [Postman API network](https://explore.postman.com/).
Each endpoint comes preconfigured with available parameters, example responses, and authentication type. You only need to add your credentials and parameter values to start exploring.
In this example, we'll work with the X [API v2 collection](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80).
### Step two: Add your keys and tokens as environmental variables
When you add the collection to your Postman instance, it automatically creates an environment called "X API v2". You need to add your keys and tokens to this environment. In this step, we'll walk you through adding the keys and tokens from your developer App into the "X API v2" environment.
To add your keys and tokens, select the "manage environments" button in the top right corner of Postman.
From the list of environments, select "X API v2".
Next, add a variable for each of the keys and tokens you generated in the Apps dashboard. Here is an example of what your table should look like:
| VARIABLE | INITIAL VALUE | CURRENT VALUE |
| :--------------- | :---------------------------------------------------------------- | :---------------------------------------------------------------- |
| consumer\_key | `QAktM6W6DF6F7XXXXXX` | `QAktM6W6DF6F7XXXXXX` |
| consumer\_secret | `AJX560A2Omgwyjr6Mml2esedujnZLHXXXXXX` | `AJX560A2Omgwyjr6Mml2esedujnZLHXXXXXX` |
| access\_token | `1995XXXXX-0NGqVhk3s96IX6SgT3H2bbjOPjcyQXXXXXXX` | `1995XXXXX-0NGqVhk3s96IX6SgT3H2bbjOPjcyQXXXXXXX` |
| token\_secret | `rHVuh7dgDuJCOGeoe4tndtjKwWiDjBZHLaZXXXXXX` | `rHVuh7dgDuJCOGeoe4tndtjKwWiDjBZHLaZXXXXXX` |
| bearer\_token | `AAAAAAAAAAAAAAAAAAAAAL9v6AAAAAAA99t03huuqRYg0mpYAAFRbPR3XXXXXXX` | `AAAAAAAAAAAAAAAAAAAAAL9v6AAAAAAA99t03huuqRYg0mpYAAFRbPR3XXXXXXX` |
The keys and tokens in the table above are not real and will not work in a request.
Once you've added your credentials as variables and made sure that the X API v2 environment is selected, you're ready to make requests to the X API v2 collection. Each endpoint's authorization tab inherits the variables from this environment automatically.
To use Postman with user access tokens, skip ahead to [Generating a user access token with Postman](#generating-a-user-access-token-with-postman).
### Step three: Select an endpoint
Next, choose an endpoint from the collection and build your request. You can select an endpoint from the right-hand side navigation. Here is what this looks like:
For this example, we'll use the X API v2 > Post Lookup > Single Post endpoint.
#### Step four: Add values to the Params tab
Next, navigate to the Params tab. You should see a set of inactive params with descriptions that explain what each parameter does and a list of the values you can pass with your request.
In this example, we'll activate the `expansions` and `tweet.fields` query parameters and add the following values:
| | |
| :------------- | :----------------------- |
| **Key** | **Value** |
| `tweet.fields` | `created_at,attachments` |
| expansions | author\_id |
In addition to the query parameters, you need to add the required path variable, `id`. Since this endpoint returns Posts, add a valid Post ID as the value.
You can find the Post ID by navigating to x.com, selecting a Post, and looking at the URL. For example, the following URL's Post ID is `1228393702244134912`:
`https://x.com/XDevelopers/status/1228393702244134912`
On the Params tab, scroll down past the query parameters to display the "Path Variables" section. Add the Post ID you want to use as the value for the `id` key.
If you entered everything correctly, the Params tab should look like the following:
#### Step five: Send your request and review your response
Now that your request is set up, select the "Send" button.
If everything was set up properly, you should receive the following payload:
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"author_id": "2244994945",
"text": "What did the developer write in their Valentine's card?\n \nwhile(true) {\n I = Love(You); \n}",
"id": "1228393702244134912",
"created_at": "2020-02-14T19:00:55.000Z"
},
"includes": {
"users": [
{
"username": "XDevelopers",
"name": "Developers",
"id": "2244994945"
}
]
}
}
```
### Generating a user access token with Postman
#### Using OAuth 1.0a to generate a user access token
Review the three-step process used in the [OAuth 1.0a flow test collection](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80).
#### Using OAuth 2.0 to generate a user access token
You can generate OAuth 2.0 access tokens to use with the X [API v2 Postman collection](https://www.postman.com/xapidevelopers/x-api-public-workspace/collection/34902927-2efc5689-99c6-4ab6-8091-996f35c2fd80).
Select the collection in your workspace, go to the "Auth" tab, and set the type to "OAuth 2.0". Under "Configure New Token", find "Configuration Options" and update the "Grant Type" to "Authorization Code (With PKCE)".
Update your Callback URL to match the callback URL associated with your application. Also update the following parameters:
* Auth URL — `https://x.com/i/oauth2/authorize`
* Access Token URL — `https://api.x.com/2/oauth2/token`
* Client ID — Your OAuth 2.0 client ID from the Dev Portal
* Client Secret — If you are using a confidential client
* Scope — Scopes to match the endpoints you want to connect to. For example: `tweet.read users.read`
* Your callback URL (also known as the redirect URL). This must match the value in your App's authentication settings.
* State — state
When you're ready, select "Get New Access Token" to generate an access token. If you see a dialog box that says something went wrong, you may need to select the back button to log in. You'll need to authorize your app to access your account by selecting "Authorize app" in the dialog box.
After you authorize your app, you're directed back to Postman, where you can see your token and select the "Use Token" button to start making requests on behalf of an authorized user.
You're now ready to use the Postman collection.
## What's next
Select the "Code" button in Postman to turn the request into the language of your choice, such as Python, Node, or Ruby, to help you get started. Postman has [great documentation](https://learning.getpostman.com/) that may be helpful. We also have [sample code on GitHub](https://github.com/xdevplatform) to help you integrate with the endpoints more quickly.
# Build for businesses
Source: https://docs.x.com/use-cases/build-for-business
How businesses use the X API for social listening, customer service, brand monitoring, market intelligence, and data-driven decision making at scale.
## Listen to the conversation on x
Understand, track, and benchmark the conversations and perceptions surrounding your brand.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/brand-monitoring)
Stay on top of breaking news and events to spot crises early that might impact your business and brand reputation.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/track-events)
## Use insights from X
Manage and track every aspect of your social presence with targeted tooling and real-time ROI.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/manage-social-media)
Directly engage with your customers to quickly answer questions, resolve their issues, and provide exceptional service.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/customer-care-management)
## Discover new trends and opportunities
Inform your business strategy with insights into emerging trends, customer preferences, and feedback.
Enhance your search results with what’s happening on X.
Understand your audience and what they value by uncovering trends and surfacing important conversations on X.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/market-research)
## Expand what’s possible with X Ads
Enhance the X Ads experience with unique innovations and efficiencies for advertisers.
[**Learn more**](https://developer.x.com/en/use-cases/build-for-businesses/advertise)
## Build for publishers
Engage your users with live X content that brings context to what’s happening and links to the source. Amplify your efforts on X by embedding your X content into your website or app.
[**Learn more**](https://developer.x.com/en/products/x-for-websites)
# Build for the public
Source: https://docs.x.com/use-cases/build-for-consumers
Build consumer apps with the X API that enhance how people post, follow, search, and engage on X, from utilities and chatbots to creator tools.
## Ways to build for people on X
We are opening up our platform to encourage you to build new tools and products that have a positive impact on the public conversation and serve people on X. Specifically, we want to encourage new innovation and development in the following areas:
Improve the health and safety of public conversation. Build content moderation tools and other solutions that help people feel safe and excited to participate on X. Create complementary technology that gives people a comprehensive choice of tools to control their int
[**Learn more**](/x-api/what-to-build#moderate-conversations-for-health-and-safety)
Build tools for creators, brands, and individuals who want to extend their reach, express their brand, and connect with people that share their passion. Or broaden the ways people can engage on X like cross-posted content, gamification, or helpful bots.
[**Learn more**](/x-api/what-to-build#enable-creation-and-personal-expression)
Help people measure, analyze, and derive insights from the public conversation or their own content. Understand your audience better, measure the performance and impact of your content, make more informed decisions, and so much more.
[**Learn more**](/x-api/what-to-build#measure-and-analyze-whats-happening)
X is for everyone, and we want to empower you to use your expertise to serve the unique needs of different communities on X. Whether you're building localized solutions for emerging global markets or enhancing experiences for communities like gaming or finance, we want everyone to find their place on X.
[**Learn more**](/x-api/what-to-build#improve-community-experiences)
Build apps, bots, or other tools that help people discover new content or make new connections. Or build curated and customizable experiences so people see more of the content they care most about.
[**Learn more**](/x-api/what-to-build#curate-and-recommend-content)
Conduct groundbreaking research, help advance knowledge about public health and the climate crises and build non-commercially for the greater good.
[**Learn more**](/x-api/what-to-build#impact-the-greater-good)
# Build for fun
Source: https://docs.x.com/use-cases/build-for-fun
Hobbyist projects to build with the X API, from creative bots and IoT installations to art projects, games, and weekend hacks using real-time data.
## Explore new ways to build for fun
Share your creative energy with the world. Build interactive experiences that spark joy and provoke conversation.
A plant that posts when it needs water? A doorbell that sends you a DM instead
of ringing? These are just some of the fun things that developers have built
to connect X to the internet of things.
Explore all of the corners of the global conversation to learn something new,
get an idea, and broaden perspectives.
Schedule posts, engage with your timeline, or make new connections with a few
lines of code.
Be yourself, the more obscure the better. That’s X.
# Build for good
Source: https://docs.x.com/use-cases/build-for-good
Use the X API for social good, from nonprofit tools and emergency response to community safety, public health, and civic engagement projects.
## Use data to create change
Build tools to bring communities closer during events like #SuperBowl and #GRAMMYs, or all year long with topics like #BlackLivesMatter, #BTS, and #TigerKing.
Keep people safe and informed with tools to automatically share information
like extreme weather updates, public health notices, and more.
Make X better for the people who use it. You've played a key part in making X healthier and more engaging since the beginning, and we want to continue to earn and facilitate your creative energy.
# Do research
Source: https://docs.x.com/use-cases/do-research
Use the X API for academic and market research with access to historical and real-time data, full-archive search, filtered streams, and analytics endpoints.
## Listen to and understand what's happening on X
From social science to computer science, advance nearly any research objective
on topics as diverse as the global conversations happening on X.
Use X data to conduct scientific studies that solve problems to impact the
mission of your non-profit organization or lab.
Use X data to explore global to local topics and events that can inform
projects and publications.
Understand your audience and what they value by uncovering trends and
surfacing important conversations on X.
important conversations on X.
# Teach and learn
Source: https://docs.x.com/use-cases/teach-and-learn
Use the X API in classrooms and curricula to teach API design, data analysis, social media research, and software engineering with real-world data.
## Educators
Bring the API into your classroom to teach students programming fundamentals and
valuable data processing skills.
**Resources:**
Are you an educator looking to use X API in your course? This
[guide to teaching with the X API](https://dev.to/suhemparack/a-guide-to-teaching-with-the-twitter-api-v2-3n08)
will help you understand the X API, why it's used by educators, what type of
classes are being taught with the API, and everything else you need to know to
get started.
**Spotlight:**
The below curriculums are built and executed using the X API v2:
* [Social Media Data Mining and Analysis](https://canvas.uw.edu/courses/1434897)
by Dr. Tanu Mitra
* [Data Science & Society](https://dssoc.github.io/) by Dr. Chris Bail
* [Introduction to Cultural Analytics & Python](https://melaniewalsh.github.io/Intro-Cultural-Analytics/welcome.html)
by Dr. Melanie Walsh
* [Oxford Spring School in Advanced Research Methods, Analysing X Data](https://github.com/cjbarrie/oxspsch)
by Dr. Chris Barrie
## Students
Complete an assignment, learn to process and analyze data, or even post your
first “Hello, world!”
[Become a X Student Ambassador](https://developer.x.com/en/community/student-ambassadors)
# What to Build
Source: https://docs.x.com/what-to-build
Project ideas and use cases for the X API, from chatbots and analytics dashboards to content moderation, research tools, and community apps.
The X API opens up possibilities across moderation, analytics, community building, and more. Here are ideas to inspire your next project.
***
## Build for safety & moderation
Help create healthier conversations on X.
Build tools to help users manage replies, filter content, and protect their experience.
Detect and flag abusive content, provide bulk blocking tools.
**Relevant endpoints:**
* [Blocks](/x-api/users/blocks/introduction) — Block and unblock users
* [Mutes](/x-api/users/mutes/introduction) — Mute accounts and keywords
* [Hide replies](/x-api/posts/hide-replies/introduction) — Hide unwanted replies
* [Manage posts](/x-api/posts/manage-tweets/introduction) — Control reply settings
***
## Build for creators
Help people express themselves and grow their audience.
Schedule posts, threads, and content calendars.
Sync content across platforms and formats.
Help users compose and publish long-form threads.
Create helpful bots that add value to the conversation.
**Relevant endpoints:**
* [Manage posts](/x-api/posts/manage-tweets/introduction) — Create and delete posts
* [Media upload](/x-api/media/quickstart/media-upload-chunked) — Upload images and videos
* [Spaces](/x-api/spaces/lookup/introduction) — Discover audio conversations
***
## Build for analytics
Help users understand their impact and audience.
Visualize engagement metrics, growth trends, and reach.
Analyze followers, engagement patterns, and demographics.
Track hashtags, topics, and conversation volume.
Compare accounts, benchmark performance.
**Relevant endpoints:**
* [Metrics](/x-api/fundamentals/metrics) — Engagement and performance data
* [Search posts](/x-api/posts/search/introduction) — Historical and recent search
* [Post counts](/x-api/posts/counts/introduction) — Volume analytics
* [Annotations](/x-api/fundamentals/post-annotations) — Topic classification
***
## Build for communities
Help people connect and organize around shared interests.
Moderation, member management, and engagement tools.
Organize Spaces, live events, and group activities.
Aggregate and curate content by topic or interest.
Build tools for specific languages and regions.
**Relevant endpoints:**
* [Lists](/x-api/lists/list-lookup/introduction) — Curated account lists
* [Spaces](/x-api/spaces/lookup/introduction) — Audio conversations
* [Follows](/x-api/users/follows/introduction) — Relationship management
***
## Build for research
Analyze public conversations and extract insights.
Study public discourse, information spread, and trends.
Source stories, verify information, track breaking news.
Monitor brand sentiment, industry trends, and competitors.
Train models, analyze networks, study behavior patterns.
**Relevant endpoints:**
* [Full-archive search](/x-api/posts/search/introduction) — Search posts back to 2006
* [Filtered stream](/x-api/posts/filtered-stream/introduction) — Near real-time matching posts
* [Post annotations](/x-api/fundamentals/post-annotations) — Entity recognition
* [Conversation ID](/x-api/fundamentals/conversation-id) — Thread reconstruction
***
## Build for good
Use the API to make a positive impact.
Monitor emergencies, coordinate aid, spread awareness.
Build tools that make X more accessible to everyone.
Create learning tools, teaching resources, and tutorials.
Help people stay informed and participate in democracy.
***
## Build with AI agents
Connect AI tools to the X API and build intelligent workflows.
Use XMCP to give AI assistants direct access to X API endpoints — create posts, search, and manage accounts via natural language.
Feed X data into LLMs for sentiment analysis, content generation, and automated reporting.
Give Grok, Cursor, or your preferred AI tool full context on the X API with llms.txt for faster development.
Build agents that monitor trends, respond to mentions, or curate content automatically.
**Get started:**
* [X MCP](/tools/mcp#x-mcp--x-api) — Hosted MCP server for the X API
* [llms-full.txt](https://docs.x.com/llms-full.txt) — Feed complete docs to your AI tool
* [OpenAPI Spec](https://api.x.com/2/openapi.json) — Machine-readable API definition
[Browse all agent resources](/tools/ai)
***
## Getting started
Ready to build? Here's your path forward:
[Sign up for a developer account](/x-api/getting-started/getting-access) and create an app.
[Make your first request](/x-api/getting-started/make-your-first-request) and explore the API.
Pick an [SDK or library](/tools-and-libraries) for your language.
Start small, iterate, and share what you've built!
***
## Share your work
Built something with the X API? We'd love to see it:
* Share in the [Developer Forum](https://devcommunity.x.com)
* Tag [@XDevelopers](https://x.com/XDevelopers) on X
* Submit to our [Success Stories](/success-stories)
# Analytics
Source: https://docs.x.com/x-ads-api/analytics
Retrieve campaign performance metrics on the X Ads API using synchronous and asynchronous analytics endpoints with segmentation and granularity options.
Analytics metrics help partners and advertisers understand the performance of the content they promote on X. This includes information such as impressions, clicks, video views, and spend. In addition, partners and advertisers are able to get detailed metrics for various segments of the audiences they reach.
The Ads API supports two ways of retrieving detailed campaign performance metrics: synchronously and asynchronously. With synchronous analytics calls, the requested metrics are returned in the response. With the asynchronous analytics endpoints, the requested metrics are available in a downloadable results file after the associated "job" has finished processing. The synchronous endpoint supports short time ranges and is ideal for real-time campaign optimizations. The asynchronous endpoints support much longer time ranges and are, thus, intended for fetching much more data, ideal for generating reporting or historical backfills.
## Details
### Synchronous vs. Asynchronous
The differences between the synchronous and asynchronous analytics endpoints are summarized in the following table. This information is intended to help developers choose which set of endpoints to use.
| Feature | Synchronous | Asynchronous |
| :------------------- | :-------------------------------------------------- | :----------------------------------------------------------- |
| Rate limiting | User-level: 250 requests / 15 minutes | Account-level: 100 concurrent\* jobs |
| Time range | 7 days | 90 days (non-segmented) 45 days (segmented) |
| Segmentation | No | Yes |
| Response returns | Metrics data | Processing state of the job\*\* |
| Recommended use case | Real-time optimization User interface requests | Regularly-scheduled syncing Backfilling historical data |
\* This refers to the maximum number of jobs that may be in a processing state at any given time.
\*\* Once the job has successfully finished processing, a URL is returned. This is where the compressed (gzip) results file can be downloaded from.
Outside of this, the endpoints offer the same functionality.
### Use cases
There are three major analytics use cases.
1. Real-time optimization: using performance metrics to update active campaigns
2. Synchronization: regularly-scheduled background syncs
3. New account on-boarding: backfilling historical data
The synchronous analytics endpoint may be used for real-time optimization to update campaigns based on changes to metrics within the last 5 to 15 minutes. Either endpoint can be used for analytics synchronization. Keep in mind that the desired time range and whether segmentation is required will determine which endpoint to use. New account on-boarding should only be done using the asynchronous analytics endpoints. (The synchronous analytics endpoint should never be used for retrieving large amounts of data.)
The asynchronous analytics endpoints can power dashboards and other UI elements if metrics are synced with a backend process. Your implementation should avoid calling the asynchronous analytics endpoints to fulfill user interface requests.
### Request Options
Analytics requests are scoped to ads accounts and, thus, require the account ID in the resource path. Request options, listed below, are specified as query parameters. The following types of values are required.
* Entities: the entity type as well as up to 20 entity IDs you'd like to request analytics for
* Time range: the start and end times, expressed in ISO 8601
* **Note:** must be expressed in whole hours
* Metric groups: one or more sets of related metrics (see Metrics and Segmentation for a list of metrics within each metric group)
* Granularity: specifies the level of aggregation in which the metrics should be returned
* Placement: determines whether metrics are pulled for ads that served on or off of X
* **Note:** only a single placement value can be specified per request
Use the `start_time` and `end_time` request parameters to specify a time range. These values must be aligned with the specified granularity in the following way.
1. `TOTAL`: specify any time range (within the endpoint's limits)
2. `DAY`: both the start time and end time values must be aligned with midnight in the account's time zone
3. `HOUR`: specify any time range (within the endpoint's limits)
End time is exclusive. For example, a request with `start_time=2026-01-01T00:00:00Z` and `end_time=2026-01-02T00:00:00Z` will return a single day's worth of analytics metrics (not two) as this time range covers only a 24 hour period.
**Segmentation**
Available only through our asynchronous analytics endpoints, segmentation allows partners and advertisers to retrieve metrics broken out by particular targeting values. To request segmented metrics, use the `segmentation_type` request parameter. For more details on segmentation options, see [Metrics and Segmentation](/x-ads-api/analytics#metrics-and-segmentation).
## FAQs
Why don't the Ads API numbers match what's shown in the X Ads UI?
* Make sure you've requested data for all placements: `ALL_ON_TWITTER`, `SPOTLIGHT`, and `TREND`.
* Remember that end times in the Ads API are exclusive; they are inclusive in the Ads UI
Why do the numbers change depending on when I request data?
* As soon as reporting metrics are available, you are able to retrieve them. They are available in near real-time. These early results are estimates, though, and, as a result, are expected to change. Metrics are finalized after 24 hours, with the exception of spend data.
* Spend metrics are generally final within 3 days of the event. However, we process billing data for up to 14 days from the date of the event (for spam filtering, for example).
How can I determine which entity IDs to request for a specific time period?
* Use the [Active Entities endpoint](/x-ads-api/analytics#active-entities-2)
Why are all of the values in the analytics response `null`?
* It's likely that the campaign did not serve during the requested time period
* Use the [Active Entities endpoint](/x-ads-api/analytics#active-entities-2) to determine which entities to fetch analytics for and for what time period
Why does the API show `null` values while the UI shows 0s?
* The UI chooses to display these values as 0s, but the values are equivalent
How can I request metrics associated with a granular placement, such as the X timeline?
* We support the following placement values in analytics: `ALL_ON_TWITTER`, `SPOTLIGHT`, and `TREND`
Is it possible to retrieve metrics for deleted or paused entities?
* Yes. The entity's status does not impact the availability of analytics metrics.
Why don't the segmented values match the non-segmented ones?
* Segmented data is *not* expected to roll-up 100% to the non-segmented data, due to how this information is derived.
Why don't the segmented values from the API match what the Ads Manager UI shows?
* The API returns segmented metrics scoped to the specific entity type you query (CAMPAIGN, PROMOTED\_TWEET). The Ads Manager UI aggregates data across entity types. These are different views of the same underlying data and this is expected behavior.
Is it possible to request data segmented by multiple dimensions?
* We do not support multi-segmentation.
## Best Practices
Some best practices when collecting [analytics](/x-ads-api/analytics) data from the Ads API.
### Rate Limiting and Retries
* On queries that are rate limited (those that return an `HTTP 429` status code), you must inspect the `x-rate-limit-reset` header and retry only at or after the time indicated.
* On queries that result in an HTTP 503 Service Unavailable status code, you must inspect the `retry-after` header and retry only after the time indicated.
* Applications that do not respect the times indicated for retries could have their access to the Ads API revoked or throttled without notice.
### Analytics Metrics In a Nutshell
* All analytics metrics are locked and will not change after 24 hours, with the exception of `billed_charge_local_micro`.
* The `billed_charge_local_micro` metric is an estimate for up to 3 days after the data is returned.
* After 24 hours, this metric can decrease due to credits for overspend (ads served after the given `end_time`) and for billable events that are determined to be junk. This metric changes minimally after 24 hours.
* Please see [Analytics](/x-ads-api/analytics) for more information.
### Fetching Real-time, Non-segmented Data
* Always provide both a `start_time` and an `end_time`.
* Do not pull data for any entities older than 7 days.
* Do request data (ideally) with `HOUR` granularity, as you can always aggregate and roll metrics up to get `DAY` and `TOTAL` granularity.
* Do request data (ideally) at the `line_items` and `promoted_tweets` level, as you can always aggregate and roll these metrics up to get totals across the entire ads entity hierarchy (i.e. for the campaign, funding instrument or account levels).
* Save and store the values of analytics metrics on your side (locally).
* Do not repeatedly query for data that is older than 30 days. This data will not change and should be stored locally.
* All non-segmented data is real-time and data should be available within seconds of an event occurring.
* Group conversion metrics and non-conversion metrics into separate requests.
### Fetching Segmented Data
* Refer to guidelines provided for "Fetching Real-time, Non-segmented Data" above. Additional advice provided below.
* For most segmented data types, it is possible for data to not be complete for up to 1 hour at times. Data segmented by `INTERESTS` can be delayed for up to 12 hours.
* Segmented data is not expected to roll-up 100% to the non-segmented data, due to how this information is derived.
### Fetching Historical Data
* When backfilling data (i.e. adding a new advertiser account), you may need to make several requests in smaller `start_time` and `end_time` chunks.
* Limit your fetches to 30-day date windows.
* Throttle these requests and distribute over time so as not to exhaust your rate limits for these fetches.
### Sample
You can find a sample script demonstrating some of these best practices (`fetch_stats`) on our [ads-platform-tools GitHub](https://github.com/xdevplatform/ads-platform-tools) repository.
## Metrics by Objective
Which metrics are applicable for an entity depends on the [campaign objective](/x-ads-api/campaign-management). Use this guide to determine the relevant metric groups to fetch for each objective type, as well as how additional derived metrics can be calculated.
### `ENGAGEMENTS`
**Relevant metric groups:**`ENGAGEMENT` and `BILLING`.
| | |
| :-------------- | :-------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| Engagement Rate | `engagements/impressions` |
| CPE | `billed_charge_local_micro/engagements` |
### `WEBSITE_CLICKS` and `WEBSITE_CONVERSIONS`
**Relevant metric groups:**`ENGAGEMENT`, `BILLING`, and `WEB_CONVERSION`.
| | |
| :---------------- | :----------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| CPM | `billed_charge_local_micro/impressions/1000` |
| Click Rate | `clicks/impressions` |
| CPLC | `billed_charge_local_micro/clicks` |
| Total Conversions | `conversion_custom` + `conversion_site_visits` + `conversion_sign_ups` + `conversion_downloads` + `conversion_purchases` |
| Conversion Rate | Total Conversions / `impressions` |
| CPA | `billed_charge_local_micro` / Total Conversions |
### `APP_INSTALLS`
**Relevant metric groups:**`ENGAGEMENT`, `BILLING`, `MOBILE_CONVERSION`, and `LIFE_TIME_VALUE_MOBILE_CONVERSION`. `VIDEO` is also applicable if video app card is used in creatives.
| | |
| :------------- | :----------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| CPM | `billed_charge_local_micro/impressions/1000` |
| App Click Rate | `app_clicks/impressions` |
| CPAC | `billed_charge_local_micro/app_clicks` |
| CPI | `billed_charge_local_micro/mobile_conversion_installs` |
### `FOLLOWERS`
**Relevant metric groups:**`ENGAGEMENT` and `BILLING`.
| | |
| :------------- | :------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| CPM | `billed_charge_local_micro/impressions/1000` |
| Follow Rate | `follows/impressions` |
| CPF | `billed_charge_local_micro/follows` |
### `VIDEO_VIEWS`
**Relevant metric groups:**`ENGAGEMENT`, `BILLING`, and `VIDEO`.
| | |
| :------------- | :-------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| CPM | `billed_charge_local_micro/impressions/1000` |
| Video Rate | `video_total_views/impressions` |
| Cost Per View | `billed_charge_local_micro/video_total_views` |
### `VIDEO_VIEWS_PREROLL`
**Relevant metric groups:**`ENGAGEMENT`, `BILLING`, and `VIDEO`.
| | |
| :------------- | :-------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| CPM | `billed_charge_local_micro/impressions/1000` |
| Video Rate | `video_total_views/impressions` |
| Cost Per View | `billed_charge_local_micro/video_total_views` |
## Metrics and Segmentation
This document is an overview of the metrics available from our [Analytics](/x-ads-api/analytics) for each entity type, as well as the available segmentation for each metric.
| | | | | | | |
| :------------------- | :-------------------------- | :-------------------- | :---------------- | :---------------------------------- | :---------------------------------------- | :------------------------------------------------------------------------ |
| | Metric Groups | | | | | |
| Entity | [`ENGAGEMENT`](#engagement) | [`BILLING`](#BILLING) | [`VIDEO`](#VIDEO) | [`WEB_CONVERSION`](#WEB_CONVERSION) | [`MOBILE_CONVERSION`](#MOBILE_CONVERSION) | [`LIFE_TIME_VALUE_MOBILE_CONVERSION`](#LIFE_TIME_VALUE_MOBILE_CONVERSION) |
| `ACCOUNT` | ✔\* | | | | | |
| `FUNDING_INSTRUMENT` | ✔\* | ✔ | | | | |
| `CAMPAIGN` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| `LINE_ITEM` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| `PROMOTED_TWEET` | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
\*Some metrics in the `ENGAGEMENT` metrics family are not available at the account and funding instrument level. See the `ENGAGEMENT` section for details.
### Available Metrics by Metrics Group
#### `ENGAGEMENT`
| | | | | |
| :---------------------- | :------------------------------------------------------------------- | :--------------------- | :------------ | :----------------------------------------- |
| Metric | Description | Segmentation Available | Data Type | Available for Account / Funding Instrument |
| `engagements` | Total number of engagements | ✔ | Array of ints | ✔ |
| `impressions` | Total number of impressions | ✔ | Array of ints | ✔ |
| `retweets` | Total number of reposts | ✔ | Array of ints | ✔ |
| `replies` | Total number of replies | ✔ | Array of ints | ✔ |
| `likes` | Total number of likes | ✔ | Array of ints | ✔ |
| `follows` | Total number of follows | ✔ | Array of ints | ✔ |
| `card_engagements` | Total number of card engagements | ✔ | Array of ints | |
| `clicks` | Total number of clicks, including favorites and other engagements | ✔ | Array of ints | |
| `app_clicks` | Number of app install or app open attempts | ✔ | Array of ints | |
| url\_clicks | Total clicks on the link or Website Card in an ad, including earned. | ✔ | Array of ints | |
| `qualified_impressions` | Total number of qualified impressions | ✔ | Array of ints | |
| `carousel_swipes` | Total swipes on Carousel images or videos | ✔ | Array of ints | |
#### `BILLING`
| | | | |
| :-------------------------- | :--------------------------------- | :--------------------- | :------------ |
| Metric | Description | Segmentation Available | Data Type |
| `billed_engagements` | Total number of billed engagements | ✔ | Array of ints |
| `billed_charge_local_micro` | Total spend in micros | ✔ | Array of ints |
#### `VIDEO`
Notice about video metrics definition changes:
The `video_total_views` metric within the `VIDEO` metrics group reports on 100%-in view for at least 3 seconds and when a user manually clicks on the play button.
Our original video view definition of 100% in view for at least 3 seconds will continue to be available as a new `video_3s100pct_views` metric in the `VIDEO` metrics group. To continue to bid and be charged based on the original view definition, use the newly available `VIEW_3S_100PCT` bid\_unit.
| | | | |
| :--------------------- | :--------------------------------------------------------------------------------------------------------- | :--------------------- | :------------ |
| Metric | Description | Segmentation Available | Data Type |
| `video_total_views` | Total number of video views | ✔ | Array of ints |
| `video_views_25` | Total number of views where at least 25% of the video was viewed. | ✔ | Array of ints |
| `video_views_50` | Total number of views where at least 50% of the video was viewed. | ✔ | Array of ints |
| `video_views_75` | Total number of views where at least 75% of the video was viewed. | ✔ | Array of ints |
| `video_views_100` | Total number of views where at least 100% of the video was viewed. | ✔ | Array of ints |
| `video_cta_clicks` | Total clicks on the call to action | ✔ | Array of ints |
| `video_content_starts` | Total number of video playback starts | ✔ | Array of ints |
| `video_3s100pct_views` | Total number of views where at least 3 seconds were played while 100% in view (legacy `video_total_views`) | ✔ | Array of ints |
| `video_6s_views` | Total number of views where at least 6 seconds of the video was viewed | ✔ | Array of ints |
| `video_15s_views` | Total number of views where at least 15 seconds of the video or for 95% of the total duration was viewed | ✔ | Array of ints |
#### `WEB_CONVERSION`
| | | | |
| :---------------------------------- | :------------------------------------------------------------------------------------------------------- | :------------------------------------- | :---------- |
| Metric | Description | Segmentation Available | Data Type |
| `conversion_purchases` | Number of conversions of type PURCHASE and the corresponding sale amount and order quantity | `PLATFORMS` only | JSON object |
| `conversion_sign_ups` | Number of conversions of type SIGN\_UP and the corresponding sale amount and order quantity | `PLATFORMS` only | JSON object |
| `conversion_site_visits` | Number of conversions of type SITE\_VISIT and the corresponding sale amount and order quantity | `PLATFORMS` only | JSON object |
| `conversion_downloads` | Number of conversions of type DOWNLOAD and the corresponding sale amount and order quantity | `PLATFORMS` only | JSON object |
| `conversion_custom` | Number of conversions of type CUSTOM and the corresponding sale amount and order quantity | `PLATFORMS` only | JSON object |
| `conversion_add_to_carts` | Number of conversions of type ADD TO CART and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_checkouts_initiated` | Number of conversions of type CHECKOUT INITIATED and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_content_views` | Number of conversions of type CONTENT VIEW and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_payment_info_additions` | Number of conversions of type PAYMENT INFO ADDITION and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_add_to_wishlists` | Number of conversions of type ADD TO WISHLIST and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_searches` | Number of conversions of type SEARCH and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_landing_page_views` | Number of conversions of type LANDING PAGE VIEWS and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
| `conversion_subscriptions` | Number of conversions of type SUBSCRIPTIONS and the corresponding sale amount and order quantity | `PLATFORMS` and `CONVERSION_TAGS` only | JSON object |
#### `MOBILE_CONVERSION`
Mobile conversion stats are available only to advertiser accounts enabled for MACT.
| | | | |
| :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------- | :---------- |
| Metric | Description | Segmentation Available | Data Type |
| `mobile_conversion_spent_credits` | Breakdown of mobile conversions of type SPENT\_CREDIT by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_installs` | Breakdown of mobile conversions of type INSTALL by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_content_views` | Breakdown of mobile conversions of type CONTENT\_VIEW by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_add_to_wishlists` | Breakdown of mobile conversions of type ADD\_TO\_WISHLIST by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_checkouts_initiated` | Breakdown of mobile conversions of type CHECKOUT\_INITIATED by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_reservations` | Breakdown of mobile conversions of type RESERVATION by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_tutorials_completed` | Breakdown of mobile conversions of type TUTORIAL\_COMPLETED by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_achievements_unlocked` | Breakdown of mobile conversions of type ACHIEVEMENT\_UNLOCKED by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_searches` | Breakdown of mobile conversions of type SEARCH by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_add_to_carts` | Breakdown of mobile conversions of type ADD\_TO\_CART by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_payment_info_additions` | Breakdown of mobile conversions of type PAYMENT\_INFO\_ADDITION by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_re_engages` | Breakdown of mobile conversions of type RE\_ENGAGE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_shares` | Breakdown of mobile conversions of type SHARE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_rates` | Breakdown of mobile conversions of type RATE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_logins` | Breakdown of mobile conversions of type LOGIN by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_updates` | Breakdown of mobile conversions of type UPDATE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_levels_achieved` | Breakdown of mobile conversions of type LEVEL\_ACHIEVED by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_invites` | Breakdown of mobile conversions of type INVITE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| `mobile_conversion_key_page_views` | Breakdown of mobile conversions of type KEY\_PAGE\_VIEW by post\_view and post\_engagement | ✔ | JSON object |
| mobile\_conversion\_downloads | Breakdown of mobile conversions of type DOWNLOAD by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| mobile\_conversion\_purchases | Breakdown of mobile conversions of type PURCHASE by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| mobile\_conversion\_sign\_ups | Breakdown of mobile conversions of type SIGN\_UP by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
| mobile\_conversion\_site\_visits | Breakdown of mobile conversions of type SITE\_VISIT by post\_view, post\_engagement, assisted, order\_quantity, and sale\_amount | ✔ | JSON object |
#### `LIFE_TIME_VALUE_MOBILE_CONVERSION`
Lifetime mobile conversion stats are available only to advertiser accounts enabled for MACT.
| | | | |
| :-------------------------------------------------------- | :-------------------------------------------------------------- | :--------------------- | :---------- |
| Metric | Description | Segmentation Available | Data Type |
| `mobile_conversion_lifetime_value_purchases` | Breakdown of mobile conversions of type PURCHASE | | JSON object |
| `mobile_conversion_lifetime_value_sign_ups` | Breakdown of mobile conversions of type SIGN\_UP | | JSON object |
| `mobile_conversion_lifetime_value_updates` | Breakdown of mobile conversions of type UPDATE | | JSON object |
| `mobile_conversion_lifetime_value_tutorials_completed` | Breakdown of mobile conversions of type TUTORIAL\_COMPLETED | | JSON object |
| `mobile_conversion_lifetime_value_reservations` | Breakdown of mobile conversions of type RESERVATION | | JSON object |
| `mobile_conversion_lifetime_value_add_to_carts` | Breakdown of mobile conversions of type ADD\_TO\_CART | | JSON object |
| `mobile_conversion_lifetime_value_add_to_wishlists` | Breakdown of mobile conversions of type ADD\_TO\_WISHLIST | | JSON object |
| `mobile_conversion_lifetime_value_checkouts_initiated` | Breakdown of mobile conversions of type CHECKOUT\_INITIATED | | JSON object |
| `mobile_conversion_lifetime_value_levels_achieved` | Breakdown of mobile conversions of type LEVEL\_ACHIEVED | | JSON object |
| `mobile_conversion_lifetime_value_achievements_unlocked` | Breakdown of mobile conversions of type ACHIEVEMENT\_UNLOCKED | | JSON object |
| `mobile_conversion_lifetime_value_shares` | Breakdown of mobile conversions of type SHARE | | JSON object |
| `mobile_conversion_lifetime_value_invites` | Breakdown of mobile conversions of type INVITE | | JSON object |
| `mobile_conversion_lifetime_value_payment_info_additions` | Breakdown of mobile conversions of type PAYMENT\_INFO\_ADDITION | | JSON object |
| `mobile_conversion_lifetime_value_spent_credits` | Breakdown of mobile conversions of type SPENT\_CREDIT | | JSON object |
| `mobile_conversion_lifetime_value_rates` | Breakdown of mobile conversions of type RATE | | JSON object |
### Segmentation
Segmentation reporting allows the retrieval of metrics broken out by the values of a given targeting type. Segmentation is only available through [asynchronous analytics queries](/x-ads-api/analytics#asynchronous-analytics) due to their significant added complexity.
As of May 2026, only the following segmentation types are enabled. METROS returns Nielsen DMA codes as numeric strings (819 = Seattle-Tacoma). Geographic segmentation types such as METROS require the country parameter (96683cc9126741d1 for US).
| | |
| :----------------- | :----------------------- |
| Segmentation Type | `country` param required |
| `AGE` | |
| `GENDER` | |
| `METROS` | ✔ |
| `PLATFORMS` | |
| `CONVERSION_TAGS*` | |
\*The CONVERSION\_TAGS segmentation is only compatible with the WEB\_CONVERSION metric group.
## Derived Metrics
Campaign metrics depend on their [campaign objective](/x-ads-api/campaign-management). Use this guide to determine how to calculate derived metrics for use based on the objectives in place.
Any `metric` without curly brackets is one that is returned by the Ads API [analytics](/x-ads-api/analytics#synchronous-analytics) endpoints. Any name surrounded by `{curly brackets}` indicates a derived metric for that category.
### ENGAGEMENTS
| | |
| :------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{Total Engagements}` | `promoted_account_follows + promoted_tweet_search_engagements + promoted_tweet_timeline_engagements + promoted_tweet_profile_engagements` or `promoted_account_follows + promoted_tweet_search_clicks + promoted_tweet_search_replies + promoted_tweet_search_retweets + promoted_tweet_search_follows + promoted_tweet_timeline_clicks + promoted_tweet_timeline_replies + promoted_tweet_timeline_retweets + promoted_tweet_timeline_follows + promoted_tweet_profile_clicks + promoted_tweet_profile_replies + promoted_tweet_profile_retweets + promoted_tweet_profile_follows` |
| `{Engagement Rate}` | `{Total Engagements} / {Impressions}` |
| `billed_charge_local_micro / {Total Engagements}` | |
### WEBSITE\_CLICKS
| | |
| :------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{Link Clicks}` | `promoted_tweet_search_url_clicks + promoted_tweet_timeline_url_clicks + promoted_tweet_profile_url_clicks` |
| `{Click Rate}` | `{Link Clicks} / {Impressions}` |
| `billed_charge_local_micro / {Link Clicks}` | |
| `conversion_site_visits` | |
| `{Conversion Rate}` | `conversion_site_visits / {Impressions}` |
| `billed_charge_local_micro / conversion_site_visits` | |
### APP\_INSTALLS
| | |
| :------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{App Clicks}` | `promoted_tweet_app_install_attempts + promoted_tweet_app_open_attempts + promoted_tweet_timeline_url_clicks + promoted_tweet_search_url_clicks` |
| `{App Click Rate}` | `{App Clicks} / {Impressions}` |
| `billed_charge_local_micro / {App Clicks}` | |
| `billed_charge_local_micro / mobile_conversion_installs` | |
### FOLLOWERS
| | |
| :----------------------------------------------------- | :----------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_account_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `promoted_account_follows` | |
| `{Follow Rate}` | `promoted_account_follow_rate` |
| `billed_charge_local_micro / promoted_account_follows` | |
### VIDEO\_VIEWS
| | |
| :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| | `billed_charge_local_micro / {Impressions} / 1000` |
| `{Video Views}` | `promoted_video_total_views` |
| `{Video Rate}` | `promoted_video_total_views / {Impressions}` |
| `{Cost Per View}` | `billed_charge_local_micro / promoted_video_total_views` |
### QUALIFIED\_IMPRESSIONS
| | |
| :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| | `billed_charge_local_micro / {Impressions} / 1000` |
| `{Qualified Impressions}` | `promoted_tweet_timeline_qualified_impressions + promoted_tweet_search_qualified_impressions + promoted_tweet_profile_qualified_impressions` |
| `{Qualified Impression Rate}` | `{Qualified Impressions} / {Impressions}` |
| `{Cost Per 1000 Qualified Impressions }` | `billed_charge_local_micro / {Qualified Impressions} / 1000` |
### CUSTOM
For `placement_type` of `PROMOTED_ACCOUNT` see the `FOLLOWERS` objective above. For all other placements with this objective, see `ENGAGEMENTS` for the corresponding derived metrics.
## Guides
### Active Entities
#### Introduction
The [Active Entities endpoint](/x-ads-api/analytics#get-stats-accounts-account-id-active-entities) is designed to be used in conjunction with our [synchronous](/x-ads-api/analytics#get-stats-accounts-account-id) and [asynchronous](/x-ads-api/analytics#asynchronous-analytics) analytics endpoints as it provides information about which campaigns to request analytics for. It does this by returning details about ads entities and when their metrics changed. Using this endpoint will greatly simplify your code and analytics fetching logic.
This guide includes information and context about the endpoint and its data source. It also provides [usage guidelines](#usage) and a series of [example requests](#example), demonstrating how to use Active Entities in conjunction with our analytics endpoints. The [Summary section](#summary) provides a high-level description of the recommended approach.
#### Data
Whenever an ads entity metric changes, we record information about that change. These change events are stored in hourly buckets and include details about the entity as well as the time that the change applies to. The latter is necessary because change events do not always correspond to when they were recorded. Billing adjustments are a common reason for this, but there are others, too.
#### Endpoint
### Request
Active Entities requests are scoped under ads accounts and have three required query parameters: `entity`, `start_time`, and `end_time`.
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t/active_entities?entity=PROMOTED_TWEET&start_time=2026-03-05T00:00:00Z&end_time=2026-03-06T00:00:00Z"`
The following `entity` values are supported: `CAMPAIGN`, `FUNDING_INSTRUMENT`, `LINE_ITEM`, `PROMOTED_ACCOUNT`, and `PROMOTED_TWEET`. This reflects the entity types that our analytics endpoints support.
The `start_time` and `end_time` values must be expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) and specify which hourly buckets to query. These must be expressed in whole hours.
This endpoint also supports three optional parameters that can be used to filter results: `funding_instrument_ids`, `campaign_ids`, and `line_item_ids`. These work at all levels of the ads hierarchy and with any specified `entity` type.
### Response
The Active Entities response for the request above is shown below.
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"entity": "PROMOTED_TWEET",
"start_time": "2026-03-05T00:00:00Z",
"end_time": "2026-03-06T00:00:00Z"
}
},
"data": [
{
"entity_id": "2r0wxw",
"activity_start_time": "2026-03-04T20:55:20Z",
"activity_end_time": "2026-03-05T03:43:56Z",
"placements": [
"ALL_ON_TWITTER"
]
},
{
"entity_id": "2r30fn",
"activity_start_time": "2026-03-05T08:11:08Z",
"activity_end_time": "2026-03-05T14:40:59Z",
"placements": [
"ALL_ON_TWITTER",
"PUBLISHER_NETWORK"
]
}
]
}
```
The `data` array includes an object for every entity that should be included in a subsequent analytics request. You should not request analytics for IDs outside of this set.
Each object includes four fields: `entity_id`, `activity_start_time`, `activity_end_time`, and `placements`. The activity start and end times represent the time range that the associated entity's change events apply to and, thus, determine the dates that should be specified in subsequent analytics requests. The `placements` array can include the following values: `ALL_ON_TWITTER`, `SPOTLIGHT`, and `TREND`. It indicates which placements should be requested for the given entity ID.
#### Usage
The Active Entities endpoint should dictate how analytics requests are made. The following usage guidelines are written to support analytics synchronization, enabling partners to keep their data stores in sync with X. In other words, it describes how to perform regularly-scheduled background syncs.
There are two decisions a developer must make.
1. How often to request active entities information and, thus, how often to pull analytics.
2. How to use the activity start and end times to determine the analytics request's `start_time` and `end_time` values.
These are discussed in greater detail in each of the two subsections, below, after the summary.
### Summary
Use the Active Entities endpoint in the following way to dictate how analytics requests are made. Follow this after you've decided how often to request active entities information and, thus, how often to pull analytics.
1. Make the Active Entities request.
2. Split the response by placement. One group for `ALL_ON_TWITTER`, one for `SPOTLIGHT`, and one for `TREND`.
3. For each placement group, do the following.
1. Extract the entity IDs.
2. Determine the analytics `start_time` and `end_time` values.
* Find the minimum `activity_start_time`. Round this value down.
* Find the maximum `activity_end_time`. Round this value up.
3. Make the analytics request(s).
* Group entity IDs into batches of 20.
* Use the `start_time` and `end_time` values from #3b.
* Specify the appropriate `placement` value.
4. Write to your data store.
Please see [active\_entities.py](https://github.com/xdevplatform/twitter-python-ads-sdk/blob/master/examples/active_entities.py) as an example that uses the Python SDK.
### Frequency
The answer to the first question determines the time range that should be used in Active Entities requests. For example, if requesting active entities information every hour, the time range should be an hour. If requesting active entities information once a day, the time range should be a day. In other words, time ranges should be selected such that the current request's `start_time` is equal to the previous request's `end_time`.
**Note**: A time window should only be requested once. Requesting a time window more than once will lead to unnecessary analytics requests. (Exception below.)
For partners wishing to request analytics multiple times an hour for the *current* hour, the same pattern applies—the frequency determines the time range. The table below shows example Active Entities start and end timestamps for this scenario.
| | | |
| :--------------- | :------------------------- | :----------------------- |
| **Request time** | **`start_time` timestamp** | **`end_time` timestamp** |
| 00:15:00 | 00:00:00 | 00:15:00 |
| 00:30:00 | 00:15:00 | 00:30:00 |
| 00:45:00 | 00:30:00 | 00:45:00 |
| 01:00:00 | 00:45:00 | 01:00:00 |
Given the way that change events are stored, all four Active Entities requests above query the same hourly bucket, which is necessary for this use case. However, after the current hour, this hourly bucket should no longer be queried.
### Activity Times
We recommend the following approach to working with activity start and end times. Across all objects in the Active Entities response, find the minimum `activity_start_time` and the maximum `activity_end_time`. Modify these values by rounding the minimum activity start time down and rounding the maximum activity end time up. Specifically, set the timestamps to zero for both and add one day to the end time, as illustrated in the following table. These are the start and end times that should be specified in subsequent analytics requests.
| | |
| :----------------------------------------------------- | :----------------------------------------------------- |
| **Min, max activity times** | **Derived times** |
| 2026-03-04T20:55:20Z
2026-03-05T14:40:59Z | 2026-03-04T00:00:00Z
2026-03-06T00:00:00Z |
**Note**: It's important to include the timestamps with hours, minutes, and seconds set to zero. Otherwise, if only the date is passed in, we will assume you're requesting analytics starting and ending at midnight in the ads account's timezone, which may not be desirable. For example, if the minimum activity start time is 2026-02-28T01:30:07Z and the timestamp is omitted for an ads account with an offset of -08:00:00, the analytics request will miss changes that happened between 01:30 and 08:00.
Alternatively, if you would prefer to request analytics for just the returned activity time window without expanding to full days, you can. Using this approach, the derived start and end times would be 2026-03-04T20:00:00Z and 2026-03-05T15:00:00Z, respectively. (Note that ranges like these are not accepted if you specify `DAY` granularity in the analytics request.)
#### Example
This section demonstrates how to use Active Entities in conjunction with the synchronous analytics endpoint. (The responses have been slightly modified for readability.) In this example, the Active Entities endpoint is called at the top of each hour, with each request looking at the previous hour. The response determines how the synchronous analytics endpoint is used.
The first Active Entities request is made at 03:00:00. The response indicates that line item dvcz7's metrics changed and that those change events apply to the window between 02:02:55 and 02:28:12.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t/active_entities?entity=LINE_ITEM&start_time=2026-02-11T02:00:00Z&end_time=2026-02-11T03:00:00Z"`
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {},
"data": [
{
"entity_id": "dvcz7",
"activity_start_time": "2026-02-11T02:02:55Z",
"activity_end_time": "2026-02-11T02:58:12Z",
"placements": [
"ALL_ON_TWITTER"
]
}
]
}
```
Based on these activity start and end times and using the approach described above, the analytics `start_time` and `end_time` values are set to 2026-02-11T00:00:00Z and 2026-02-12T00:00:00Z, respectively. We see that the third element in each of the metrics arrays below are non-zero, as we expected based on the active entities information.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t?entity=LINE_ITEM&entity_ids=dvcz7&start_time=2026-02-11T00:00:00Z&end_time=2026-02-12T00:00:00Z&granularity=HOUR&metric_groups=ENGAGEMENT,VIDEO&placement=ALL_ON_TWITTER"`
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "stats",
"time_series_length": 24,
"data": [
{
"id": "dvcz7",
"id_data": [
{
"segment": null,
"metrics": {
"impressions": [
0,0,2792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"engagements": [
0,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"video_total_views": [
0,0,1326,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
]
}
}
]
}
],
"request": {}
}
```
The next Active Entities request happens at 04:00:00 and only looks at the previous hour. As mentioned above, a time window should only be requested once. Based on the response, we see that change events for this line item apply to *both* 02:00:00 and 03:00:00. In the subsequent analytics request, we expect to see changes for both hours.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t/active_entities?entity=LINE_ITEM&start_time=2026-02-11T03:00:00Z&end_time=2026-02-11T04:00:00Z"`
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {},
"data": [
{
"entity_id": "dvcz7",
"activity_start_time": "2026-02-11T02:07:17Z",
"activity_end_time": "2026-02-11T03:49:22Z",
"placements": [
"ALL_ON_TWITTER"
]
}
]
}
```
In addition to seeing non-zero metrics for 03:00:00, we see that the impressions, spend, and MRC video views have been updated from their previous values. Impressions, for example, are now 2,995 for the 02:00:00 hour, up from 2,792. This demonstrates how change events that were recorded during the 03:00:00 hour apply to the 02:00:00 hour.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t?entity=LINE_ITEM&entity_ids=dvcz7&start_time=2026-02-11T00:00:00Z&end_time=2026-02-12T00:00:00Z&granularity=HOUR&metric_groups=ENGAGEMENT,VIDEO&placement=ALL_ON_TWITTER"`
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "stats",
"time_series_length": 24,
"data": [
{
"id": "dvcz7",
"id_data": [
{
"segment": null,
"metrics": {
"impressions": [
0,0,2995,734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"engagements": [
0,0,65,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"video_total_views": [
0,0,1449,342,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
]
}
}
]
}
],
"request": {}
}
```
The Active Entities request at 05:00:00, again looking at just the previous hour, shows that change events apply to the 03:00:00 hour only. The changes to analytics metrics in the subsequent request reflect this.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t/active_entities?entity=LINE_ITEM&start_time=2026-02-11T04:00:00Z&end_time=2026-02-11T05:00:00Z"`
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {},
"data": [
{
"entity_id": "dvcz7",
"activity_start_time": "2026-02-11T03:42:39Z",
"activity_end_time": "2026-02-11T03:48:48Z",
"placements": [
"ALL_ON_TWITTER"
]
}
]
}
```
The analytics response shows that only metrics for the 03:00:00 hour have changed; the values for the 02:00:00 hour are the same as they were during the previous analytics request.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t?entity=LINE_ITEM&entity_ids=dvcz7&start_time=2026-02-11T00:00:00Z&end_time=2026-02-12T00:00:00Z&granularity=HOUR&metric_groups=ENGAGEMENT,VIDEO&placement=ALL_ON_TWITTER"`
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "stats",
"time_series_length": 24,
"data": [
{
"id": "dvcz7",
"id_data": [
{
"segment": null,
"metrics": {
"impressions": [
0,0,2995,753,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"engagements": [
0,0,65,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
],
"video_total_views": [
0,0,1449,351,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
]
}
}
]
}
],
"request": {}
}
```
Finally, at 06:00:00 we see that there are no additional change events. **Note**: This does *not* imply that metrics for this line item cannot change in the future, though.
```text theme={null}
`twurl -H ads-api.x.com "/12/stats/accounts/18ce54d4x5t/active_entities?entity=LINE_ITEM&start_time=2026-02-11T05:00:00Z&end_time=2026-02-11T06:00:00Z"`
```
```json theme={null}
{
"request": {},
"data": []
}
```
### Asynchronous Guide
## API Reference
### Asynchronous Analytics
#### Introduction
The asynchronous analytics endpoints allow partners and advertisers to request metrics by submitting create requests that the server processes asynchronously. (We refer to these as asynchronous analytics "jobs.") With this approach, the client's connection does not need to remain open until the request has been fulfilled.
These endpoints, like their synchronous counterpart, allow partners and advertisers to request detailed statistics on campaign performance. They support requesting data for accounts, funding instruments, campaigns, line items, promoted posts, and media creatives. The difference between these and the synchronous endpoint is that the asynchronous analytics endpoints support longer date ranges, up to 90 days, as well as segmentation. Additional details on the differences between the two can be found on our [Analytics Overview](/x-ads-api/analytics) page.
Unlike our synchronous endpoints, rate limiting is based on the number of concurrent jobs for a given account. In other words, it's based on the number of jobs that can be in a processing state at a given time. We count this at the ads account level.
#### Usage
Retrieving campaign metrics using the asynchronous analytics endpoints is a multi-step process. It involves creating a job, checking whether the job has finished processing, and, finally, downloading the data. The data file must be decompressed. The four specific steps are outlined below.
1. Create the job using the [POST stats/jobs/accounts/:account\_id](/x-ads-api/analytics#asynchronous-analytics) endpoint.
2. Make requests at regular intervals to the [GET stats/jobs/accounts/:account\_id](/x-ads-api/analytics#asynchronous-analytics) endpoint to determine whether the job has finished processing.
3. Once the job has finished processing, download the data file.
4. Unzip the data file.
The response object returned in the data file has the same JSON schema as the synchronous analytics endpoint's response.
Segmented campaign metrics are only available via the asynchronous analytics endpoints. Campaign metrics can be broken out by location, gender, interest, keyword, and more. For a full list of options, see the [Metrics and Segmentation](/x-ads-api/analytics#metrics-and-segmentation) page. In order to request segmented metrics, use the `segmentation_type` request parameter when creating the job.
#### Example
This section demonstrates how to use the asynchronous analytics endpoints.
Start by creating a job using the [POST stats/jobs/accounts/:account\_id](/x-ads-api/analytics#asynchronous-analytics) endpoint. The example below requests engagement metrics—such as impressions, likes, clicks, etc.—for a specific line item over a week's time. (Note that the requested time range goes up to, but does not include March 20th since the timestamp is set to midnight.)
```text theme={null}
$ twurl -X POST -H ads-api.x.com "/12/stats/jobs/accounts/18ce54d4x5t?entity=LINE_ITEM&entity_ids=el32n&start_time=2026-03-12T00:00:00Z&end_time=2026-03-20T00:00:00Z&granularity=TOTAL&placement=ALL_ON_TWITTER&metric_groups=ENGAGEMENT"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"start_time": "2026-03-12T00:00:00Z",
"entity_ids": [
"el32n"
],
"end_time": "2026-03-20T00:00:00Z",
"placement": "ALL_ON_TWITTER",
"granularity": "TOTAL",
"entity": "LINE_ITEM",
"metric_groups": [
"ENGAGEMENT"
]
}
},
"data": {
"start_time": "2026-03-12T00:00:00Z",
"segmentation_type": null,
"url": null,
"id_str": "1120829647711653888",
"entity_ids": [
"el32n"
],
"end_time": "2026-03-20T00:00:00Z",
"country": null,
"placement": "ALL_ON_TWITTER",
"id": 1120829647711653888,
"expires_at": null,
"account_id": "18ce54d4x5t",
"status": "PROCESSING",
"granularity": "TOTAL",
"entity": "LINE_ITEM",
"created_at": "2026-04-01T23:19:46Z",
"platform": null,
"updated_at": "2026-04-01T23:19:46Z",
"metric_groups": [
"ENGAGEMENT"
]
}
}
```
This response does not return the line item metrics. It simply provides information about the job you just created. The job ID is needed to check on the status of the job. This is shown in both the `id` and `id_str` response attributes.
Next, you'll want to check whether the job you've created using the `id_str` from the previous response, has finished processing as indicated by `"status": "SUCCESS"` in the response. This means the data is ready to download. The `url` field contains the download link.
```text theme={null}
$ twurl -H ads-api.x.com "/12/stats/jobs/accounts/18ce54d4x5t?job_ids=1120829647711653888"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"job_ids": [
1120829647711653888
]
}
},
"next_cursor": "1120828505715920896",
"data": [
{
"start_time": "2026-03-12T00:00:00Z",
"segmentation_type": null,
"url": "https://ton.twimg.com/advertiser-api-async-analytics/stats_job_1120829647711653888.json.gz",
"id_str": "1120829647711653888",
"entity_ids": [
"el32n"
],
"end_time": "2026-03-20T00:00:00Z",
"country": null,
"placement": "ALL_ON_TWITTER",
"id": 1120829647711653888,
"expires_at": "2026-04-03T23:19:48Z",
"account_id": "18ce54d4x5t",
"status": "SUCCESS",
"granularity": "TOTAL",
"entity": "LINE_ITEM",
"created_at": "2026-04-01T23:19:46Z",
"platform": null,
"updated_at": "2026-04-01T23:19:48Z",
"metric_groups": [
"ENGAGEMENT"
]
}
]
}
```
While we're passing in a single job ID in the above example, in practice, you'll want to use the `job_ids` parameter to check on the status of multiple jobs at a time by specifying up to 200 job IDs.
Next, download the data file using the listed `url` value.
```text theme={null}
$ wget https://ton.twimg.com/advertiser-api-async-analytics/stats_job_1120829647711653888.json.gz
```
Finally, unzip the data file.
```text theme={null}
`$ gunzip stats_job_1120829647711653888.json.gz`
```
The contents of the file are shown below.
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "stats",
"time_series_length": 1,
"data": [
{
"id": "el32n",
"id_data": [
{
"segment": null,
"metrics": {
"impressions": [
3482
],
"tweets_send": null,
"qualified_impressions": null,
"follows": null,
"app_clicks": null,
"retweets": [
102
],
"unfollows": null,
"likes": [
15
],
"engagements": [
171
],
"clicks": [
30
],
"card_engagements": null,
"poll_card_vote": null,
"replies": null,
"carousel_swipes": null
}
}
]
}
],
"request": {
"params": {
"start_time": "2026-03-12T00:00:00Z",
"segmentation_type": null,
"entity_ids": [
"el32n"
],
"end_time": "2026-03-20T00:00:00Z",
"country": null,
"placement": "ALL_ON_TWITTER",
"granularity": "TOTAL",
"entity": "LINE_ITEM",
"platform": null,
"metric_groups": [
"ENGAGEMENT"
]
}
}
}
```
### Reach and Average Frequency
#### GET stats/accounts/:account\_id/reach/campaigns
Retrieve reach and average frequency analytics for specified campaigns.
### Resource URL
`https://ads-api.x.com/stats/accounts/:account_id/reach/campaigns`
### Parameters
| Name | Description |
| :------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| account\_id *required* | The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests excluding [GET accounts](/x-ads-api/campaign-management/reference#accounts). The specified account must be associated with the authenticated user.
Type: string
Example: `18ce54d4x5t` |
| campaign\_ids *required* | Scope the response to just the desired campaigns by specifying a comma-separated list of identifiers. Up to 20 IDs may be provided.
**Note**: Up to 20 campaign IDs may be provided.
Type: string
Example: `8fgzf` |
| end\_time *required* | Scopes the retrieved data to the specified end time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-26T07:00:00Z` |
| start\_time *required* | Scopes the retrieved data to the specified start time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-19T07:00:00Z` |
### Example Request
`GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t/reach/campaigns?campaign_ids=8fgzf&start_time=2026-05-19&end_time=2026-05-26`
### Example Response
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"campaign_ids": [
"8fgzf"
],
"start_time": "2026-05-19T00:00:00Z",
"end_time": "2026-05-26T00:00:00Z",
"account_id": "18ce54d4x5t"
}
},
"data_type": "reach",
"data": [
{
"id": "8fgzf",
"total_audience_reach": 1217,
"average_frequency": 1.01
}
]
}
```
#### GET stats/accounts/:account\_id/reach/funding\_instruments
Retrieve reach and average frequency analytics for specified funding instruments.
### Resource URL
`https://ads-api.x.com/stats/accounts/:account_id/reach/funding_instruments`
### Parameters
| Name | Description |
| :----------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| account\_id *required* | The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests excluding [GET accounts](/x-ads-api/campaign-management/reference#accounts). The specified account must be associated with the authenticated user.
Type: string
Example: `18ce54d4x5t` |
| funding\_instrument\_ids *required* | Scope the response to just the desired funding instruments by specifying a comma-separated list of identifiers. Up to 20 IDs may be provided.
**Note**: Up to 20 funding instrument IDs may be provided.
Type: string
Example: `lygyi` |
| end\_time *required* | Scopes the retrieved data to the specified end time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-26T07:00:00Z` |
| start\_time *required* | Scopes the retrieved data to the specified start time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-19T07:00:00Z` |
### Example Request
```text theme={null}
GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t/reach/funding_instruments?funding_instrument_ids=lygyi&start_time=2026-05-19&end_time=2026-05-26
```
### Example Response
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"funding_instrument_ids": [
"lygyi"
],
"start_time": "2026-05-19T00:00:00Z",
"end_time": "2026-05-26T00:00:00Z",
"account_id": "18ce54d4x5t"
}
},
"data_type": "reach",
"data": [
{
"id": "lygyi",
"total_audience_reach": 1217,
"average_frequency": 1.01
}
]
}
```
### Synchronous Analytics
#### GET stats/accounts/:account\_id
Retrieve synchronous analytics for the current account. A maximum time range (`end_time` - `start_time`) of 7 days is allowed.
### Resource URL
`https://ads-api.x.com/12/stats/accounts/:account_id`
### Parameters
| Name | Description |
| :------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| account\_id *required* | The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests excluding [GET accounts](/x-ads-api/campaign-management/reference#accounts). The specified account must be associated with the authenticated user.
Type: string
Example: `18ce54d4x5t` |
| end\_time *required* | Scopes the retrieved data to the specified end time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-26T07:00:00Z` |
| entity *required* | The entity type to retrieve data for.
Type: enum
Possible values: `ACCOUNT`, `CAMPAIGN`, `FUNDING_INSTRUMENT`, `LINE_ITEM`, `PROMOTED_ACCOUNT`, `PROMOTED_TWEET` |
| entity\_ids *required* | The specific entities to retrieve data for. Specify a comma-separated list of entity IDs.
**Note**: Up to 20 entity IDs may be provided.
Type: string
Example: `8u94t` |
| granularity *required* | Specify how granular the retrieved data should be.
Type: enum
Possible values: `DAY`, `HOUR`, `TOTAL` |
| metric\_groups *required* | The specific metrics that should be returned. Specify a comma-separated list of metric groups. For more information see [Metrics and Segmentation](/x-ads-api/analytics#metrics-and-segmentation).
**Note**: `MOBILE_CONVERSION` data should be requested separately.
Type: enum
Possible values: `BILLING`, `ENGAGEMENT`, `LIFE_TIME_VALUE_MOBILE_CONVERSION`, `MOBILE_CONVERSION`, `VIDEO`, `WEB_CONVERSION` |
| placement *required* | Scopes the retrieved data to a particular placement.
**Note**: Only a single value accepted per request. For entities with both X and X Audience Platform placement, separate requests are required, one for each placement value.
Type: enum
Possible values: `ALL_ON_TWITTER`, `SPOTLIGHT`, `TREND` |
| start\_time *required* | Scopes the retrieved data to the specified start time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-19T07:00:00Z` |
### Example Request
```text theme={null}
GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t?entity=LINE_ITEM&entity_ids=8u94t&start_time=2026-05-19&end_time=2026-05-26&granularity=TOTAL&placement=ALL_ON_TWITTER&metric_groups=ENGAGEMENT
```
### Example Response
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "stats",
"time_series_length": 1,
"data": [
{
"id": "8u94t",
"id_data": [
{
"segment": null,
"metrics": {
"impressions": [
1233
],
"tweets_send": null,
"qualified_impressions": null,
"follows": null,
"app_clicks": null,
"retweets": null,
"likes": [
1
],
"engagements": [
58
],
"clicks": [
58
],
"card_engagements": null,
"poll_card_vote": null,
"replies": null,
"carousel_swipes": null
}
}
]
}
],
"request": {
"params": {
"start_time": "2026-05-19T07:00:00Z",
"segmentation_type": null,
"entity_ids": [
"8u94t"
],
"end_time": "2026-05-26T07:00:00Z",
"country": null,
"placement": "ALL_ON_TWITTER",
"granularity": "TOTAL",
"entity": "LINE_ITEM",
"platform": null,
"metric_groups": [
"ENGAGEMENT"
]
}
}
}
```
### Active Entities
#### GET stats/accounts/:account\_id/active\_entities
Retrieve details about which entities' analytics metrics have changed in a given time period.
This endpoint should be used in conjunction with our analytics endpoints. The results of this endpoint indicate which ads entities to request analytics for. See our [Active Entities Guide](/x-ads-api/analytics#active-entities) for usage guidelines.
Change events are available in hourly buckets.
* The `start_time` and `end_time` values specify which hourly buckets to query.
* The returned `data` array will include an object for every entity that should be included in subsequent analytics requests.
* **IMPORTANT**: The dates that should be specified in subsequent analytics requests should be determined based on the `activity_start_time` and `activity_end_time` values.
* These values represent the time ranges that the stored change events *apply to*. This is returned per entity.
| | |
| :------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{Total Engagements}` | `promoted_account_follows + promoted_tweet_search_engagements + promoted_tweet_timeline_engagements + promoted_tweet_profile_engagements` or `promoted_account_follows + promoted_tweet_search_clicks + promoted_tweet_search_replies + promoted_tweet_search_retweets + promoted_tweet_search_follows + promoted_tweet_timeline_clicks + promoted_tweet_timeline_replies + promoted_tweet_timeline_retweets + promoted_tweet_timeline_follows + promoted_tweet_profile_clicks + promoted_tweet_profile_replies + promoted_tweet_profile_retweets + promoted_tweet_profile_follows` |
| `{Engagement Rate}` | `{Total Engagements} / {Impressions}` |
| `billed_charge_local_micro / {Total Engagements}` | |
| `{Media Views}` | `promoted_tweet_timeline_media_views + promoted_tweet_search_media_views + promoted_tweet_profile_media_views` |
| `{Media View Rate}` | `{Media Views} / {Impressions}` |
| | |
| :------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{Link Clicks}` | `promoted_tweet_search_url_clicks + promoted_tweet_timeline_url_clicks + promoted_tweet_profile_url_clicks` |
| `{Click Rate}` | `{Link Clicks} / {Impressions}` |
| `billed_charge_local_micro / {Link Clicks}` | |
| `conversion_site_visits` | |
| `{Conversion Rate}` | `conversion_site_visits / {Impressions}` |
| `billed_charge_local_micro / conversion_site_visits` | |
| | |
| :------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `{App Clicks}` | `promoted_tweet_app_install_attempts + promoted_tweet_app_open_attempts + promoted_tweet_timeline_url_clicks + promoted_tweet_search_url_clicks` |
| `{App Click Rate}` | `{App Clicks} / {Impressions}` |
| `billed_charge_local_micro / {App Clicks}` | |
| `billed_charge_local_micro / mobile_conversion_installs` | |
| | |
| :----------------------------------------------------- | :------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_account_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `promoted_account_follows` | |
| `{Follow Rate}` | `promoted_account_follow_rate` |
| `billed_charge_local_micro / promoted_account_follows` | |
| `{Media Views}` | `promoted_tweet_timeline_media_views + promoted_tweet_search_media_views + promoted_tweet_profile_media_views` |
| `{Media View Rate}` | `{Media Views} / {Impressions}` |
| | |
| :---------------------------------------------------------------------------------------------------------------------------- | :------------------------------------ |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| `billed_charge_local_micro / {Impressions} / 1000` | |
| `promoted_tweet_search_card_engagements + promoted_tweet_timeline_card_engagements + promoted_tweet_profile_card_engagements` | |
| `{Lead Rate}` | `{Leads} / {Impressions}` |
| `{Cost Per Lead}` | `billed_charge_local_micro / {Leads}` |
| | |
| :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| | `billed_charge_local_micro / {Impressions} / 1000` |
| `{Video Views}` | `promoted_video_total_views` |
| `{Video Rate}` | `promoted_video_total_views / {Impressions}` |
| `{Cost Per View}` | `billed_charge_local_micro / promoted_video_total_views` |
| | |
| :------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------- |
| Derived Metric | Exposed Metric Calculation |
| `promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions` | |
| | `billed_charge_local_micro / {Impressions} / 1000` |
| `{Qualified Impressions}` | `promoted_tweet_timeline_qualified_impressions + promoted_tweet_search_qualified_impressions + promoted_tweet_profile_qualified_impressions` |
| `{Qualified Impression Rate}` | `{Qualified Impressions} / {Impressions}` |
| `{Cost Per 1000 Qualified Impressions }` | `billed_charge_local_micro / {Qualified Impressions} / 1000` |
**Note**: A maximum time range (`end_time` - `start_time`) of 90 days is allowed.
### Resource URL
`https://ads-api.x.com/12/stats/accounts/:account_id/active_entities`
### Parameters
| Name | Description |
| :----------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| account\_id *required* | The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests excluding [GET accounts](/x-ads-api/campaign-management/reference#accounts). The specified account must be associated with the authenticated user.
Type: string
Example: `18ce54d4x5t` |
| end\_time *required* | Scopes the retrieved data to the specified end time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-26T07:00:00Z` |
| entity *required* | The entity type to retrieve data for.
Type: enum
Possible values: `CAMPAIGN`, `FUNDING_INSTRUMENT`, `LINE_ITEM`, `PROMOTED_ACCOUNT`, `PROMOTED_TWEET` |
| start\_time *required* | Scopes the retrieved data to the specified start time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Type: string
Example: `2026-05-19T07:00:00Z` |
| campaign\_ids *optional* | Scope the response to just entities associated with desired campaigns by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
**Note**: Exclusive with `funding_instrument_ids` and `line_item_ids`.
Type: string
Example: `8wku2` |
| funding\_instrument\_ids *optional* | Scope the response to just entities associated with desired funding instruments by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
**Note**: Exclusive with `campaign_ids` and `line_item_ids`.
Type: string
Example: `lygyi` |
| line\_item\_ids *optional* | Scope the response to just entities associated with desired line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
**Note**: Exclusive with `campaign_ids` and `line_item_ids`.
Type: string
Example: `8v7jo` |
### Example Request
`GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t/active_entities?entity=PROMOTED_TWEET&start_time=2026-02-28&end_time=2026-03-01`
### Example Response
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"entity": "PROMOTED_TWEET",
"start_time": "2026-02-28T08:00:00Z",
"end_time": "2026-03-01T08:00:00Z"
}
},
"data": [
{
"entity_id": "2mvb28",
"activity_start_time": "2026-02-28T01:30:07Z",
"activity_end_time": "2026-03-01T07:42:55Z",
"placements": [
"ALL_ON_TWITTER"
]
},
{
"entity_id": "2mvb29",
"activity_start_time": "2026-02-27T11:30:07Z",
"activity_end_time": "2026-03-01T07:42:50Z",
"placements": [
"ALL_ON_TWITTER",
"PUBLISHER_NETWORK"
]
},
{
"entity_id": "2mvfan",
"activity_start_time": "2026-02-27T09:00:05Z",
"activity_end_time": "2026-03-01T06:06:36Z",
"placements": [
"PUBLISHER_NETWORK"
]
},
{
"entity_id": "2n17dx",
"activity_start_time": "2026-02-28T02:02:26Z",
"activity_end_time": "2026-03-01T07:52:44Z",
"placements": [
"ALL_ON_TWITTER",
"PUBLISHER_NETWORK"
]
}
]
}
```
# Audiences
Source: https://docs.x.com/x-ads-api/audiences
Overview of audience targeting on X Ads, covering Custom Audiences, CRM, web, mobile, and lookalike segments used to reach users in ad campaigns.
**Build highly targeted audiences for your X ad campaigns using first-party data and X engagement signals.**
## Quick links
* [Full API Reference](/x-ads-api/audiences/reference) — All Audience endpoints and objects
* [Guides](#guides) — CRM, Web, Mobile, ID Sync, User Data uploads, FAQ
## Custom Audiences
### Overview
There are multiple ways for partners to create [Custom Audiences](https://business.x.com/en/targeting/tailored-audiences.html).
* [Audience API (CRM)](#crm)
* [Web](#web)
* [Mobile](#mobile)
* [Flexible](#flexible)
Please note that you cannot exclude lookalike custom audiences from targeting. Additionally, you cannot target both a custom audience and a custom audience lookalike on the same ad line item (ad group).
**Audience management**
Audiences can be managed via audience partners and Ads API partners. We offer a series of endpoints in the API to access and maintain custom audiences.
For custom audience information, we offer 2 endpoints:
* [GET accounts/:account\_id/custom\_audiences](/x-ads-api/audiences)
* [GET accounts/:account\_id/custom\_audiences/:custom\_audience\_id](/x-ads-api/audiences)
For more details on how to upload and manage audiences, view the [Audience API guide](/x-ads-api/audiences).
**Processing Times**
Generally speaking audience changes are processed in batches that run every 6-8 hours. While an audience change is processing the existing audience to be updated is unaffected. We do not recommend making more than one update for additions and one update for removals per audience within this timeframe.
**Targeting**
An audience can only be targeted if it matches at least 100 users active within the past 90 days on X-owned and -operated clients. [GET accounts/:account\_id/custom\_audiences/:custom\_audience\_id](/x-ads-api/audiences) will indicate if an audience may not be targeted because it matches too few users.
**Audience API (CRM)**
Audience or API partners provide a list of hashed identifiers and X performs a match and produces segments that are made available against media buying on X. Partners can create these audiences with the [Audience API](/x-ads-api/audiences).
**How it works?**
**Web**
We offer a standard cookie matching process when working with MPP audience partners to identify segments to target against media buying on X. In addition, advertsiers can setup a [X Web Event Tag](/x-ads-api/measurement/web-conversions#web-event-tags) to collect website user data and create a corresponding Custom Audience.
**Setup Steps**
**How it works?**
**Mobile**
Please see [the Custom Audiences from Mobile Apps blog post](https://blog.x.com/2014/introducing-tailored-audiences-from-mobile-apps) for details.
**Flexible**
[Flexible audiences](/x-ads-api/audiences) give advertisers the ability to build and save audience combinations based on existing custom audiences or subsets of existing custom audiences. Subsets of a custom audience’s members can be targeted based on the recency and frequency of interaction.
**Restricted Use Cases for Custome Audiences**
[Read more about restrictions](https://developer.x.com/en/developer-terms/more-on-restricted-use-cases "Read more about restrictions")
### Audiences FAQ[](#real-time-tailored-audiences "Permalink to this headline")
**Q: We pushed a huge amount of data, why does the audience size show up as TOO\_SMALL?**
A: Currently the data is being added into audience in realtime, but the job which processes data to provide audience size will run only after a period of time. The correct audience size should be displayed in the UI after a matter of hours.
**Q: We finished sending audience data, and waited 24 hours or more, but still cannot target the audience - what should we do as next steps?**
A: Please confirm that the following things:
* The user ID being passed is correct and not malformed.
* The audience names being passed are correct and match previous membership updates.
* Please confirm the response from POST commands.
* Please confirm the ID Sync pixel is implemented correctly, and as described by ID Sync process enough users have visited the site in question to map users. Unmapped users in the membership updates will not be translated into targeted users.
If all else are confirmed as correct and working, please contact X product contacts with information as detailed as possible (see [Guide to Partner Inbounds](/x-ads-api/introduction) for example of preferred information).
**Q: How many times can we call the endpoint, and with what algorithm?**
A: We strongly recommend that you call our system with incremental deltas, and never re-send the complete audience memberships. The system has been tested to have a throughput sufficient to process incremental data updates for some of the largest websites in the world. The initial upload of audiences should be carefully throttled and first upload is expected to take a significant amount of time to complete.
**Q: What is the minimum size for an audience to be used for targeting?**
* The minimum size for an audience to is 100 users (post match). If an audience with less than 500 users is matched, it will not be available for targeting in the X Ads UI.
**Q: How long will it take to process the audience files? And how long will it take for the audience files to be ready in the X User Interface?**
* It typically takes 4-6 hours to process the audience files, but that will depend on the size of the file. Once the file is processed the audiences are available on the X Ads UI.
**Q: How is the match rate calculated?**
* Match Rate = 90 day active X users / number of users provided
**Q: How do we test if an audience file is working properly?**
* You can provide a test audience file and use “keltonlynn” as the advertiser handle. We can then verify that the file is able to be properly ingested and loaded into the X UI.
**Q: What is a partner user identifier (`p_user_id`)?**
* This is the identifier that is used by your company to uniquely identify each of your customers.
**Q: What is a standard ID?**
* This can be an email address, device ID, X @handle or ID).
**Q: How do I get the HMAC Key?**
* This will be provided by an encrypted email. Please provide your public PGP key to [mpp-inquiry@x.com](mailto:mpp-inquiry%x.com) and we will send you a test email to verify that everything is working. Once verified, we will send you the HMAC Key.
**Q: How do I verify that the hashing process worked using the given HMAC Key?**
* X will provide a test file (containing sample email addresses, device IDs, etc…) and a resulting hash file that you can verify your results against.
**Q: Is there a file size limitation for the full data match file?**
* No, there is no size limitation for the full data match file.
**Q: How long will it take for the full data match file to be processed?**
* Once the file is received by X, it will take approximately 1 day to process the file.
### CRM
This document describes the integration details for Custom Audiences CRM partners including file formats & data exchange process.
**Summary**
Company will provide a list of hashed common user identifiers (i.e. e-mail addresses) or partner user IDs on behalf of a customer to X to perform a blind match and produce a list of X User IDs for targeting. The segments for targeting will be made available to the advertiser’s specific @handle specified by the filename in ads.x.com campaign setup.
All files from Company will be provided to X through a secure package on IronBox ([www.golockbox.com](http://www.golockbox.com)) through a specific account granted to Company by X. X will provide access to IronBox. Documentation on IronBox APIs can be found at [https://secure.goironcloud.com/Docs/Help/](https://secure.goironcloud.com/Docs/Help/).
#### Partner ID Matching Requirements
If company uses its own standard ID system to track users (i.e. not common user identifiers like email addresses, device ids, X user ID, etc...) then this is the recommended process.
**1. Full Data match**
Initially, Company will provide a comprehensive list of all user records which include a unique common user identifier with X in a single file to perform a full data match and produce a mapping stored by X of Partner IDs (`p_user_id`) to X IDs (`tw_id`). This will be done on a 2-3 month basis regularly to ensure proper upkeep. Once the match is completed, X will share a baseline match rate from this file with Company via e-mail.
The format of this file should be:
Name Convention: FullDataMatch.\[CompanyName].txt
Hashing Algorithm: HMAC\_SHA-256
Format:
Column 1: HMAC hashed value of common identifiers
Column 2: Partner User ID (unique per user, non-unique in file)
Column Delimiter (CSV): Commas will be used to delimit the hashed common user identifier from the Partner ID
Line separated values
* Ex: If user record A has Partner User ID 1 and common identifier 1, 2 and 3:
| | |
| :----------------------- | :--------- |
| common user identifier 1 | p\_user\_1 |
| common user identifier 2 | p\_user\_1 |
| common user identifier 3 | p\_user\_1 |
\*See Hashing Directions section for common user identifiers below
**2. Custom Segment Lists**
Company will provide lists of users in the form of `p_user_id` to create custom audiences for customers for targeting on X.
* Line separated values
* `p_user_id`
* * (Same as provided in 1. Full Data Match section above. If the value provided in full data match is hashed then Company will provide same hashed value in audience file. If value provided is not hashed then Company will provide unhashed value.)
#### Standard Matching Requirements
If company does not use a standard ID for mapping of all customer user identifiers, this is the recommended process.
**Custom Segment Lists**
Company will provide lists of hashed common user identifiers directly to X on behalf of customers to create custom audiences.
The format of this file should be:
* Line separated values
* Hashed common user identifier (i.e. e-mail address)
* Follow file naming conventions outlined below
* Follow hashing directions for e-mail addresses below (in Hashing Directions)
#### Custom Segment List File Naming & Operations
The operation of a file will be dictated by the name of the file with the following available operations and general file naming convention: audiencename\_partnername.handle.operation.filetype
* audiencename: The name of the Custom Audience. This field is the name that will be displayed when selecting the audience in the ads.x.com campaign setup UI e.g. brand\_loyalty\_card\_holders.
* partnername: Name of the company delivering the data on behalf of advertiser e.g. company\_name.
* handle: X Account (@handle) that will have access to Custom Audiences e.g. @pepsi, @dietpepsi
* operation: new, add, remove, removeall, replace (details below)
* : Standard Unix epoch time in seconds, used to ensure that each audience file uploaded is unique
* filetype: file should be in \*.txt format
#### Creating and Updating Audiences
Create a new audience with a single file e.g. loyalty\_card\_holders\_partnername.pepsi.new\.txt
Add - Add the matches from a list to an existing audience e.g. loyalty\_card\_holders\_partnername.pepsi.add.txt
Remove - Remove the matches from a list from an existing audience Ex: loyalty\_card\_holders\_partnername.pepsi.remove.txt
Remove All - Remove the matches produced from a regularly updated cumulative list from all audiences for that client (i.e. Client’s Opt Out List). Ex: partnername.pepsi.removeall.txt
* This can be used for a comprehensive list of users who have opted-out from the Advertiser.
* X will only respect the latest list provided in this file, and will respect across all existing and future audiences for matched.
X users at the time this file was provided & processed.
Replace - Remove an existing audience and replace it with a new audience list. Ex: loyalty\_card\_holders\_partnername.pepsi.replace.txt
Overall Company Opt-Out - Company will provide a cumulative Opt-Out file to remove users that have opted out as per the Company’s Opt-Out policy.
X will only respect the latest list provided in this Company Opt-Out file and will respect across all existing and future audiences for matched X users at the time this file was provided & processed. The format of the Company Opt-Out file will be as follows: Ex: partnername.removeall.txt
Delete - Remove an existing audience from the current list of audiences e.g. Ex: loyalty\_card\_holders\_partnername.pepsi.delete.txt
#### Hashing Directions
X will securely share a base64 encoded production key via PGP for hashing common user identifiers (i.e. email addresses). Company will base64 decode the key to produce a 32-byte key to be used to perform the hashing.
Example base64 encoded key:
BrQvOg+dACBUmKjRiNxZgJLh6zydjS0ZOv80FelTNzM=
Example Base64 decoded key:
/:� TшY
Normalization: Company will perform basic normalization on the common user identifiers before hashing (except on Device IDs, see Device ID Normalization section).
#### E-mail Normalization
Namely, strip out the leading and trailing spaces and also lowercase the email address.
Ex: Raw e-mail address: testemail\_Organisational\_baseball+884`@`It92I6Ev2B`.`Com
After normalization: testemail\_organisational\_baseball+884`@`it92i6ev2b`.`com
Hashed value: 74d9584eded0ad1e5572a1c1849f3716751d371d6117a6155dad5363f4b4fbec
Note: The specific number of characters for both the encoded hmac and key could vary based on the input and the encoding so the specific number of characters.
#### Device ID Normalization
We will have the same requirements for hashing of device IDs using a SHA-256 hashing algorithm and a common salt that we provide to data partners. We strip out spaces like we do with email addresses, but there is no lowercase normalization for IDFAs/Android IDs and the exact format of the IDFA/Android ID should be used.
Here is example raw format of Device IDs for iOS & Android, pre-hashing:
iOS IDFA: DD99CFF7-6186-4602-9DF2-ED3FD0B2D431
Android ID: b5bf2122961b3595
Hashed iOS IDFA: 134fb8cd95c7fd42e2793f469a447198ca5f990968db2dbadad70e723ed9750b
Hashed Android ID: 130dddff1939f229476f50bc8adab8fcb7e3525b0e9604fe8effc15e68cee4a4
#### X User ID Normalization
X IDs will still be hashed as the grouping of data - ie Customer List of @handles - is private to the advertiser even though it is not PII. We will have the same requirements for hashing of X IDs using a SHA-256 hashing algorithm and a common salt that we provide to data partners. Spaces should be stripped out of both the X ID/`@`username, but User IDs do not require normalization. @usernames should be lowercased for normalization. And the @ symbol should not be included as part of the username.
The raw ID format will be:
* User ID: 27674040
* @username: testusername
Hashed User ID: bf6b57d4e861e83bea8bbed2b800b251a64c95468ee6e8cb07c3368c9ed45e85
Hashed @username: 12201ae78ad1afa907c7112d17f498154ffb0bf9ea523f5390e072a06d7d9812
### ID Sync Integration
Partners sending data with a `p_id` must undergo an ID Sync process to generate a mapping of the advertiser or partner’s user ids to X user ids. This allows advertisers to directly target their own user segments on X. Partners must also set the value of the param `user_identifier_type` to either `TALIST_PARTNER_USER_ID` or `TAWEB_PARTNER_USER_ID` while sending their membership updates.
* **Web Only**: This can be done by placing a pixel on the advertiser’s site, as outlined below.
* **List**: This can be done using any of the methods described on the [CRM](/x-ads-api/audiences/reference#crm) page.
#### Pixel URL
| |
| :----------------------------------------------------------------- |
| **Base URL** |
| [https://analytics.x.com/i/adsct](https://analytics.x.com/i/adsct) |
#### Pixel Parameters
| | |
| :------------ | :---------------------------------- |
| **Parameter** | **Description** |
| `p_id` | Your X-assigned partner id |
| `p_user_id` | The user’s id in the partner system |
#### ID Sync Pixel:
Using an example partner id of 111, and an example `p_user_id` of abc, the constructed pixel would be the following:
```json theme={null}
```
**Opt-Out File Configuration and Sending Opt-Out Files**
Partners should provide X with a list of users that to the partner’s best knowledge have selected to opt-out of targeted ad delivery. The format of file should be sent as:
| | | | |
| :---------------- | :---------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Column Number** | **Column Name** | **Column Type** | **Description** |
| 1 | Partner ID | string | The “partner id” is the ID that X provides to the Partner in order to uniquely identify each Partner. |
| 2 | The user’s id in the partner system | string | The `p_user_id` is the unique ID that is used to identify the user by the Partner. The file containing these opt-out users should be uploaded using the [TON upload](/x-ads-api/audiences) endpoint and the path of uploaded data should be sent to the Global Opt Out endpoint here:[PUT accounts/:account\_id/custom\_audiences/global\_opt\_out](/x-ads-api/audiences). |
**Sending Membership Updates**
As specified in our endpoint documentation, when passing users via the [POST custom\_audience\_memberships](/x-ads-api/audiences) endpoint you should pass a customer ID to enable a cookie based match. Partners sending data with a `p_id` **must** set the `user_identifier_type` to `TALIST_PARTNER_USER_ID` or `TAWEB_PARTNER_USER_ID`.
All other steps will remain the same as those listed in the [Real-Time Audience API Integration Guide](/x-ads-api/audiences)
### Custom Audiences User Data
This document outlines the format for \[Custom Audience]/x-ads-api/audiences user data.
**Data normalization**
**Device IDs**:
* IDFA - lower-cased with dashes; ex: `4b61639e-47cc-4056-a16a-c8217e029462`
* AdID - original format on device is required, not capitalized with dashes; ex: `2f5f5391-3e45-4d02-b645-4575a08f86e`
* Android id - original format on device is required, not capitalized without dashes or spaces; ex: `af3802a465767e36`
**Email Addresses**:
* lowercase, remove leading and trailing spaces; ex: `support@x.com`
**X Usernames**:
* no @, lowercased and leading and trailing spaces trimmed; ex: `jack`
**X User IDs**:
* Standard integer; ex: `143567`
**Data hashing**
The data for each line must be hashed using `SHA256`, without a salt. Additionally, the final output hash must be in lower case. E.g., 49e0be2aeccfb51a8dee4c945c8a70a9ac500cf6f5cb08112575f74db9b1470d and \*\*not \*\*49E0BE2AECCFB51A8DEE4C945C8A70A9AC500CF6F5CB08112575F74DB9B1470D
```
# hasing user @AdsAPI using python
import hashlib
hashlib.sha256("adsapi".encode()).hexdigest()
#output
49e0be2aeccfb51a8dee4c945c8a70a9ac500cf6f5cb08112575f74db9b1470d
```
Additional code samples for hashing can be found at [github.com/xdevplatform/ads-platform-tools](https://github.com/xdevplatform/ads-platform-tools).
### Custom Audiences: Web
**Information**
Partners will send a list of IDs (`p_user_ids`) to target on behalf of an advertiser. This is accomplished through an ID Sync process that builds a mapping between the `p_user_ids` and X user ID. This mapping is then used to produce lists of X User IDs that can be used for Targeting. These custom audiences will be made available on the advertiser’s specific @handle specified by the label on ads.x.com Custom Audiences Web campaign setup.
X will provide the secure pixel that can be dropped on partner tags and sites in order to match the IDs (`p_user_ids`) to X user IDs. Once the ID Sync process is complete, the targeting files will be created by the partner and will be made available to X through an HTTPS endpoint. These targeting files are ingested on a regular basis by X and are then made available in the X UI.
**X Secure Pixel**
The X secure pixel will look as follows:
[https://analytics.x.com/i/adsct?p\\\_user\\\_id=xyz\&p\_id=123](https://analytics.x.com/i/adsct?p\\_user\\_id=xyz\&p_id=123)
**`p_user_id`** - xyz represents the partner user ID that is provided by the Partner
**`p_id`** - 123 represents the unique ID for the Partner (provided by X)
**Partner HTTPS Endpoint & Targeting User File**
Partner will need to provide X with an HTTPS endpoint and credentials (username/password) that can be used to ingest the targeting file on a regular basis. A sample HTTPS endpoint will look as follows:
```
https:///twitter/partner_targeting_%Y-%M-%D.tsv.gz
```
%Y - Format Code for Year (YYYY)
%M - Format Code for Month (MM)
%D - Format Code for Day (DD)
The transmitted data will consist of the following files:
1. Partner Targeting User File
2. Targeting Conversion File
All the files will be in the TSV format, where the individual fields of each row are separated from each other by a tab character. Valid field values themselves will never contain the tab character.
**Allowed X IP Range:**
Here is the range of IPs that can be allowed for access to the Partner Endpoint.
* 199.16.156.0/22
* 199.59.148.0/22
**Partner Targeting User File:**
| **Column Number** | **Column Name** | **Column Type** | **Description** |
| :---------------- | :--------------- | :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | partner id | string | The “partner id” is the ID that X provides to the Partner in order to uniquely identify each Partner. |
| 2 | advertiser id | string | The “advertiser id” is the @handle for the advertiser. |
| 3 | p\_user\_id | string | The “p\_user\_id” is the unique ID that is used to identify the user by the Partner. |
| 3 | confidence score | integer | The “confidence score” is optional. Our recommendation for confidence score is to use 0-100. If the use case is for retargeting, then a confidence score of “100” is a user who has been directly retargeted. Any score from 0-99 would correspond to the level of confidence of the look-alike. |
| 4 | segment label | string | The “segment label” is optional. Partners can use “segment label” to specify product categories, for example. Our recommendation is to use this “segment label” as this is the human readable name for Custom Audiences in the ads.x.com UI. |
**Notes:**
Every time we receive a new Partner Targeting File, we expect this to be the full list of users that Partner recommends us to target, not incremental, unless otherwise agreed upon. We will agree with each partner what the frequency of delivery of this Partner Targeting File will be. If we do not receive a Partner Targeting File as expected, we will use the previous version with some pre-defined expiration time.
## Audience API Integration
### Overview
The Audience API was launched as part of [v4](/x-ads-api/introduction) of the Ads API and with it, brings several improvements to the legacy Audiences endpoints. This new endpoint is backed by a new Audience processing backend, and brings several improvements in terms of stability, robustness and reliability. The purpose of this guide is to highlight the differences between the Audience API and the legacy Audience upload and management processes.
Reference documentation can be found on the [Audience API](/x-ads-api/audiences) reference documentation page.
**Note**: All Audience user data must be SHA-256 hashed prior to upload. More details, along with the accepted user identifier types and data normalization can be found on the [user data](/x-ads-api/audiences) page.
**Changes to Audience Functionality**
The following changes to Custom Audiences have been introduced as of v4 and any deprecated endpoints will no longer be available once v3 of the Ads API has been sunset:
* **Deprecated** TON Upload:
* GET accounts/:account\_id/custom\_audience\_changes
* GET accounts/:account\_id/custom\_audience\_changes/:custom\_audience\_change\_id
* POST accounts/:account\_id/custom\_audience\_changes
* PUT accounts/:account\_id/custom\_audiences/global\_opt\_out
* **Deprecated** Real Time Audiences:
* POST custom\_audience\_memberships
* Custom Audience:
* The `list_type` parameter will be removed from the request and response on all [Custom Audience](/x-ads-api/audiences) endpoints. This parameter was previously used to identify the user identifier type of the Audience (i.e., email, X User ID, etc.) however Audiences now have the ability to accept multiple user identifiers for the same Audience thereby making this value irrelevant.
* General:
* The Audience lookback window has been updated to match against users active within the past 90 days (from 30 days)
* The minimum number of matched users required for an audience to be targetable has been decreased to 100 users (from 500 users)
**Prerequisites**
* Ads API access
* For access to the Audience endpoint, you will need to be added to an allowlist. Please fill this form and accept the new [X Ads Products and Services Agreement](/x-ads-api/introduction) if initially accepted prior to 2018-08-01
**Audience Upload Process**
The following table lists the primary differences between the old and new Audience creation flows, with more details available further below:
| Step in Process | Audience API | (Deprecated) TON Upload |
| :---------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------- |
| Create a shell Audience | Can be created via the \[POST custom\_audience endpoint]/x-ads-api/audiences | Can be created via the \[POST custom\_audience endpoint]/x-ads-api/audiences |
| Add a new user | Use the `operation_type` `Update` with the [Audience endpoint](/x-ads-api/audiences) | Use the `operation` `ADD` with the [POST custom\_audience\_changes](/x-ads-api/audiences) endpoint |
| Remove a user | Use the `operation_type` `Delete` with the [Audience endpoint](/x-ads-api/audiences) | Use the `operation` `REMOVE` with the [POST custom\_audience\_changes](/x-ads-api/audiences) endpoint |
| Opting-Out Users | Use the `operation_type` `Delete` with the [Audience endpoint](/x-ads-api/audiences) and the corresponding `custom_audience_id`s that the user is a part of | Use the [Global opt-out endpoint](/x-ads-api/audiences) |
**Note** Any audiences being updated or opted-out via the TON Upload path must have a corresponding list uploaded via the [TON Upload](/x-ads-api/audiences) endpoint and associated with an Audience using the [custom\_audience\_changes](/x-ads-api/audiences) endpoint.
**Rate Limiting**
The Audience API endpoint has a rate limit of 1500/1min per account. There are no limits on the number of users that can be sent in a single payload. The only constraints on the payload are:
1\. Total number of operations: 2500 operations
2\. Maximum payload size: 5,000,000 bytes
**Audience User Management**
In order to create a new Audience, the following steps are required
### Create a new Custom Audience
Create a new Custom Audience "shell" using the \[POST custom\_audience]/x-ads-api/audiences endpoint and retrieve the corresponding Custom Audience `id`. This step is required if creating an Audience from scratch. If updating an existing Audience, skip to the next section
### Add Users to an Audience
Use the [POST accounts/:account\_id/custom\_audiences/:custom\_audience\_id/users](/x-ads-api/audiences) with the Custom Audience `id` and a sample payload like so:
POST [https://ads-api.x.com/11/accounts/18ce54d4x5t/custom\_audiences/1nmth/users](https://ads-api.x.com/11/accounts/18ce54d4x5t/custom_audiences/1nmth/users)
```
# All values must be hashed, unhashed values are used in this example for illustrative purposes
[
{
"operation_type": "Update",
"params": {
"effective_at": "2018-05-15T00:00:00Z",
"expires_at": "2019-01-01T07:00:00Z",
"users": [
{
"email": [
"abc@x.com"
],
"handle": [
"x",
"adsapi"
]
},
{
"email": [
"edf@x.com"
],
"twitter_id": [
"121291606",
"17874544"
]
}
]
}
}
]
```
In order to add a user to an Audience, use the `operation_type` `Update`. The new Audience interface enables the ability to pass in multiple user keys for a single user. Each object in the array of JSON objects corresponds to a single user. Using the example payload above, the request will add two users to an Audience, one with an `email` and `handle` and another with an `email` and `twitter_id`.
#### Remove Users from an Audience
Similar to the process outlined for adding users, users can be removed from an audience using like so:
POST [https://ads-api.x.com/11/accounts/18ce54d4x5t/custom\_audiences/1nmth/users](https://ads-api.x.com/11/accounts/18ce54d4x5t/custom_audiences/1nmth/users)
```
# All values must be hashed, unhashed values are used in this example for illustrative purposes
[
{
"operation_type": "Delete",
"params": {
"effective_at": "2018-05-15T00:00:00Z",
"expires_at": "2019-01-01T07:00:00Z",
"users": [
{
"email": [
"abc@x.com"
],
"twitter_id": [
"783214",
"1225933934"
]
},
{
"email": [
"edf@x.com"
],
"twitter_id": [
"121291606",
"17874544"
]
}
]
}
}
]
```
The `operation_type` must be set to `Delete` and users will be matched on any keys that were present when adding users to the audience. For example, if a user was added to an audience using an `email` and `twitter_id`, then the same user can be removed using any one of these keys, i.e., either `email` or `twitter_id` or both.
Additionally, it is possible to add and remove users from an Audience within the same request. The endpoint supports multiple `operation_type` per request.
#### Opt-Out Users
With the deprecation of the global opt-out endpoint, partners are required to `Delete` any users that have opted-out of any Audiences. There are a few ways to achieve this:
1. Keep track of which users are part of which Audiences and remove these users individually from each Audience.
2. Remove the user from **all** Audiences associated with an Ads account.
**General Best Practices**
* We strongly recommend calling this endpoint in near real-time batches to avoid spiky queues which take longer to process and in general cause unnecessary load on our system. This also ensures users are available for campaign targeting sooner.
* A successful API call will return a `success_count` and `total_count` corresponding to the number of `user` objects that have been received in the request.
* This endpoint is atomic in nature, that is, either the entire request is successful or in case of any errors then the entire request will fail. In case of an error response, consumers of the API are recommended to fix the error and retry the request with the entire payload.
* Upon failure, partners recommended to use an [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) approach with retries. For example, retry immediately upon the first failure, retry after 1 minute after the second failure and retry after 5 minutes after the third consecutive failure, and so on
***
## Full API Reference
For the complete reference (Tailored Audience Permissions, Custom Audiences, Custom Audiences Users, Keyword Insights, Do Not Reach Lists, etc.), see the **[Audiences API Reference](/x-ads-api/audiences/reference)** page.
# Audiences API Reference
Source: https://docs.x.com/x-ads-api/audiences/reference
Endpoint reference for the X Ads Audiences API, including keyword insights, custom audience management, and user list upload request and response details.
## API Reference
### Keyword Insights
#### GET insights/keywords/search[](#get-insights-keywords-search "Permalink to this headline")
Given a group of keywords, get the associated Tweet volume as well as a set of 30 related keywords. The Tweet volume corresponds to the input keywords only, not the related keywords.
A maximum time range (`end_time` - `start_time`) of 7 days is allowed.
Please note that results are scoped by a single geo (country).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/insights/keywords/search`
Specifies the granularity of the data returned for the time range denoted by `start_time` and `end_time`. For instance, when set to `HOUR`, you will be presented with a datapoint for each hour between `start_time` and `end_time`.
Possible values: `DAY`, `HOUR`
A comma-separated string of keywords to narrow search by. All keywords are OR'ed with one another.
**Note**: A maximum of 10 keywords (`keywords` and `negative_keywords` combined) may be used.
Scopes the retrieved data to data collected in the window of time between `start_time` and `end_time`. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
Scopes the retrieved data to data collected in the window of time between `start_time` and `end_time`. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Defaults to the current time.
A targeting value you would get from the [GET targeting\_criteria/locations](/x-ads-api/campaign-management/reference#get-targeting-criteria-locations) endpoint to narrow results in terms of where the user of the account is located. Note that at present only country level locations are supported.
A comma-separated string of keywords to exclude. All negative keywords are OR'ed with one another.
**Note**: A maximum of 10 keywords (`keywords` and `negative_keywords` combined) may be used.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
GET https://ads-api.x.com/12/insights/keywords/search?end_time=2018-02-02&granularity=DAY&keywords=developers&start_time=2018-02-01
```
**Example Response[](#example-response "Permalink to this headline")**\*
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"start_time": "2018-02-01T00:00:00Z",
"end_time": "2018-02-02T00:00:00Z",
"granularity": "DAY",
"keywords": [
"developers"
]
}
},
"data": {
"related_keywords": [
"dev",
"developer",
"coders",
"mysql",
"devs",
"#technology",
"#developers",
"security",
"programmers",
"#tech",
"javascript",
"#iot",
"#bigdata",
"cloud",
"devops",
"php",
"developer",
"programmer",
"engineer",
"big data",
"agile",
"app",
"programming",
"ios",
"maker",
"startups",
"developer's",
"java",
"#devops",
"startup"
],
"tweet_volume": [
15707
]
}
}
```
### Tailored Audience Permissions
#### GET accounts/:account\_id/tailored\_audiences/:tailored\_audience\_id/permissions[](#get-accounts-account-id-tailored-audiences-tailored-audience-id-permissions "Permalink to this headline")
Retrieve details for some or all permissions associated with the specified tailored audience.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/5/accounts/:account_id/tailored_audiences/:tailored_audience_id/permissions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the tailored audience you are operating with in the request.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired accounts by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Scope the response to just the desired tailored audience permissions by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/5/accounts/18ce54d4x5t/tailored_audiences/1nmth/permissions`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"tailored_audience_id": "1nmth"
}
},
"next_cursor": null,
"data": [
{
"tailored_audience_id": "1nmth",
"permission_level": "READ_ONLY",
"id": "ri",
"created_at": "2017-06-08T23:17:59Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-06-08T23:17:59Z",
"deleted": false
}
]
}
```
#### POST accounts/:account\_id/tailored\_audiences/:tailored\_audience\_id/permissions[](#post-accounts-account-id-tailored-audiences-tailored-audience-id-permissions "Permalink to this headline")
Create a new permission object allowing the specified audience to be shared with a given account.
**Note**: Creating or modifying permissions for a tailored audience requires that the audience be owned by the account attempting to modify permissions. You can check the ownership of a tailored audience by looking at the `is_owner` response attribute in the response for a given audience.
**Note**: Audiences can only be shared between ads accounts under the same business or if the ads account that owns the audience has the `SHARE_AUDIENCE_OUTSIDE_BUSINESS` account feature.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/5/accounts/:account_id/tailored_audiences/:tailored_audience_id/permissions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The account you wish to grant the tailored audience permissions for.
The type of access to the tailored audience that the `granted_account_id` should have.
Possible values: `READ_ONLY`, `READ_WRITE`
A reference to the tailored audience you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/5/accounts/18ce54d4x5t/tailored_audiences/2906h/permissions?granted_account_id=18ce54aymz3&permission_level=READ_ONLY`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"granted_account_id": "18ce54aymz3",
"permission_level": "READ_ONLY",
"tailored_audience_id": "2906h"
}
},
"data": {
"tailored_audience_id": "2906h",
"permission_level": "READ_ONLY",
"id": "14m",
"created_at": "2017-09-12T23:49:34Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-09-12T23:49:34Z",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/tailored\_audiences/:tailored\_audience\_id/permissions/:tailored\_audience\_permission\_id[](#delete-accounts-account-id-tailored-audiences-tailored-audience-id-permissions-tailored-audience-permission-id "Permalink to this headline")
Revoke the specified Tailored Audience sharing permission.
**Note**: Creating or modifying permissions for a tailored audience requires that the audience be owned by the account attempting to modify permissions. You can check the ownership of a tailored audience by looking at the `is_owner` response attribute in the response for a given audience.
When revoked, we guarantee that the granted account (`granted_account_id`) will not be able to target the audience in future campaigns. Existing campaigns will continue to run with the shared audiences; campaigns do not stop and the audience does not get removed from the campaign. It is not possible to copy this campaign after the audience sharing permission has been revoked.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/5/accounts/:account_id/tailored_audiences/:tailored_audience_id/permissions/:tailored_audience_permission_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the tailored audience you are operating with in the request.
A reference to the tailored audience permission you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/5/accounts/18ce54d4x5t/tailored_audiences/1nmth/permissions/ri`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"tailored_audience_permission_id": "ri",
"tailored_audience_id": "1nmth"
}
},
"data": {
"tailored_audience_id": "1nmth",
"permission_level": "READ_ONLY",
"id": "ri",
"created_at": "2017-06-08T23:17:59Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-08-30T18:29:35Z",
"deleted": true
}
}
```
### Targeted Audiences
#### GET accounts/:account\_id/custom\_audiences/:custom\_audience\_id/targeted[](#get-accounts-account-id-custom-audiences-custom-audience-id-targeted "Permalink to this headline")
Retrieve a list of active or all line items and campaigns that target a given `custom_audience_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
When `false`, includes line items that have `servable=false` status.
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/2906h/targeted`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"custom_audience_id": "2906h",
}
},
"next_cursor": null,
"data": [
{
"campaign_id": "59hod",
"campaign_name": "test-campaign",
"line_items": [
{
"id": "5gzog",
"name": "test-line-item",
"servable": true
}
]
},
{
"campaign_id": "arja7",
"campaign_name": "Untitled campaign",
"line_items": [
{
"id": "bjw1q",
"name": null,
"servable": true
}
]
}
]
}
```
### Custom Audiences Users
#### POST accounts/:account\_id/custom\_audiences/:custom\_audience\_id/users[](#post-accounts-account-id-custom-audiences-custom-audience-id-users "Permalink to this headline")
This endpoint will allow partners to add, update and remove users from a given `custom_audience_id`. The endpoint will also accept multiple user identifier types per user as well.
All data being provided in the `users` field of the request **except** `partner_user_id` must be hashed using `SHA256` and [normalized](/x-ads-api/audiences/reference#twitter-user-id-normalization).
**Batch Requests**
* The current maximum batch size is `2500` **for this endpoint**. The batch size is determined by the number of operations (`Update`/`Delete`) per request. For example, over 2500 operation objects (`{"operation_type": "Update/Delete", [..] }`) in one array result in an error.
* The max request POST body size this endpoint can accept is `5,000,000` bytes.
* The rate limits for this endpoint are 1500 per 1 minute window
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
The response returned by the Ads API contains two fields, a `success_count` and a `total_count`. These values must always be equal, and they are a count of the number of records in the request that have been processed by the backend. A situation where the number of records sent in the request body is **not** equal the `success_count` and `total_count` should be treated as an error condition, requiring a retry.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required parameters) are show in the response under the `operation_errors` object.
* The index of the error in the `operation_errors` refers to the index in the input item, with the corresponding error message
#### Resource URL[](#resource-url "Permalink to this headline")
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id/users`
#### Parameters[](#parameters "Permalink to this headline")
The per `users` group operation type being performed.
Possible values: `Update`, `Delete`
A JSON object containing the `users` array, the `effective_at` and `expires_at` timestamps.
An array of JSON objects containing all params for an individual user.
The UTC time at which the custom audience association(s) should take effect. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). Defaults to the current date and time.
The UTC time at which the custom audience association(s) should expire. The specified time must be later than the value of `effective_at`. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). Defaults to 13 months from the request timestamp.
Given the multi-key approach to the `users` object, each element of this object is documented below:
Email address(es) for the user.
IDFA/AdID/Android ID.
The @handle(s) belonging to the user.
The X ID belonging to the user.
Phone number(s) for the user.
The user's ID in the partners' system.
#### Example Request[](#example-request "Permalink to this headline")
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/1nmth/users`
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
[
{
"operation_type": "Update",
"params": {
"effective_at": "2018-05-15T00:00:00Z",
"expires_at": "2019-01-01T07:00:00Z",
"users": [
{
"email": [
"4798b8bbdcf6f2a52e527f46a3d7a7c9aefb541afda03af79c74809ecc6376f3"
],
"handle": [
"7352f353c460e74c7ae226952d04f8aa307b12329c5512ec8cb6f1a0f8f9b2cb",
"49e0be2aeccfb51a8dee4c945c8a70a9ac500cf6f5cb08112575f74db9b1470d"
]
},
{
"email": [
"5bf13d5ad4200407c5bc8b9bb578e425d05ef936fd488e3799a9d0806669223c"
],
"twitter_id": [
"34d56c7159a7eea941f359653029410f813f65a1d2d13ecc5ccbdd5a8cb755cf",
"00e7b76c9739dec57f4c4a20ec021a20ffcf26bd00f519b17ea00f0ed6048f85"
]
}
]
}
},
{
"operation_type": "Delete",
"params": {
"effective_at": "2018-05-15T00:00:00Z",
"expires_at": "2019-01-01T07:00:00Z",
"users": [
{
"device_id": [
"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"
],
"email": [
"4798b8bbdcf6f2a52e527f46a3d7a7c9aefb541afda03af79c74809ecc6376f3"
],
"handle": [
"461222f5dd690a20651c3d19848015cb0369db3f8e937571ffb775de70750847"
],
"twitter_id": [
"c623c7e163984493b46c547088542e95d0aaa529bc52bbecce3ff91eb6b7843b"
]
},
{
"email": [
"5bf13d5ad4200407c5bc8b9bb578e425d05ef936fd488e3799a9d0806669223c"
],
"twitter_id": [
"858cdc7f313f84a3f3c48e9a6323307c1ef1bb7439b8e3623e140454b0fd8fa5",
"bb074e154657b91d99bd1bb3757409149670e8ae7a0fe9136fae29a26a7881c8"
]
}
]
}
}
]
```
#### Example Response[](#example-response "Permalink to this headline")
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"custom_audience_id": "1nmth"
}
},
"data": {
"success_count": 4,
"total_count": 4
}
}
```
### Custom Audience Permissions
#### GET accounts/:account\_id/custom\_audiences/:custom\_audience\_id/permissions[](#get-accounts-account-id-custom-audiences-custom-audience-id-permissions "Permalink to this headline")
Retrieve details for some or all permissions associated with the specified custom audience.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id/permissions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired accounts by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Scope the response to just the desired custom audience permissions by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/1nmth/permissions`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"custom_audience_id": "1nmth"
}
},
"next_cursor": null,
"data": [
{
"custom_audience_id": "1nmth",
"permission_level": "READ_ONLY",
"id": "ri",
"created_at": "2017-06-08T23:17:59Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-06-08T23:17:59Z",
"deleted": false
}
]
}
```
#### POST accounts/:account\_id/custom\_audiences/:custom\_audience\_id/permissions[](#post-accounts-account-id-custom-audiences-custom-audience-id-permissions "Permalink to this headline")
Create a new permission object allowing the specified audience to be shared with a given account.
**Note**: Creating or modifying permissions for a custom audience requires that the audience be owned by the account attempting to modify permissions. You can check the ownership of a custom audience by looking at the `is_owner` response attribute in the response for a given audience.
**Note**: Audiences can only be shared between ads accounts under the same business or if the ads account that owns the audience has the `SHARE_AUDIENCE_OUTSIDE_BUSINESS` account feature.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id/permissions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The account you wish to grant the custom audience permissions for.
The type of access to the custom audience that the `granted_account_id` should have.
Possible values: `READ_ONLY`, `READ_WRITE`
A reference to the custom audience you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
```
POST https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/2906h/permissions?granted_account_id=18ce54aymz3&permission_level=READ_ONLY
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"granted_account_id": "18ce54aymz3",
"permission_level": "READ_ONLY",
"custom_audience_id": "2906h"
}
},
"data": {
"custom_audience_id": "2906h",
"permission_level": "READ_ONLY",
"id": "14m",
"created_at": "2017-09-12T23:49:34Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-09-12T23:49:34Z",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/custom\_audiences/:custom\_audience\_id/permissions/:custom\_audience\_permission\_id[](#delete-accounts-account-id-custom-audiences-custom-audience-id-permissions-custom-audience-permission-id "Permalink to this headline")
Revoke the specified Custom Audience sharing permission.
**Note**: Creating or modifying permissions for a custom audience requires that the audience be owned by the account attempting to modify permissions. You can check the ownership of a custom audience by looking at the `is_owner` response attribute in the response for a given audience.
When revoked, we guarantee that the granted account (`granted_account_id`) will not be able to target the audience in future campaigns. Existing campaigns will continue to run with the shared audiences; campaigns do not stop and the audience does not get removed from the campaign. It is not possible to copy this campaign after the audience sharing permission has been revoked.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id/permissions/:custom_audience_permission_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
A reference to the custom audience permission you are operating with in the request.
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
A reference to the custom audience permission you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/1nmth/permissions/ri`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"custom_audience_permission_id": "ri",
"custom_audience_id": "1nmth"
}
},
"data": {
"custom_audience_id": "1nmth",
"permission_level": "READ_ONLY",
"id": "ri",
"created_at": "2017-06-08T23:17:59Z",
"granted_account_id": "18ce54aymz3",
"updated_at": "2017-08-30T18:29:35Z",
"deleted": true
}
}
```
### Custom Audiences
#### GET accounts/:account\_id/custom\_audiences[](#get-accounts-account-id-custom-audiences "Permalink to this headline")
Retrieve details for some or all Custom Audiences associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Allows filtering the response to lists you own or lists that have been shared with you. By default, without specifying this parameter you will only see audiences you own.
Possible values: `OWNER`, `SHARED`
An optional query to scope resource by `name`.
**Note**: This performs case-insensitive prefix matching.
Min, Max length: `1`, `255`
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Scope the response to just the desired custom audiences by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences?custom_audience_ids=1nmth`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"custom_audience_ids": [
"1nmth"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"targetable": true,
"name": "twurl-using-subshell-for-file",
"targetable_types": [
"CRM",
"EXCLUDED_CRM"
],
"audience_type": "CRM",
"description": null,
"permission_level": "READ_WRITE",
"owner_account_id": "18ce54d4x5t",
"id": "1nmth",
"reasons_not_targetable": [],
"created_at": "2017-01-08T08:19:58Z",
"updated_at": "2017-01-08T16:21:13Z",
"partner_source": "OTHER",
"deleted": false,
"audience_size": 1470
}
]
}
```
#### GET accounts/:account\_id/custom\_audiences/:custom\_audience\_id[](#get-accounts-account-id-custom-audiences-custom-audience-id "Permalink to this headline")
Retrieve specific Custom Audiences associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/2906h`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"custom_audience_id": "2906h",
"account_id": "18ce54d4x5t"
}
},
"data": {
"targetable": false,
"name": "developers",
"targetable_types": [
"CRM",
"EXCLUDED_CRM"
],
"audience_type": "CRM",
"description": null,
"permission_level": "READ_WRITE",
"owner_account_id": "18ce54d4x5t",
"id": "2906h",
"reasons_not_targetable": [],
"created_at": "2017-08-22T23:34:26Z",
"updated_at": "2017-08-22T23:34:26Z",
"partner_source": "OTHER",
"deleted": false,
"audience_size": 140321
}
}
```
#### POST accounts/:account\_id/custom\_audiences[](#post-accounts-account-id-custom-audiences "Permalink to this headline")
Create a new placeholder Custom Audience associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The display name for this audience. Unique name value must be used. Failure to do so will result in an error.
A description for this audience.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences?name=developers`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"targetable": false,
"name": "developers",
"targetable_types": [
"CRM",
"EXCLUDED_CRM"
],
"audience_type": "CRM",
"description": null,
"permission_level": "READ_WRITE",
"owner_account_id": "18ce54d4x5t",
"id": "2906h",
"reasons_not_targetable": [
"PROCESSING",
"TOO_SMALL"
],
"created_at": "2017-08-22T23:34:26Z",
"updated_at": "2017-08-22T23:34:26Z",
"partner_source": "OTHER",
"deleted": false,
"audience_size": null
},
"request": {
"params": {
"account_id": "18ce54d4x5t",
"name": "developers"
}
}
}
```
#### PUT accounts/:account\_id/custom\_audiences/:custom\_audience\_id[](#put-accounts-account-id-custom-audiences-custom-audience-id "Permalink to this headline")
Update the specific Custom Audience associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Custom Audience you are operating with in the request.
The display name for this audience. Unique name value must be used. Failure to do so will result in an error.
A description for this audience.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/2906h?name=developers_changed`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"targetable": false,
"name": "developers_changed",
"targetable_types": [
"CRM",
"EXCLUDED_CRM"
],
"audience_type": "CRM",
"description": null,
"permission_level": "READ_WRITE",
"is_owner": true,
"id": "2906h",
"reasons_not_targetable": [
"PROCESSING",
"TOO_SMALL"
],
"created_at": "2017-08-22T23:34:26Z",
"updated_at": "2017-08-22T23:34:26Z",
"partner_source": "OTHER",
"deleted": false,
"audience_size": null
},
"request": {
"params": {
"account_id": "18ce54d4x5t",
"name": "developers_changed"
}
}
}
```
#### POST batch/accounts/:account\_id/custom\_audiences[](#post-batch-accounts-account-id-custom-audiences "Permalink to this headline")
Allows for batch creation of Custom Audiences. See the [Custom Audiences Overview](/x-ads-api/audiences) page for information on audiences.
**Note:** This batch endpoint is currently in **closed beta** and available to select advertisers. During this beta period, only Flexible Audiences based on mobile custom audiences can be created.
**Batch Requests**
* The current maximum batch size is 10.
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
Batch API responses return an ordered collection of items. Otherwise, they are identical in structure to their corresponding single-item endpoints.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required parameter) are shown in the response under the `operation_errors` object.
**Flexible Audiences**
* Flexible Audiences are immutable once created.
* Custom Audiences are passed in a tree structure with boolean logic combinations to create Flexible Audiences
* A maximum of 10 Custom Audiences leaf nodes can be used to create a Flexible Audience.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/batch/accounts/:account_id/custom_audiences`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The type of audience to create.
Possible values: `FLEXIBLE`, `MOBILE_AUDIENCE`
An array containing objects which define the subset of a Custom Audience's members that you would like to target. Each object should contain a `custom_audience_id`, `frequency`, `frequency_comparator`, `lookback_window`, `negate`, and, in some cases, additional `child_segments`.
The display name for the audience. Unique name value must be used. Failure to do so will result in an error.
The per item operation type being performed.
Possible values: `Create`, `Update`, `Delete`
The logical relationship between the child segments in its parent (containing) object. Required if child\_segments is non-empty for the parent object.
Possible values: `AND`, `OR`
An integer value specifying the range of days within which the user has taken the specific action and qualified for the given custom audience.
Possible values: `1`, `7`, `14`, `30`
An object containing a `boolean_operator` and `child_segments` which define the subset of a Custom Audience's members that you would like to target.
The id of the custom audience to use as a child segment.
An integer value specifying the frequency within the lookback window that the user has taken the specific action and qualified for the given custom audience.
The comparator to the `frequency` passed in the request.
**Note**: In the values below, `GTE` refers to greater than or equal, `LT` to less than, and so on.
Possible values: `NUM_GTE`, `NUM_GT`, `NUM_EQ`, `NUM_LTE`, `NUM_LT`
Negates the segment and thus is excluded in the combination.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/batch/accounts/18ce54d4x5t/custom_audiences`
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
[
{
"operation_type":"Create",
"params":{
"name":"my_flexible_audience_name",
"audience_type":"FLEXIBLE",
"segments":{
"boolean_operator":"AND",
"child_segments":[
{
"custom_audience_id":"TYIF",
"frequency":1,
"frequency_comparator":"NUM_GT",
"lookback_window":30,
"negate":true,
"child_segments":[
]
},
{
"boolean_operator":"OR",
"child_segments":[
{
"custom_audience_id":"TXR1",
"lookback_window":30,
"child_segments":[
]
},
{
"custom_audience_id":"TYFO",
"frequency":1,
"frequency_comparator":"NUM_GT",
"lookback_window":30,
"negate":true,
"child_segments":[
]
}
]
}
]
}
}
}
]
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"targetable": false,
"name": "my_flexible_audience_name",
"targetable_types": [
"FLEXIBLE",
"EXCLUDED_FLEXIBLE"
],
"audience_type": "FLEXIBLE",
"id": "13ld7",
"reasons_not_targetable": [
"PROCESSING",
"TOO_SMALL"
],
"metadata": [
{
"custom_audience_id": "13ld7",
"account_id": "qsx3w2",
"name": "my_flexible_audience_name",
"audience_source": "FLEXIBLE_AUDIENCE",
"upload_status": "UPLOADED",
"segments": {
"boolean_operator": "AND",
"frequency": 1,
"frequency_comparator": "NUM_GTE",
"negate": false,
"child_segments": [
{
"custom_audience_id": "tyif",
"lookback_window": 30,
"frequency": 1,
"frequency_comparator": "NUM_GT",
"negate": true,
"child_segments": [
]
},
{
"boolean_operator": "OR",
"frequency": 1,
"frequency_comparator": "NUM_GTE",
"negate": false,
"child_segments": [
{
"custom_audience_id": "txr1",
"lookback_window": 30,
"frequency": 1,
"frequency_comparator": "NUM_GTE",
"negate": false,
"child_segments": [
]
},
{
"custom_audience_id": "tyfo",
"lookback_window": 30,
"frequency": 1,
"frequency_comparator": "NUM_GT",
"negate": true,
"child_segments": [
]
}
]
}
]
}
}
],
"created_at": "2015-11-10T21:26:43Z",
"updated_at": "2015-11-11T01:11:47Z",
"partner_source": "OTHER",
"deleted": false,
"audience_size": null
},
"request": [
{
"params": {
"name": "my_flexible_audience_name",
"audience_type": "FLEXIBLE",
"segments": {
"boolean_operator": "AND",
"child_segments": [
{
"custom_audience_id": "TYIF",
"lookback_window": 30,
"frequency": 1,
"frequency_comparator": "NUM_GT",
"negate": true,
"child_segments": [
]
},
{
"boolean_operator": "OR",
"child_segments": [
{
"custom_audience_id": "TXR1",
"lookback_window": 30,
"child_segments": [
]
},
{
"custom_audience_id": "TYFO",
"lookback_window": 30,
"frequency": 1,
"frequency_comparator": "NUM_GT",
"negate": true,
"child_segments": [
]
}
]
}
]
},
"account_id": "qsx3w2"
},
"operation_type": "Create"
}
]
}
```
#### DELETE accounts/:account\_id/custom\_audiences/:custom\_audience\_id[](#delete-accounts-account-id-custom-audiences-custom-audience-id "Permalink to this headline")
Delete the specified Custom Audience belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/custom_audiences/:custom_audience_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the custom audience you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/custom_audiences/2906h`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"targetable": false,
"name": "developers",
"targetable_types": [
"CRM",
"EXCLUDED_CRM"
],
"audience_type": "CRM",
"description": null,
"permission_level": "READ_WRITE",
"owner_account_id": "18ce54d4x5t",
"id": "2906h",
"reasons_not_targetable": [
"TOO_SMALL"
],
"created_at": "2017-08-22T23:34:26Z",
"updated_at": "2017-08-30T18:09:00Z",
"partner_source": "OTHER",
"deleted": true,
"audience_size": null
},
"request": {
"params": {
"custom_audience_id": "2906h",
"account_id": "18ce54d4x5t"
}
}
}
```
### Do Not Reach Lists
#### GET accounts/:account\_id/do\_not\_reach\_lists[](#get-accounts-account-id-do-not-reach-lists "Permalink to this headline")
Retrieve details for some or all Do Not Reach List associated with the current account.
**Note**: An `account_id` can only have at most one Do Not Reach List
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/do_not_reach_lists`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54bgxky/do_not_reach_lists`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54bgxky"
}
},
"next_cursor": null,
"data": [
{
"targetable": false,
"name": "Do Not Reach List",
"description": "test DNRL",
"id": "4kzrq",
"reasons_not_targetable": [
"TOO_SMALL"
],
"created_at": "2021-10-28T22:09:29Z",
"list_size": null,
"updated_at": "2021-11-04T03:33:06Z",
"deleted": false
}
]
}
```
#### POST accounts/:account\_id/do\_not\_reach\_lists[](#post-accounts-account-id-do-not-reach-lists "Permalink to this headline")
Create a new Do Not Reach List associated with the current account.
**Note**: An `account_id` can only have at most one Do Not Reach List
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/do_not_reach_lists`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A description for this audience.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54bgxky/do_not_reach_lists?description=A list of users to exclude`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"description": "A list of users to exclude",
"account_id": "18ce54bgxky"
}
},
"data": {
"targetable": false,
"name": "Do Not Reach List",
"description": "A list of users to exclude",
"id": "4ofrq",
"reasons_not_targetable": [
"PROCESSING",
"TOO_SMALL"
],
"created_at": "2022-02-08T23:02:48Z",
"list_size": null,
"updated_at": "2022-02-08T23:02:48Z",
"deleted": false
}
}
```
#### POST batch/accounts/:account\_id/do\_not\_reach\_lists/:do\_not\_reach\_list\_id/users[](#post-batch-accounts-account-id-do-not-reach-lists-do-not-reach-list-id-users "Permalink to this headline")
This endpoint allows users to be added, updated and removed from a given `do_not_reach_list_id`. This endpoint only accepts emails as the valid user identifier type.
All data being provided in the `emails` field of the request must be hashed using `SHA256` and [normalized](/x-ads-api/audiences/reference#e-mail-normalization).
**Notes**
* An `account_id` can only have at most one Do Not Reach List
* Users added to this list **must** have an `expires_at` timestamp set to less than 13 months from the current timestamp
* Do Not Reach List API does not accept an `effective_at` timestamp and defaults to the current timestamp
* Do Not Reach List does not remove users from any or all custom audiences in the account but acts as exclusion targeting for all campaigns served for the account
**Batch Requests**
* The current maximum batch size is `2500` **for this endpoint**. The batch size is determined by the number of operations (`Update`/`Delete`) per request. For example, over 2500 operation objects (`{"operation_type": "Update/Delete", [..] }`) in one array result in an error.
* The max request POST body size this endpoint can accept is `5,000,000` bytes.
* The rate limits for this endpoint are 1500 per 1 minute window
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
The response returned by the Ads API contains two fields, a `success_count` and a `total_count`. These values must always be equal, and they are a count of the number of records in the request that have been processed by the backend. A situation where the number of records sent in the request body is **not** equal the `success_count` and `total_count` should be treated as an error condition, requiring a retry.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required parameters) are show in the response under the `operation_errors` object.
* The index of the error in the `operation_errors` refers to the index in the input item, with the corresponding error message
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/batch/accounts/:account_id/do_not_reach_lists/:do_not_reach_list_id/users`
The per item operation type being performed.
Possible values: `Update`, `Delete`
A JSON object containing the `emails` array and the `expires_at` timestamp.
An array of hashed email addresses.
The UTC time at which the Do Not Reach List association(s) should expire. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Do Not Reach List you are operating with in the request.
The per `users` group operation type being performed.
Possible values: `Update`, `Delete`
A JSON object containing the `emails` array and `expires_at` timestamp.
An array of JSON objects containing all params for an individual user.
The UTC time at which the user association(s) should expire. The specified time must be later than the value of the current timestamp. Expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). Defaults to 13 months from current timestamp.
Given the multi-key approach to the `users` object, each element of this object is documented below:
Email address(es) for the user.
Phone number(s) for the user.
**Example Request[](#example-request "Permalink to this headline")**
```
`POST https://ads-api.x.com/12/batch/accounts/18ce54bgxky/do_not_reach_lists/4kzro/users`
[
{
"operation_type": "Update",
"params": {
"expires_at": "2023-01-22T00:00:00Z",
"users": [
{
"email": [
"FEAD76F6ADF99FFFB997AA4E3C8AD38FF531BC4C956DBD03CD0163F744D8AABC"
],
"phone_number": [
"CCABF1B62A202E0FE28BC6C014983C89A65451DD4482BD66A0ADB65366F38A9A"
]
},
{
"email": [
"FEAD76F6ADF99FFFB997AA4E3C8AD38FF531BC4C956DBD03CD0163F744D8AABA"
],
"phone_number": [
"CCABF1B62A202E0FE28BC6C014983C89A65451DD4482BD66A0ADB65366F38A9E"
]
}
]
}
}
]
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"success_count": 2,
"total_count": 2
}
],
"request": [
{
"params": {
"do_not_reach_list_id": "4ofrq",
"expires_at": "2023-01-22T00:00:00Z",
"account_id": "18ce54bgxky"
},
"operation_type": "Update"
}
]
}
```
#### DELETE accounts/:account\_id/do\_not\_reach\_lists/:do\_not\_reach\_list\_id[](#delete-accounts-account-id-do-not-reach-lists-do-not-reach-list-id "Permalink to this headline")
Delete the specified Do Not Reach List belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/do_not_reach_lists/:do_not_reach_list_id`
**Parameters[](#parameters "Permalink to this headline")**
None
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54bgxky/do_not_reach_lists/4ofrp`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"do_not_reach_list_id": "4ofrp",
"account_id": "18ce54bgxky"
}
},
"data": {
"targetable": false,
"name": "Do Not Reach List",
"description": null,
"id": "4ofrp",
"reasons_not_targetable": [
"PROCESSING",
"TOO_SMALL"
],
"created_at": "2022-02-08T23:02:07Z",
"list_size": null,
"updated_at": "2022-02-08T23:02:21Z",
"deleted": true
}
}
```
# Campaign Management
Source: https://docs.x.com/x-ads-api/campaign-management
Create, manage, and optimize advertising campaigns on X. Define budgets, targeting, creatives, and bidding strategies using the Ads API.
**Programmatically create, schedule, and manage ad campaigns on X.**
Campaigns define your budget and schedule. Line items (also called ad groups) control targeting, bidding, and the creatives that run within a campaign.
Looking for detailed endpoint documentation?
The full API reference (all endpoints, request/response examples, and parameter tables for Accounts, Campaigns, Line Items, Funding Instruments, Targeting, etc.) has moved to the dedicated
Campaign Management API Reference page.
Old deep links (e.g. #get-accounts-account-id-campaigns) will automatically redirect there.
## Quick links
* [What Can You Promote?](#what-can-you-promote)
* [Creating a Campaign – Step by Step](#creating-a-campaign---step-by-step)
* [Guides](#guides)
* [Full API Reference](/x-ads-api/campaign-management/reference) — All endpoints, parameters, and examples for Accounts, Campaigns, Line Items, Funding Instruments, Targeting, and more.
## Advertiser API
Programmatically schedule campaigns and manage ads on X through this suite of APIs.
## What you can promote
### [Promoted Ads](https://business.x.com/help/what-are-promoted-tweets)
* Promoted Ads are ordinary ads purchased by advertisers who want to reach a wider group of users or to spark engagement from their existing followers.
* Promoted Ads are clearly labeled as Promoted when an advertiser is paying for their placement on X. In every other respect, Promoted Ads act just like regular ads and can be reposted, replied to, liked and more. They have typical delivery rules and are created using [POST statuses/update](/x-api/posts/creation-of-a-post).
* **“Promoted-only” Tweets,** created via [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet), can be used in Promoted Tweets campaigns but will not serve to followers or appear on the public timeline. To retrieve a list of promoted-only tweets for a certain account, use [GET accounts/:account\_id/scoped\_timeline](/x-ads-api/creatives).
### [Promoted Accounts](https://business.x.com/help/what-are-promoted-accounts)
* Promoted Accounts are part of Who to Follow, which suggests accounts that people don’t currently follow and may find interesting. Promoted Accounts help introduce an even wider variety of accounts people may enjoy.
* Promoted Accounts for Timeline, associate a Promoted Tweet with a Promoted Account campaign and will display in user timelines.
Promoted Trends are not available in the Ads API.
## Campaigns and Ad Groups (Line Items)
Campaigns define the schedule and budget of an ad. The advertiser specifies a daily and overall budget. The campaign can be bound to a specific start and end time or run continuously until the budget is spent. The budget comes from one of the Funding Instruments of the advertising account. Campaign identifiers (:campaign\_id) are the base-36 representation of the base-10 value we present in the X Ads UI.
Advertising accounts are limited to a maximum of 200 active campaigns. This limit can be raised to 4,000 active campaigns manually by the advertiser’s X Account Manager upon request. A campaign is considered active until it reaches its end time or gets deleted. Paused campaigns are considered active until their designated end times.
Line items spend the budget defined by a campaign. Line items pull together the per-engagement bid, the Tweet or account to promote, and the targeting rules.
## Analytics
The X Ads API offers a set of analytics endpoints to track and optimize ad performance. Please see Analytics and Analytics Best Practices for more information.
For the billing metric, the data may not be finalized until three days after the event. Before that point, the data should be considered speculative. The final billable number will always be less than the speculative amount. The billable number is corrected for spam and related low-quality traffic. See Timezones for other considerations regarding time.
## Creating a Campaign - Step-by-Step
The following example assumes you have installed, configured, and authorized your app and user using [twurl](https://github.com/twitter/twurl). twurl is a command-line tool in the spirit of cURL that gracefully handles X OAuth authentication. twurl is a great tool for quickly testing and debugging Ads API (and REST API) functionality. To see the full headers of the request and response, use `-t` to trace the call, roughly equivalent to cURL’s `-v` option.
**For this example, we will create a Promoted Ads campaign that will be targeted by keyword.**
1. **Retrieve the account id.**
```
twurl -H ads-api.x.com /9/accounts/
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
}
},
"data": [
{
"name": "Test account for @AdsAPI",
"timezone": "America/Los_Angeles",
"timezone_switch_at": null,
"id": "xxxxxx",
"created_at": "2014-03-09T00:41:49Z",
"salt": "f9f9d5a5f23075c618da5eb1d1a9df57",
"updated_at": "2015-01-29T00:41:49Z",
"approval_status": "ACCEPTED",
"deleted": false
}
],
"data_type": "account",
"total_count": 1,
"next_cursor": null
}
```
2. **Retrieve the funding instrument id.**
Hit the [GET accounts/:account\_id/funding\_instruments](/x-ads-api/campaign-management/reference#get-accounts-account-id-funding-instruments) API using the account id retrieved in the previous command.
```
twurl -H ads-api.x.com /9/accounts/xxxxxx/funding_instruments
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"cancelled": true,
"created_at": "2014-03-09T00:41:49Z",
"credit_limit_local_micro": null,
"currency": "USD",
"deleted": false,
"description": null,
"end_time": null,
"funded_amount_local_micro": null,
"id": "yyyy",
"type": null,
"updated_at": "2014-05-29T00:41:49Z"
}
],
"data_type": "funding_instrument",
"next_cursor": null,
"request": {
"params": {
"account_id": "xxxxxx"
}
},
"total_count": 1
}
```
3. **Create a campaign and associate it with the funding instrument.**
Specify a start time and a budget for the campaign. For the purpose of this example, we will use a budget of \$500 and for the daily limit, \$50.
```
twurl -H ads-api.x.com -d "funding_instrument_id=yyyy&name=My First Campaign&total_budget_amount_local_micro=500000000&daily_budget_amount_local_micro=50000000" /9/accounts/xxxxxx/campaigns
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"created_at": "2015-02-09T00:00:00Z",
"currency": "USD",
"daily_budget_amount_local_micro": 50000000,
"deleted": false,
"end_time": null,
"funding_instrument_id": "yyyy",
"id": "92ph",
"name": "My First Campaign",
"entity_status": "PAUSED",
"standard_delivery": true,
"total_budget_amount_local_micro": 500000000,
"updated_at": "2015-02-09T00:00:00Z"
},
"data_type": "campaign",
"request": {
"params": {
"account_id": "xxxxxx",
"daily_budget_amount_local_micro": 50000000,
"funding_instrument_id": "yyyy",
"name": "My First Campaign",
"total_budget_amount_local_micro": 500000000
}
}
}
```
4. **Create a line item associated with the campaign.**
Now that we have a campaign id, we can create a line item to associate with it. The line item wraps the bid price, targeting, and actual creative portion of the campaign. For this line item, we will be promoting tweets with a bid of \$1.50.
```
twurl -H ads-api.x.com -d "campaign_id=XXXX&bid_amount_local_micro=1500000&product_type=PROMOTED_TWEETS&placements=ALL_ON_TWITTER&objective=ENGAGEMENTS&entity_status=PAUSED" /9/accounts/xxxxxxx/line_items
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "line_item",
"data": {
"bid_type": "MAX",
"name": "Untitled",
"placements": [
"ALL_ON_TWITTER"
],
"bid_amount_local_micro": 1500000,
"automatically_select_bid": false,
"advertiser_domain": null,
"primary_web_event_tag": null,
"charge_by": "ENGAGEMENT",
"product_type": "PROMOTED_TWEETS",
"bid_unit": "ENGAGEMENT",
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "azjx",
"entity_status": "PAUSED",
"optimization": "DEFAULT",
"categories": [],
"currency": "USD",
"created_at": "2015-02-09T00:00:00Z",
"updated_at": "2015-02-09T00:00:00Z",
"include_sentiment": "POSITIVE_ONLY",
"campaign_id": "92ph",
"deleted": false
},
"request": {
"params": {
"placements": [
"ALL_ON_TWITTER"
],
"bid_amount_local_micro": 1500000,
"product_type": "PROMOTED_TWEETS",
"entity_status": "PAUSED",
"account_id": "xxxxxxx",
"campaign_id": "92ph"
}
}
}
```
5. **Create a targeting profile associated with the line item.**
With the line item created, we can assign targeting criteria. We want to target the phrase keywords “grumpy cat” in the San Francisco Bay Area location. This is going to require a location id lookup and two targeting\_criteria POST requests.
```
twurl -H ads-api.x.com "/9/targeting_criteria/locations?location_type=CITIES&q=San Francisco"
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "San Francisco-Oakland-San Jose CA, US",
"targeting_type": "LOCATION",
"targeting_value": "5122804691e5fecc"
}
],
"data_type": "targeting_criterion",
"request": {
"params": {
"location_type": "CITY",
"q": "San Francisco"
}
}
}
```
```
twurl -H ads-api.x.com -X POST -d "line_item_id=yyyy&targeting_type=LOCATION&targeting_value=5122804691e5fecc" /9/accounts/xxxxxx/targeting_criteria
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"created_at": "2015-02-09T00:00:15Z",
"deleted": false,
"id": "2u3be",
"line_item_id": "yyyy",
"name": "San Francisco-Oakland-San Jose CA, US",
"targeting_type": "LOCATION",
"targeting_value": "5122804691e5fecc",
"updated_at": "2013-05-30T21:01:35Z"
},
"data_type": "targeting_criterion",
"request": {
"params": {
"account_id": "xxxxxx",
"line_item_id": "yyyy",
"targeting_type": "LOCATION",
"targeting_value": "5122804691e5fecc"
}
}
}
```
```
twurl -H ads-api.x.com -X POST -d "line_item_id=yyyy&targeting_type=PHRASE_KEYWORD&targeting_value=grumpy cat" /9/accounts/xxxxxx/targeting_criteria
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"created_at": "2015-02-09T00:00:20Z",
"deleted": false,
"id": "2u3bd",
"line_item_id": "yyyy",
"name": "grumpy cat",
"targeting_type": "PHRASE_KEYWORD",
"targeting_value": "grumpy cat",
"updated_at": "2013-05-30T18:05:35Z"
},
"data_type": "targeting_criterion",
"request": {
"params": {
"account_id": "xxxxxx",
"line_item_id": "yyyy",
"targeting_type": "PHRASE_KEYWORD",
"targeting_value": "grumpy cat"
}
}
}
```
6. **Finally, un-pause the line item.**
```
twurl -H ads-api.x.com -X PUT "/9/accounts/xxxxxx/line_items/yyyy/?entity_status=ACTIVE"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "line_item",
"data": {
"bid_type": "MAX",
"name": "grumpy cat",
"placements": [],
"bid_amount_local_micro": 1500000,
"automatically_select_bid": false,
"advertiser_domain": null,
"primary_web_event_tag": null,
"charge_by": "ENGAGEMENT",
"product_type": "PROMOTED_TWEETS",
"bid_unit": "ENGAGEMENT",
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "yyyy",
"entity_status": "ACTIVE",
"optimization": "DEFAULT",
"categories": [],
"currency": "USD",
"created_at": "2015-02-09T00:00:20Z",
"updated_at": "2015-02-09T00:00:20Z",
"include_sentiment": "POSITIVE_ONLY",
"campaign_id": "dy1f",
"deleted": false
},
"request": {
"params": {
"line_item_id": "yyyy",
"entity_status": "ACTIVE",
"account_id": "xxxxxx"
}
}
}
```
That’s it! We now have an active, targeted, and funded Promoted Tweets in Timelines campaign which is running.
### Objective Based Campaigns
Objective-based campaigns and pricing allow advertisers to pay for the actions that are aligned with their marketing objectives. To support these, set the appropriate `objective` on line items.
The parameter used on the line item write endpoints and returned on the read endpoints, is `objective`. This field has the following possible values as of today:
* `APP_ENGAGEMENTS`
* `APP_INSTALLS`
* `FOLLOWERS`
* `ENGAGEMENTS`
* `REACH`
* `VIDEO_VIEWS`
* `PREROLL_VIEWS`
* `WEBSITE_CLICKS`
Objectives impact how we optimize campaigns in our auctions and how we bill on those campaigns. We enable pricing based on objective, such as CPAC for `APP_ENGAGEMENTS`, CPAC *or* CPI for `APP_INSTALLS`, CPLC for `WEBSITE_CLICKS`, CPF for `FOLLOWERS`, CPE for `ENGAGEMENTS`, and CPM for `REACH`.
Mobile app promotion campaigns are required to contain either the `APP_ENGAGEMENTS` or `APP_INSTALLS` objective.
**Note:** Line items with different objectives are not allowed under the same campaign.
| Campaign objective | API objective | Media in Tweets | Pricing model |
| :----------------- | :---------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------- |
| App re-engagements | `APP_ENGAGEMENTS` | Image or video app download card required. | CPAC |
| App installs | `APP_INSTALLS` | Image or video app download card required. | CPAC or CPI (set using `charge_by`) |
| Reach | `REACH` | No restrictions. | CPM |
| Followers | `FOLLOWERS` | Tweet not required, but recommended. There are no media restrictions on Tweets for Followers campaigns, though we recommend text-only Tweets. [More information](https://business.x.com/en/help/campaign-setup/create-a-followers-campaign.html#serve) | CPF |
| Engagements | `ENGAGEMENTS` | No restrictions. | CPE |
| Video Views | `VIDEO_VIEWS` | Video conversation card, video, or GIF required. | CPV or cost per 3s/100% view |
| Pre-roll views | `PREROLL_VIEWS` | Video required. | CPV or cost per 3s/100% view |
| Website Clicks | `WEBSITE_CLICKS` | Website card recommended, but not required. Tweet must have either a website card or a website link (not both). | CPLC |
### Funding Instruments
Funding Instruments are the source of campaign budget. Funding Instruments can not be created via the Ads API, they have to be already established by the advertiser’s account manager at X (for credit lines) or via ads.x.com (for credit cards) to be available.
To get a list of all `funding_instruments` on an account, see [GET accounts/:account\_id/funding\_instruments](/x-ads-api/campaign-management/reference#get-accounts-account-id-funding-instruments) and [GET accounts/:account\_id/funding\_instruments/:funding\_instrument\_id](/x-ads-api/campaign-management/reference#get-accounts-account-id-funding-instruments-funding-instrument-id) for the details of a specific one.
#### Funding Instrument Attributes
Descriptive: `account_id`, funding instrument `id`, funding instrument `type`, `description`, and `io_header`(insertion order header ID). Note that a single `io_header` may be associated with multiple funding instruments.
Funding ability: `able_to_fund` and `reasons_not_able_to_fund`.
Time: `created_at`, `updated_at`, `start_time`, and `end_time` represented by a string, formatted as “%Y-%m-%dT%l:%M:%S%z”.
Boolean status: `paused`, `deleted`, and `cancelled` (true or false).
Financial: `currency` ([ISO-4217](http://en.wikipedia.org/wiki/ISO_4217) format), `credit_limit_local_micro`, `credit_remaining_local_micro`, and `funded_amount_local_micro`. The value of a currency is represented in micros. For USD, \$5.50 is encoded as 5.50\*1e6, or 5,500,000. To represent a “whole value”, you need to multiply the local micro by 1e6 (1\_000\_000) for all currencies.
#### Attribute Details
`credit_limit_local_micro` is only valid for `CREDIT_CARD` or `CREDIT_LINE` type funding instruments and represents the credit limit for that instrument.
`funded_amount_local_micro` is only valid for `INSERTION_ORDER` type funding instruments and represents the allocated budget.
`credit_remaining_local_micro` is valid for `CREDIT_LINE` and `AGENCY_CREDIT_LINE` type funding instruments. It represents the `credit_limit_local_micro` minus the amount already spent on that funding instrument. It does not represent the difference between `funded_amount_local_micro` and the amount spent. We draw a distinction between credit limit and funded amount because they represent different underlying funding methods and spending agreements we have with advertisers.
#### Types of Funding Instruments
**Credit Cards**
Typically used by self-serve advertisers (without an account manager).
**Credit Lines**
These are in the form of insertion orders (IOs) and are set by account managers.
**Multi-Handle Credit Lines**
Advertisers can fund campaigns across multiple handles with this type of credit line. This feature is enabled by their X Account Manager, associating the different @handles to a specific credit line.
For example, @NikeSB and @NikeFuel can both have access to the @Nike credit line. This funding instrument is available just like any other. You retrieve the data by submitting a GET request to the funding\_instrument endpoint. Here is a sample response (note the `CREDIT_LINE` type).
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
GET https://ads-api.x.com/5/accounts/a0b1c3/funding_instruments
{
"request": {
"params": {
"account_id": "a0b1c3"
}
},
"data": [
{
"start_time": "2013-05-30T04:00:00Z",
"description": "FakeNike - Credit Line",
"credit_limit_local_micro": 150000000000,
"end_time": null,
"cancelled": false,
"id": "i1234",
"paused": false,
"account_id": "a0b1c3",
"reasons_not_able_to_fund": [],
"io_header": null,
"currency": "USD",
"funded_amount_local_micro": 0,
"created_at": "2013-05-30T18:16:38Z",
"type": "CREDIT_LINE",
"able_to_fund": true,
"updated_at": "2013-05-30T18:16:38Z",
"credit_remaining_local_micro": 123661919751,
"deleted": false,
}
],
"data_type": "funding_instrument",
"total_count": 1,
"next_cursor": null
}
```
The only thing particular about this funding instrument is the type and the fact that it is available to all the accounts that were associated to it. Of course, the remaining credit is impacted by all campaigns funded by this instrument, across all accounts sharing it. The details of what accounts are associated to a specific credit line are not available via the API (nor via ads.x.com).
For more information on Funding Instrument enumerations, please click [here](/x-ads-api/introduction).
### Targeting
Targeting is a core concept of the Ads API. Targeting is set at the line item level and options vary across placements. To set new targeting criteria you need to use [POST accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#post-accounts-account-id-targeting-criteria) and [PUT accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#get-accounts-account-id-targeting-criteria) to update them.
Use [GET accounts/:account\_id/line\_items](/x-ads-api/campaign-management/reference#get-accounts-account-id-line-items) for a list of all line items and [GET accounts/:account\_id/line\_items/:line\_item\_id](/x-ads-api/campaign-management/reference#get-accounts-account-id-line-items-line-item-id) to retrieve a specific line item.
#### Targeting options by placement
[Promoted Tweets](https://business.x.com/help/what-are-promoted-tweets) and [Promoted Accounts](https://business.x.com/help/what-are-promoted-accounts) products can be made available on a variety of placements. [Promoted Trends (PTr)](https://business.x.com/help/what-are-promoted-trends) are not available via the API.
For possible placement combinations, refer to the [GET line\_items/placements](/x-ads-api/campaign-management/reference#get-line-items-placements) endpoint. Each placement has different options for targeting. Location, Platform and Gender are available for all. The other options are contextual to the type of placement.
* **X Search**: Age Targeting, Devices, Events, Gender, Keyword Types (All), Language, Locations, Network Activation, Network Operators, Platform, Platform Version, Tailored Audiences, WiFi Only
* **X Timeline**: Age Targeting, Devices, Events, Followers Of, Similar to Followers Of, Gender, Interest, Language, Locations, Network Activation, Network Operators, Non-exact Keyword Types, Partner Audience Types, Platform, Platform Version, Retargeting Types, Tailored Audiences, TV Targeting Types, WiFi Only
* **X Profiles & Tweet Details**: Age Targeting, Devices, Events, Followers Of, Similar to Followers Of, Gender, Interest, Language, Locations, Network Activation, Network Operators, Non-exact Keyword Types, Partner Audience Types, Platform, Platform Version, Retargeting Types, Tailored Audiences, TV Targeting Types, WiFi Only
#### Understanding targeting types
**Age Targeting**: Target users based on specific age buckets. A list of age bucket enums can be found on the [Enumerations](/x-ads-api/introduction) page.
[Events](https://business.x.com/help/event-targeting): Specify an event for targeting. Only one event can be used for targeting (per line item). Use the [GET targeting\_criteria/events](/x-ads-api/campaign-management/reference#get-targeting-criteria-events) endpoint to find events available for targeting.
[Gender](https://business.x.com/help/geo-gender-and-language-targeting): Target males (1) or females (2). Leave null to target all.
[Installed App Store Categories](https://business.x.com/help/installed-app-category-targeting): use this targeting type to target users based on the categories of apps they have installed or have indicated interest in. See [GET targeting\_criteria/app\_store\_categories](/x-ads-api/campaign-management/reference#get-targeting-criteria-app-store-categories).
[Interests](https://business.x.com/help/interest-and-username-targeting): Target users by interest. Get the interests list from [GET targeting\_criteria/interests](/x-ads-api/campaign-management/reference#get-targeting-criteria-interests). You can target up to 100 interests.
**Followers Of**: Target the followers of any fully promotable users for the current account (note, currently the primary account holder is the only fully-promotable user of that account). [GET accounts/:account\_id/promotable\_users](/x-ads-api/campaign-management/reference#get-accounts-account-id-promotable-users) to get a list of promotable users.
[Similar to Followers Of](https://business.x.com/help/interest-and-username-targeting): Target people with the same interests as followers of specific users. You can use up to 100 [Users](/x-api/fundamentals/data-dictionary/reference#user).
[Locations](https://business.x.com/help/geo-gender-and-language-targeting): Specify up to 2,000 locations to target. Get list from [GET targeting\_criteria/locations](/x-ads-api/campaign-management/reference#get-targeting-criteria-locations). There are additional requirements for ads that target certain countries. See [Country Targeting and Display Requirements](/x-ads-api/campaign-management/reference#country-targeting-and-display-requirements) for more information.
[Keywords](https://business.x.com/help/keyword-targeting): Keyword targeting options are specific by type of placement. You can use up to 1000 keywords for targeting (per line item). See the Keyword Types section for options.
[Language Targeting](https://business.x.com/help/geo-gender-and-language-targeting): Target users who understand specific languages.
[Mobile Network Operator Targeting](https://business.x.com/help/device-carrier-and-new-mobile-user-targeting): Enables advertisers to target users based on mobile carrier, using the targeting type `NETWORK_OPERATOR` from [GET targeting\_criteria/network\_operators](/x-ads-api/campaign-management/reference#get-targeting-criteria-network-operators).
[New Mobile Device Targeting](https://business.x.com/help/device-carrier-and-new-mobile-user-targeting): Reach users based on the date that they first accessed X via their device, using the targeting type `NETWORK_ACTIVATION_DURATION` using operator\_type of LT for less than and `GTE` for greater than or equal.
[Platforms](/x-ads-api/campaign-management/reference#get-targeting-criteria-platforms), [Platform Versions](/x-ads-api/campaign-management/reference#get-targeting-criteria-platform-versions), [Devices](/x-ads-api/campaign-management/reference#get-targeting-criteria-devices), and Wifi-Only: Allows targeting of mobile devices across a variety of vectors. Platforms is a high-level targeting type that can hit broad categories of phone. Example values are `iOS` and `Android`. Devices allow you to target users of specific mobile devices, for example the `iPhone 5s`, `Nexus 4`, or `Samsung Galaxy Note`. Platform versions allow you to target users of versions of specific mobile operating systems, down to the point release. Examples include iOS 7.1 and Android 4.4. Wifi-Only allows you to target only those users who are using their devices on a WiFi network; if this is not set, users using the carrier connection as well as WiFi will be targeted.
* Users can target platforms and devices if there is no overlap. I can target Blackberry as a platform and iPad Air as a device simultaneously.
* Users can target devices and os versions simultaneously. I can target iPad Air and iOS >= 7.0.
* Users cannot target platforms that are broader than devices. I cannot target iOS and iPad Air.
\[Tailored Audiences]/x-ads-api/audiences: Reach users through an approved ads partner to target groups of customers and connect with them on X.
**[TV Targeting](https://support.x.com/articles/20170766-tv-targeting)**
**TV Show Targeting**: reach people that engage with specific TV programs. This targeting criteria can be configured to continuously target while a campaign is active with the `TV_SHOW` targeting type. Use the [GET targeting\_criteria/tv\_markets](/x-ads-api/campaign-management/reference#get-targeting-criteria-tv-markets) and [GET targeting\_criteria/tv\_shows](/x-ads-api/campaign-management/reference#get-targeting-criteria-tv-shows) endpoints to determine TV shows available.
**Tweet Engager Retargeting**
Tweet engager retargeting enables advertisers to target audiences across devices who have previously been exposed to or engaged with their promoted or organic Tweets on X. With this targeting advertisers can follow up with people who saw or engaged with an advertiser’s content on X and are most likely to further engage or convert with subsequent messaging or offers. Users will be eligible for targeting within minutes of exposure or engagement and will remain eligible for up to 90 days afterwards for engagements and 30 days for exposures.
Tweet Engager Targeting Types:
* `ENGAGEMENT_TYPE` which accepts either `IMPRESSION` or `ENGAGEMENT` as a targeting value. This specifies whether you wish to target exposed users (`IMPRESSION`) or engaged users (`ENGAGEMENT`).
* `CAMPAIGN_ENGAGEMENT` uses a campaign ID as the targeting value. Users who engaged with or were exposed to this campaign (depending on `ENGAGEMENT_TYPE`) are the ones who will be targeted.
* `USER_ENGAGEMENT` which uses the promoted user ID as the targeting value to target users who were exposed to or engaged with an advertiser’s organic content (depending on `ENGAGEMENT_TYPE`). This must be the promoted user ID associated with the Ads account.
*Note:* `ENGAGEMENT_TYPE` is required in addition to at least one valid `CAMPAIGN_ENGAGEMENT` or `USER_ENGAGEMENT` value. Both tweet engager targeting types may be present and multiple campaigns may be targeted on a given line item.
**Video Viewer Targeting**: Video viewer targeting builds on Tweet engager targeting to enable advertisers to target audiences who have previously watched part or all of a video on X. Advertisers can target organic videos, promoted videos, or both. Promoted videos are not limited to video view objective campaigns or line items.
Video Viewer Targeting Types:
* `VIDEO_VIEW` for users who have clicked to play the video or have viewed 3 seconds of autoplay
* `VIDEO_VIEW_PARTIAL` for users who have viewed 50% of the video
* `VIDEO_VIEW_COMPLETE` for users who have viewed at least 95% of the video
As with Tweet engager targeting, one or both of the following must also be present in targeting criteria for the line item when `ENGAGEMENT_TYPE` is used:
* `CAMPAIGN_ENGAGEMENT` uses a campaign ID as the targeting value. Users who watched a video (based on `ENGAGEMENT_TYPE`) in this campaign are the ones who will be targeted.
* `USER_ENGAGEMENT` which uses the promoted user ID as the targeting value to target users who watched a video (based on `ENGAGEMENT_TYPE`) in an advertiser’s organic content. This must be the promoted user ID associated with the Ads account.
**Keyword Types**
See our support document on [keyword targeting](https://business.x.com/en/help/campaign-setup/campaign-targeting/keyword-targeting.html) for a conceptual overview.
* **Broad** (default value): match all words, independent of order. Not sensitive to capitalization, plurals or tense. Will automatically be expanded when possible (i.e. “car repair” would also match “automobile fix”). If you want to target without expansion, you need to add a + sign before the keywords, like “+boat +jet”. Using keywords without the + will default to Broad Match.
* **Unordered** (deprecated): match all words, independent of order. Not sensitive to capitalization, plurals or tense.
* **Phrase**: match the exact keywords string, other keywords can be present.
* **Exact**: match exactly the keywords string, not any others.
* **Negative**: avoid matching searches that include all of these keywords somewhere in the query, regardless of the order in which they are written, even if other words are present.
* **Negative Phrase**: avoid matching searches that include this exact keywords string somewhere in the query, even if other words are present.
* **Negative Exact**: avoid matching searches that exactly match these keywords and contain no other words.
**Emoji targeting**
Emoji targeting is supported via keyword targeting. To use emoji targeting, simply create keyword targeting for Unicode codepoints representing that emoji such as *U+1F602* (*xF0x9Fx98x82* in UTF-8) for the ‘face with tears of joy’ emoji (😂). Emoji which we accept can be confirmed with the [twemoji](https://x.github.io/twemoji/preview.html) list. Targeting an emoji targets all variations.
For a summary of all values with required/optional and specific details for each, see [PUT accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#get-accounts-account-id-targeting-criteria).
#### Targeting Criteria Combinations
**Updated Campaign Workflow**
Create campaigns which target broadly with geo, gender, language, and device/platform criteria. Advertisers can then combine the broad targeting with additional targeting criteria (e.g. interests, keywords, followers, tailored audiences, TV). **If no targeting criteria is specified for a line item, the line item will target all users worldwide.**
| | |
| :----------------- | :-------------------- |
| “Primary” Types | Other Types |
| Followers | Locations |
| Tailored Audiences | Gender |
| Interests | Languages |
| Keywords | Devices and platforms |
| TV | Age |
Targeting criteria will be combined for your ad group such that:
* “Primary” Targeting Types will get **∪**‘d (i.e. put in a logical union).
* Other Targeting Types will get **AND**‘d.
* Same types will get **OR**‘d.
**Some examples**
At a glance: \[(**Followers**) ∪ (**Tailored Audiences**) ∪ (**Interests**) ∪ (**Keywords**)] AND (**Location**) AND (**Gender**) AND (**Languages**) AND (**Devices and Platforms**)
A Geo example:
Let’s say we want an ad group for our campaign to serve targeting:
* X users in the U.S., England, and Canada (Location)
* who are Women (Gender)
* derived from Tailored Audiences list (“Primary”)
* with Keywords (“Primary”)
The targeting criteria will be:
\[**US** OR **GB** OR **CA**] AND \[**Female**] AND \[**Tailored Audiences** ∪ **Keyword**]
### Additional examples
* Select Gender and Geo but no primary: (**Male**) AND (**US** OR **GB**)
* Select Gender, Geo, Interest: (**Female**) AND (**CA**) AND (**Computers** OR **Technology** OR **Startups**)
* Select Gender, Geo, Interest, Tailored Audiences, Keywords: (**Male**) AND (**GB**) AND (**Cars** ∪ **Tailored Audiences for CRM** ∪ **autocross**)
### Budget Pacing
Advertisers now have more control over how fast their daily budgets are spent on your Promoted Tweet and Account campaigns. Enabling standard delivery, which is the default, ensures an even spend rate throughout the day.
By turning **off** standard delivery, we will serve impressions and generate engagements as quickly as possible until your daily budget is exhausted, which may be quite early on in the day depending on targeting and competition. This is called accelerated delivery.
**Getting Started**
Standard delivery is the default option for all campaigns, so no action is required unless you wish to turn it off. To spend through your daily budget on a campaign as fast as possible set the `standard_delivery` parameter to `false` to set the pace to accelerated delivery (see [GET accounts/:account\_id/campaigns](/x-ads-api/campaign-management/reference#get-accounts-account-id-campaigns)).
**Notes**
* “Day” is respective to X [advertiser account](/x-ads-api/campaign-management/reference#accounts) timezone (eg. America/Los\_Angeles).
* Early results indicate that standard delivery will improve eCPE/CPF for advertisers, with more consistent coverage throughout the day.
For more additional information about budgets and pacing please see the [Bidding and Auctions FAQ](https://business.x.com/en/help/troubleshooting/bidding-and-auctions-faqs.html).
### Target Bidding
Campaign management
#### Bid Strategy
We have introduced the concept of Bid Strategy to simplify campaign creation workflow and reduce confusion about combinations of multiple parameters.
All previous (marked as legacy) combinations of parameters can be achieved by setting an equivalent goal parameter. Further information can be found in the announcement [here](https://devcommunity.x.com/t/ads-api-version-10/158787/1#changed-default-bid_strategy-values-9).
As example:
| | | |
| :--------------------- | :---------------------------------------------------------------------------------------------- | :--------------------------------------------------------- |
| **Campaign Objective** | **Legacy** | **Ads API v10+** |
| App Installs | `bid_type`= `AUTO`
`bid_strategy` = `AUTO` |
| Website Clicks | `bid_type` = `TARGET` (Note: `bid_unit` was not needed for some campaign objectives) | `bid_strategy` = `TARGET` |
#### Target Bidding
Using target bidding, you can specify a target cost you want to pay and the X Ads platform will optimize your campaign for performance while staying near or below your target cost.
This feature gives you the flexibility to reach users who are especially likely to take the desired action (such as a link click, a lead or a follow) while maintaining cost control. This is a powerful feature for advertisers who desire more options for campaign setup and optimization (including bidding options).
For line items with compatible campaign objectives, we’ve introduced a new pricing mechanism for bid amount that lets you specify a target cost you want to pay. Our ad platform dynamically bids on your behalf to help you drive more results, while working to keep your average cost within 20% of your specified target. The `bid_strategy` setting on line items may be set with a value of `TARGET` to enable target bidding on relevant campaign objectives, such as:
* `WEBSITE_CLICKS`
* `WEBSITE_CONVERSIONS`
* `APP_INSTALLS`
* `APP_ENGAGEMENTS`
* `REACH`
### Country Targeting and Display Requirements
Campaign management
Country-specific targeting and display requirements are contained on this page. These requirements must be adhered to by all partners.
#### Russia
[X’s Ads Policies](https://support.x.com/groups/58-advertising/topics/249-advertiser-policies/articles/20171727-illegal-products-and-services) prohibit advertisers from targeting Russia with advertisements that are not in the Russian language. When your users specifically target Russia, you must display the following warning message to your users:
Ads targeting Russia must be in the Russian language.
### Partner Managed Funding Instruments
The onboarding flow configures an [ads.x.com](https://ads.x.com) account for the X account, which can be managed by the partner through the Ads API, and whose advertising spend is billed to the partner.
#### Partner Initial Set-up
The process to initially set-up a new PMFI Ads API partner takes up to 3-weeks from exchange of required information. The following must be shared with your technical contacts at X, as well as the X contact managing the integration with the partner in order to get the process started:
* **The partner must share their PGP/GPG public key.** A shared secret key needs to be exchanged between the Ads API partner and X. This will be used to verify data during the onboarding flow.
* **The** `app_id` **or** `consumer_secret` **for the [X app](/resources/fundamentals/developer-apps) that will be used for Ads API access.** You can view and edit your existing X apps via the [app dashboard](https://developer.x.com/content/developer-twitter/en/apps) if you are logged into your X account on developer.x.com. If you need to create a X app, you will need to have an approved [developer account](/resources/fundamentals/developer-portal). X allows one app for production+sandbox and one optional app for sandbox-only access. The X app must be created on a corporate, partner-controlled X handle.
#### Advertiser Onboarding Flow
The advertiser onboarding flow occurs via a web browser in the following way:
1. The user starts the onboarding flow on the partner’s website and enters the handle they want to onboard.
2. The partner redirects the user to a URL on [ads.x.com](https://ads.x.com) with a signed payload. This payload contains the partner’s API `app_id`, the X `user_id` of the X handle which is to be onboarded and a callback URL and other fields documented below.
3. The user is asked to sign into [ads.x.com](http://ads.x.com) using the standard x.com login page.
4. Once the user is logged in, the onboarding process is initiated. This step includes ad review, account validation and other checks.
5. When all onboarding tasks are completed, the user is redirected to the callback URL that was provided by the Ads API partner, with a payload that indicates success or failure. This includes the 3-legged authorization process.
#### Onboarding redirect payload
URL for redirect:
[https://ads.x.com/link\\\_managed\\\_account](https://ads.x.com/link\\_managed\\_account)
The redirect URL will be called with the following parameters:
| | | |
| :------------------- | :---------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name | Type | Description |
| callback\_url | URL encoded string | user will be redirected to this url after the account link process completes, regardless of outcome. See the partner redirect url section for protocol details |
| client\_app\_id | integer | X API client app id, used to identify the managing partner |
| promotable\_user\_id | integer | X user\_id of the @handle whose promotions are to be managed by the managing partner. Used to make sure it is the same as the user who logs into ads.x.com to complete the linking process |
| fi\_description | URL encoded String (max 255 characters) | funding instrument name. This will be displayed in the description field in the API when the funding instrument is retrieved. If a funding\_instrument description is given, the existing funding\_instrument will be paused, and a new managed partner funding instrument will be set up. (if one exists with the same name, nothing will happen) |
| timezone | String, in Area/Location format | This will be the timezone used to determine the day to which daily budgets apply, and in which charges will be aggregated |
| currency | ISO 4217 Currency Code | Currency that will be used to enter bids, and in which charges will be billed |
| country | ISO 3166-1 alpha 2 Country Code | Billing Country for the account |
| signature | URL encoded, base64 encoded binary code, as explained below | signature that combines a shared secret and the other parameters to verify authenticity of the call, as well as validity of the parameters. |
#### Callback URL payload
The base redirect URL is provided using the callback\_url parameter on the account link request (see above). The parameters added by [ads.x.com](https://ads.x.com) are:
| | | |
| :---------------------- | :---------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name | Type | Description |
| status | string | **OK** an account was created, or an existing, eligible account was found.
**ACCOUNT\_INELIGIBLE** if partner specific constraints are not met **USER\_MISMATCH** the X account used to sign into ads.x.com was different from the promotable\_user\_id on the account link request **INCOMPLETE\_SERVING\_BILLING\_INFO** timezone, currency or country were not specified **INVALID\_COUNTRY** an invalid country value was given **INVALID\_CURRENCY** an invalid currency value was given **INVALID\_TIMEZONE** an invalid timezone value was given |
| account\_id | URL encoded string | X ads account id of the linked account |
| funding\_instrument\_id | URL encoded string | ID of the active partner managed funding instrument |
| signature | URL encoded, base64 encoded binary code, as explained below | Base64 encoded HMAC-SHA1 signature that combines a shared secret and the other parameters to verify authenticity of the call, as well as validity of the parameters. To make sure the callback url is only valid for the X user\_id that the account link process was intended for, the X user\_id is to be appended to the shared secret (using &) when signing the request. |
To make sure the callback URL is only valid for the X `user_id` that the account link process was intended for, the X `user_id` is to be appended to the shared secret (using &) when signing the request.
#### Signing the request and callback URLs
In order to ensure that the requests to `/link_managed_account` and the callback url are valid, the requests need to be signed at the source and verified by the recipient before the recipient takes action on them. Signing the request with a secret that is shared between X and the managing partner ensures that each party only accepts requests sent by the authorized counterpart.
The signature generation algorithm is similar to the one used in OAuth.
Create a signature base string as follows:
* Convert the HTTP Method to uppercase and set the base string equal to this value.
* Append the ‘&’ character to the base string.
* Percent encode the URL (without parameters) and append it to the base string.
* Append the ‘&’ character to the base string.
* Append the percent encoded query string, which is built as follows:
* Percent encode every key and value that will be signed.
* Sort the list of parameters alphabetically by key.
* For each key/value pair (and with primary\_promotable\_user\_id for the partner redirect url):
* Append the percent encoded key to the query string.
* Append the ‘=’ character to the base string.
* Append the percent encoded value to the query string.
* Separate the percent encoded key=value pairs with the ‘&’ character.
* Use the HMAC-SHA1 algorithm, using the previously exchanged shared secret, as the key, and the base string as the value to generate the signature.
* Base64 encode the output of Step 2, drop the trailing newline character percent encode the signature generated in Step 3 and add it to the url in a signature parameter
#### Signing examples
Signing a link account request
Url to sign, assuming a GET request:
[https://ads.x.com/link\\\_managed\\\_account?callback\\\_url=https%3A%2F%2Fmanagingpartner.com%2Flink\\\_account\\\_callback\&client\\\_app\\\_id=12345\&fi\\\_description=some%20name\&promotable\\\_user\\\_id=1](https://ads.x.com/link\\_managed\\_account?callback\\_url=https%3A%2F%2Fmanagingpartner.com%2Flink\\_account\\_callback\&client\\_app\\_id=12345\&fi\\_description=some%20name\&promotable\\_user\\_id=1)
This url has the following parameters:
callback\_url = [https://managingpartner.com/link\\\_account\_callback](https://managingpartner.com/link\\_account_callback)
client\_app\_id = 12345
fi\_description = some name
promotable\_user\_id = 1
The base string consisting of http method and url without parameters, steps a - d, looks like:
GET [https://ads.x.com/link\\\_managed\\\_account](https://ads.x.com/link\\_managed\\_account)
The query string, produced by the substeps of e, looks like:
callback\_url=[https://managingpartner.com/link\\\_account\\\_callback\&client\\\_app\\\_id=12345\&fi\\\_description=some](https://managingpartner.com/link\\_account\\_callback\&client\\_app\\_id=12345\&fi\\_description=some) name\&promotable\_user\_id=1
Note that the key-value pairs are sorted by key name.
The percent encoded query string looks like:
callback\_url%3Dhttps%253A%252F%252Fmanagingpartner.com%252Flink\_account\_callback%26client\_app\_id%3D12345%26fi\_description%3Dsome%2520name%26promotable\_user\_id%3D1
The complete base string, combining steps a - d and e:
GET [https://ads.x.com/link\\\_managed\\\_account\&callback\\\_url%3Dhttps%253A%252F%252Fmanagingpartner.com%252Flink\\\_account\\\_callback%26client\\\_app\\\_id%3D12345%26fi\\\_description%3Dsome%2520name%26promotable\\\_user\\\_id%3D1](https://ads.x.com/link\\_managed\\_account\&callback\\_url%3Dhttps%253A%252F%252Fmanagingpartner.com%252Flink\\_account\\_callback%26client\\_app\\_id%3D12345%26fi\\_description%3Dsome%2520name%26promotable\\_user\\_id%3D1)
Using the hmac-sha1 algorithm we will sign this with the word “secret” as the key. The result is Base64 encoded, and presented without the final “\n” (steps 2 and 3): `KBxQMMSpKRrtg9aw3qxK4fTXvUc=`
This signature is then added (percent encoded) to the end of the original url in the signature parameter (step 4):
[https://ads.x.com/link\\\_managed\\\_account?callback\\\_url=https%3A%2F%2Fmanagingpartner.com%2Flink\\\_account\\\_callback\&client\\\_app\\\_id=12345\&fi\\\_description=some%20name\&promotable\\\_user\\\_id=1\&signature=KBxQMMSpKRrtg9aw3qxK4fTXvUc%3D](https://ads.x.com/link\\_managed\\_account?callback\\_url=https%3A%2F%2Fmanagingpartner.com%2Flink\\_account\\_callback\&client\\_app\\_id=12345\&fi\\_description=some%20name\&promotable\\_user\\_id=1\&signature=KBxQMMSpKRrtg9aw3qxK4fTXvUc%3D)
Signing a partner redirect url (account link request callback) The URL to sign, assuming a GET request:
[https://managingpartner.com/link\\\_account\\\_callback?status=OK\&account\\\_id=ABC\&funding\\\_instrument\_id=DEF](https://managingpartner.com/link\\_account\\_callback?status=OK\&account\\_id=ABC\&funding\\_instrument_id=DEF)
This url has the following parameters:
`account_id` = `ABC`, `funding_instrument_id` = `DEF` and `status` = `OK`
The base string consisting of http method and url without parameters, steps a - d, looks like:
GET https%3A%2F%2Fmanagingpartner.com%2Flink\_account\_callback&\`\`
The query string, produced by the substeps of e, looks like:
account\_id=ABC\&funding\_instrument\_id=DEF\&status=OK
The percent encoded query string looks like:
account\_id%3DABC%26funding\_instrument\_id%3DDEF%26status%3DOK
The complete base string, combining steps a - d and e:
GET https%3A%2F%2Fmanagingpartner.com%2Flink\_account\_callback\&account\_id%3DABC%26funding\_instrument\_id%3DDEF%26status%3DOK
Using the hmac-sha1 algorithm we will sign this with the word “secret” and the X user id for which the original link request was made, 1 (`promotable_user_id` = 1 from above) as the key, “secret&1”.
The result is Base64 encoded, and presented without the final “\n” (steps 2 and 3): `jDSHDkHJIFXpPLVxtA3a9d4bPjM=`
This signature is then added (percent encoded) to the end of the original url in the signature parameter (step 4):
[https://managingpartner.com/link\\\_account\\\_callback?\&status=OK\&account\\\_id=ABC\&funding\\\_instrument\_id=DEF\&signature=jDSHDkHJIFXpPLVxtA3a9d4bPjM%3D](https://managingpartner.com/link\\_account\\_callback?\&status=OK\&account\\_id=ABC\&funding\\_instrument_id=DEF\&signature=jDSHDkHJIFXpPLVxtA3a9d4bPjM%3D)
### Shared Key use / renewal
The signing algorithm should have the ability to repeat itself with multiple keys. This will allow multiple shared keys to be used, and enables cycling shared keys on a periodic basis.
### partner\_managed\_funding\_instrument creation
If the fi\_description parameter is given, and no existing partner\_managed\_funding\_instrument with the same name exists in the account, a new partner\_managed\_funding\_instrument will be created, and all existing partner\_managed\_funding\_instruments will be paused.
If a partner\_managed\_funding\_instrument with the same name exists, no new one will be created.
### Repeated on-boarding flow calls / token refresh
The on-boarding flow can be repeated in case the API access token was lost. The on-boarding flow implementation will require the user is logged in. If the user matches the promotable\_user\_id, and the associated ads account is found, and everything looks good, the user will be redirected back to the callback url, and the partner can initiate the OAuth flow to obtain an [access token](/resources/fundamentals/authentication#obtaining-access-tokens-using-3-legged-oauth-flow).
### Non-redirectable error flow
If the account link url is invoked with invalid parameters, the user will be shown a page similar to the one shown in the OAuth flow when invalid or expired parameters are given.
#### Ongoing updates to the PMFI
Once the advertiser has been onboarded, the funding instrument can be managed using the [PUT accounts/:account\_id/funding\_instruments/:funding\_instrument\_id](/x-ads-api/campaign-management/reference#get-accounts-account-id-funding-instruments) endpoint by only the partner who manages it.
### Placements
There are several places where X ads can be displayed. This is set at the [line item](/x-ads-api/campaign-management/reference#line-items) using the `placements` parameter. The possible values are:
* `ALL_ON_TWITTER`
* `PUBLISHER_NETWORK`
* `TWITTER_PROFILE`
* `TWITTER_SEARCH`
* `TWITTER_TIMELINE`
* `SPOTLIGHT`
* `TREND`
The line item’s `product_type` and `objective` determine which placements are allowed. The [GET line\_items/placements](/x-ads-api/campaign-management/reference#line-item-placements) endpoint can be used to retrieve the valid placement options for each product type.
Additionally, the following table lists the valid placement and objective combinations.
| Objective | `ALL_ON_TWITTER` | `TWITTER_PROFILE` | `TWITTER_SEARCH` | `TWITTER_TIMELINE` |
| :---------------- | :--------------- | :---------------- | :--------------- | :----------------- |
| `APP_ENGAGEMENTS` | ✔ | ✔ | ✔ | ✔ |
| `APP_INSTALLS` | ✔ | ✔ | ✔ | ✔ |
| `REACH` | ✔ | ✔ | ✔ | ✔ |
| `FOLLOWERS` | ✔ | ✔ | ✔ | ✔ |
| `ENGAGEMENTS` | ✔ | ✔ | ✔ | ✔ |
| `VIDEO_VIEWS` | ✔ | ✔ | ✔ | ✔ |
| `PREROLL_VIEWS` | ✔ | ✔ | ✔ | ✔ |
| `WEBSITE_CLICKS` | ✔ | ✔ | ✔ | ✔ |
**Note**: It is not possible to specify *only* `TWITTER_PROFILE` placement.
**Note**: `TWITTER_SEARCH` requires [keyword targeting](/x-ads-api/campaign-management/reference#targeting-options).
**Note**: The `REACH` objective must include `TWITTER_TIMELINE` placement. It can have either `ALL_ON_TWITTER`, any combination of placements that include `TWITTER_TIMELINE`, or `TWITTER_TIMELINE` on its own.
### Ad groups FAQ
This document is meant to be a collection of commonly asked questions about Ad Groups in X's Ads API.
#### What is an Ad Group?
Ad groups, known as line items in the Ads API, exist under campaigns and are used for targeting and bidding against a set of X users. Advertisers promote Tweets or media (e.g., videos that are promoted as In-stream ads) by associating them with a line item.
#### How do we create an Ad Group?
Ad Groups are created by calling [POST accounts/:account\_id/line\_items](/x-ads-api/campaign-management/reference#post-accounts-account-id-line-items) multiple times for the same campaign ID, and keeping (possibly completely different) targeting and Tweets associated with those line items. There is a limit of 100 line items per campaign and a limit of 200 active campaigns for a single ads account. Across all campaigns, there is a limit of and 8,000 active line items per ads account.
#### Why should we add support for Ad Groups?
Ad Groups are intended to make it easier for advertisers to organize, optimize and manage their campaigns.
The advantage of Ad Groups is to compare and control different strategies across bid, budget, creative, and targeting. Upon associating multiple Promoted Tweets to a single line item, the auction would select the best Tweet from that group and then select the best Tweet for that campaign from all of the line items. If you have multiple Ad Groups with single Tweets, it would effectively select the Tweet that would likely perform better from that Ad Group.
Using Ad Groups enables an advertiser to split up targeting and bidding into a much greater number of possible combinations, and in general allows splitting up targeting into logical groups.
Ads API tools in particular could be built around fine tuned optimization rules with Ad Groups that would be more difficult to do via manual edits due to the larger scale of line item and creative combinations.
#### How does the line item budget relate to campaign budget in an Ad Groups campaign?
The total\_budget\_amount\_local\_micro for a line item cannot exceed the total budget for its parent campaign. Similarly, the line item’s bid\_amount\_local\_micro value should not exceed daily\_budget\_amount\_local\_micro or total\_budget\_amount\_local\_micro of the parent campaign. Setting these values incorrectly may put the overall campaign into a paused and unservable state.
Note that the total campaign budget can be less than the sum of the budgets of its child line items, and distribution of budget between line items is partially up to the Ads API tool to effectively optimize and change as daily performance of targeting (line item) could differ significantly day to day due to X’s realtime nature.
#### Do Ad Groups perform better than single line items?
The performance of a campaign depends upon many factors and effectively a Tweet is the final deciding factor of performance. A Line Item will be treated as a factor of whether or not a Tweet is even in the running to be served to a user.
Line items that target the same sets of users are considered to have overlap of users. It is considered a best practice to reduce this overlap of targeting between line items so that the highest performing sets of users can be clearly identified.
## Guides
### Video Views Preroll Objective
The following guide outlines the steps required to set up a PREROLL\_VIEWS campaign on the Ads API. Broadly speaking these campaigns are split into two types, Curated Categories and Content Categories (referred to as Standard Categories on the Ads UI).
#### Endpoints Required
* [Chunked media upload](/x-api/media/quickstart/media-upload-chunked) (for video upload)
* [POST accounts/:account\_id/media\_library](/x-ads-api/creatives/reference#media-library) (for video association to ads account)
* [POST accounts/:account\_id/campaigns](/x-ads-api/campaign-management/reference#post-accounts-account-id-campaigns) (create campaign)
* [GET content\_categories](/x-ads-api/campaign-management/reference#content-categories) (to get the mapping of content categories to IAB categories)
* [GET accounts/:account\_id/curated\_categories](/x-ads-api/campaign-management/reference#curated-categories-2)
* [GET publishers](/x-ads-api/campaign-management/reference#publishers)
* [POST accounts/:account\_id/line\_item\_curated\_categories](/x-ads-api/campaign-management/reference#line-item-curated-categories)
* [POST accounts/:account\_id/line\_items](/x-ads-api/campaign-management/reference#campaigns) (create ad group)
* [POST accounts/:account\_id/media\_creatives](/x-ads-api/campaign-management/reference#post-accounts-account-id-media-creatives) (to associate video with ad group)
* [POST accounts/:account\_id/preroll\_call\_to\_action](/x-ads-api/creatives/reference#preroll-call-to-actions) (set CTA and redirect URL)
* [POST batch/accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#post-batch-accounts-account-id-targeting-criteria) (targeting)
#### Steps
#### Upload the video
Uploading the video involves 2 steps:
#### Upload the video media
First, using the [Chunked media upload](/x-api/media/quickstart/media-upload-chunked) endpoint, you will upload the video to X for processing. You must pass the `media_category=amplify_video` on the initial `INIT` using this endpoint. You’ll upload the video in chunks. Once the `STATUS` returns a `state` of `succeeded` you may continue with the next steps. More on the uploading of media using the chunked endpoint can be found in our [Promoted Video Overview](/x-ads-api/creatives/reference#promoted-video).
#### Add the video to the ads account
Once the state returned using the `STATUS` command is `succeeded`, you’ll use the media\_key returned from that endpoint to add the video to the advertiser’s media library, using the [POST accounts/:account\_id/media\_library](/x-ads-api/creatives/reference#media-library) endpoint.
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/55w3kv/media\_library?media\_key=3_931236738554519552
{
"request": {
"params": {
"account_id": "55w3kv",
"media\_key": "3\_931236738554519552"
}
},
"data": {
"tweeted": false,
"name": null,
"file_name": null,
"media\_url": "https://video.twimg.com/amplify\_video/1059840836186165250/vid/568x320/Gr2l1fB1X7xotKwC.mp4?tag=8",
"media\_category": "AMPLIFY\_VIDEO",
"media\_key": "3\_931236738554519552",
"created_at": "2017-11-16T19:05:14Z",
"media\_status": "TRANSCODE\_COMPLETED",
"media_id": 931236738554519552,
"media_type": "VIDEO",
"updated_at": "2017-11-16T19:05:23Z",
"deleted": false
}
}
```
#### Setup the campaign
### Campaign Creation
Create the [campaign](/x-ads-api/campaign-management/reference#post-accounts-account-id-campaigns) and [line item/ad group](/x-ads-api/campaign-management/reference#campaigns). Line items should be created with an `objective` of `VIDEO_VIEWS_PREROLL`, and a `product_type` of `MEDIA`. The `categories` parameter must also be set to the appropriate [advertiser business categories](/x-ads-api/campaign-management/reference#advertiser-business-categories).
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/accounts/55w3kv/campaigns?name=test-curated-categories-api&funding\_instrument\_id=103hp9&start\_time=2021-02-10&entity\_status=PAUSED&daily\_budget\_amount\_local\_micro=55000000
{
"request": {
"params": {
"name": "test-curated-categories-api",
"start_time": "2021-02-10T00:00:00Z",
"daily\_budget\_amount\_local\_micro": 55000000,
"funding\_instrument\_id": "103hp9",
"entity_status": "PAUSED",
"account_id": "55w3kv"
}
},
"data": {
"name": "test-curated-categories-api",
"start_time": "2021-02-10T00:00:00Z",
"reasons\_not\_servable": \[
"EXPIRED",
"PAUSED\_BY\_ADVERTISER",
"FUNDING_PROBLEM"
\],
"servable": false,
"purchase\_order\_number": null,
"effective_status": "PAUSED",
"daily\_budget\_amount\_local\_micro": 55000000,
"end_time": null,
"funding\_instrument\_id": "103hp9",
"duration\_in\_days": null,
"standard_delivery": true,
"total\_budget\_amount\_local\_micro": null,
"id": "f2rp3",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2021-02-08T23:55:38Z",
"updated_at": "2021-02-08T23:55:38Z",
"deleted": false
}
}
```
### Line Item Creation
Line items must have the categories parameter set to the appropriate set of IAB categories, retrieved via the [GET content\_categories](/x-ads-api/campaign-management/reference#content-categories) endpoint. These content categories each correspond to one or more IAB categories.
In order to use these values, partners must select an appropriate content category and use the entire set of iab\_categories returned in the response, to set the categories parameter on the line items endpoint. Any partial application of the iab\_categories will result in the entire group being set on the line item. For example,
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
GET https://ads-api.x.com/8/advertiser\_business\_categories
{
"request": {
"params": {}
},
"next_cursor": null,
"data": \[
{
"id": "1jl",
"name": "Consumer Packaged Goods",
"iab_categories": \[
"IAB9-26",
"IAB9-18",
"IAB9-29",
"IAB9-1",
"IAB9-8",
"IAB9-22",
"IAB6",
"IAB9-5",
"IAB9-12",
"IAB9-11",
"IAB9-23",
"IAB9-14",
"IAB4",
"IAB9-25",
"IAB9-17",
"IAB23",
"IAB9-24",
"IAB9-13",
"IAB16",
"IAB9-4",
"IAB9-9",
"IAB9-20",
"IAB22",
"IAB9-28",
"IAB9-27",
"IAB9-16",
"IAB9-31",
"IAB9-3",
"IAB9-19",
"IAB10",
"IAB9-2",
"IAB9-6",
"IAB9-21",
"IAB9-10",
"IAB9-15"
\]
},
{
"id": "1jm",
"name": "Health & Pharma",
"iab_categories": \[
"IAB7"
\]
},
{
"id": "1jn",
"name": "Alcohol",
"iab_categories": \[
"IAB8-5",
"IAB8-18"
\]
},
{
"id": "1jo",
"name": "Dining",
"iab_categories": \[
"IAB8-10",
"IAB8-8",
"IAB8-7",
"IAB8-15",
"IAB8-3",
"IAB8-4",
"IAB8-1",
"IAB8-16",
"IAB8-12",
"IAB8-13",
"IAB8-17",
"IAB8-11",
"IAB8-6",
"IAB8-9",
"IAB8-2",
"IAB8-14"
\]
},
{
"id": "1jp",
"name": "Financial Services",
"iab_categories": \[
"IAB3",
"IAB13",
"IAB21"
\]
},
{
"id": "1jq",
"name": "Retail",
"iab_categories": \[
"IAB18"
\]
},
{
"id": "1jr",
"name": "Travel",
"iab_categories": \[
"IAB20"
\]
},
{
"id": "1js",
"name": "Gaming",
"iab_categories": \[
"IAB9-30"
\]
},
{
"id": "1jt",
"name": "Technology",
"iab_categories": \[
"IAB19-22",
"IAB19-13",
"IAB19-4",
"IAB19-33",
"IAB19-26",
"IAB19-3",
"IAB19-16",
"IAB19-9",
"IAB19-32",
"IAB19-25",
"IAB19-30",
"IAB19-36",
"IAB19-21",
"IAB5",
"IAB19-12",
"IAB19-28",
"IAB19-17",
"IAB19-8",
"IAB19-7",
"IAB19-24",
"IAB15",
"IAB19-11",
"IAB19-31",
"IAB19-20",
"IAB19-15",
"IAB19-1",
"IAB19-35",
"IAB19-29",
"IAB19-34",
"IAB19-23",
"IAB19-2",
"IAB19-5",
"IAB19-14",
"IAB19-27",
"IAB19-10",
"IAB19-19"
\]
},
{
"id": "1ju",
"name": "Telecommunication",
"iab_categories": \[
"IAB19-6",
"IAB19-18"
\]
},
{
"id": "1jv",
"name": "Auto",
"iab_categories": \[
"IAB2"
\]
},
{
"id": "1jw",
"name": "Media & Entertainment",
"iab_categories": \[
"IAB14-8",
"IAB14-4",
"IAB1-5",
"IAB14-7",
"IAB1-7",
"IAB17",
"IAB14-3",
"IAB1-1",
"IAB12",
"IAB1-6",
"IAB25-1",
"IAB1-2",
"IAB14-2",
"IAB14-6",
"IAB1-3",
"IAB1-4",
"IAB14-5"
\]
},
{
"id": "1jx",
"name": "Politics",
"iab_categories": \[
"IAB11-4"
\]
},
{
"id": "1jy",
"name": "Gambling",
"iab_categories": \[
"IAB9-7"
\]
},
{
"id": "1jz",
"name": "Dating",
"iab_categories": \[
"IAB14-1"
\]
},
{
"id": "1k0",
"name": "Non-Profit",
"iab_categories": \[
"IAB11-1",
"IAB11-2",
"IAB11-3",
"IAB11-5"
\]
}
\]
}
```
Now, in order to set the `categories` parameter to "Science & Education", the entire set of `iab_categories` i.e., `"IAB5", "IAB15"` must be set for the line item, like so:
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/accounts/55w3kv/line\_items?campaign\_id=f2rp3&bid\_amount\_local\_micro=5500000&name=curated-category-line-item&product\_type=MEDIA&placements=ALL\_ON\_TWITTER&objective=PREROLL_VIEWS&categories=IAB3,IAB13,IAB21
{
"request": {
"params": {
"name": "curated-category-line-item",
"placements": \[
"ALL\_ON\_TWITTER"
\],
"bid\_amount\_local_micro": 5500000,
"product_type": "MEDIA",
"objective": "PREROLL_VIEWS",
"account_id": "55w3kv",
"categories": \[
"IAB3",
"IAB13",
"IAB21"
\],
"campaign_id": "f2rp3"
}
},
"data": {
"bid_type": "MAX",
"advertiser\_user\_id": 312226591,
"name": "curated-category-line-item",
"placements": \[
"ALL\_ON\_TWITTER"
\],
"start_time": null,
"bid\_amount\_local_micro": 5500000,
"automatically\_select\_bid": false,
"advertiser_domain": null,
"target\_cpa\_local_micro": null,
"raw_categories": \[
"x",
"5l",
"9z"
\],
"primary\_web\_event_tag": null,
"charge\_by": "VIEW\_3S_100PCT",
"product\_type": "PROMOTED\_TWEETS",
"end_time": null,
"duration\_in\_days": null,
"bid\_unit": "VIEW\_3S_100PCT",
"total\_budget\_amount\_local\_micro": null,
"objective": "PREROLL_VIEWS",
"id": "iqwka",
"entity_status": "ACTIVE",
"automatic\_tweet\_promotion": null,
"optimization": "DEFAULT",
"frequency_cap": null,
"android\_app\_store_identifier": null,
"categories": \[
"IAB3",
"IAB13",
"IAB21"
\],
"currency": "USD",
"created_at": "2021-02-09T00:00:46Z",
"tracking_tags": \[\],
"ios\_app\_store_identifier": null,
"amplify_config": {
"auto_promote": true,
"is_open": true
},
"updated_at": "2021-02-09T00:00:46Z",
"campaign_id": "f2rp3",
"creative_source": "MANUAL",
"deleted": false
}
}
```
#### Publisher Selection
An advertiser may choose to target either a Content Category or a Curated Category, with additional details described below.
**Note:** Line items may target either Curated or Content Categories but not both.
### Curated Categories
Curated Categories allow advertisers to target a preset group of publishers and can be retrieved using the [GET curated\_categories](/x-ads-api/campaign-management/reference#curated-categories-2) endpoint. These categories are country specific, and therefore require that the line item target the appropriate country based on the country\_code of the category.
In order to use one of these categories, the following steps are required in the specific order listed:
1. The line item needs to target the appropriate country based on the country\_code of the Curated Category
2. The [POST line\_item\_curated\_categories](/x-ads-api/campaign-management/reference#line-item-curated-categories) endpoint must be used to associate the line item with a specific curated\_category\_id.
**Note:** Associating a line item with a curated category will also limit the number of publishers that can be denylisted to 5. The full list of user\_id used to denylist specific publishers can be retrieved from the [GET publishers](/x-ads-api/campaign-management/reference#publishers) endpoint. Additionally, a given line item may target no more than one Curated Category at a time.
The following example illustrates how to associate a curated category id: b0xt which is only available in the US, with the line item created in the previous step.
First, the line item’s targeting criteria is set to the value 96683cc9126741d
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
GET https://ads-api.x.com/8/targeting\_criteria/locations?country\_code=US&location_type=COUNTRIES
{
"data": \[
{
"name": "United States",
"country_code": "US",
"location_type": "COUNTRIES",
"targeting_value": "96683cc9126741d1",
"targeting_type": "LOCATION"
}
\],
"request": {
"params": {
"location_type": "COUNTRIES",
"country_code": "US"
}
},
"next_cursor": null
}
POST https://ads-api.x.com/8/batch/accounts/55w3kv/targeting_criteria
\[
{
"operation_type": "Create",
"params": {
"line\_item\_id": "iqwka",
"targeting_type": "LOCATION",
"targeting_value": "96683cc9126741d1",
"operator_type": "EQ"
}
}
\]
{
"data": \[
{
"line\_item\_id": "iqwka",
"name": "United States",
"raw_negated": false,
"raw\_targeting\_value": "2",
"id": "rv9hmc",
"raw\_targeting\_type": "GEO",
"raw\_operator\_type": "EQUAL_TO",
"location_type": "COUNTRIES",
"operator_type": "EQ",
"created_at": "2021-02-09T00:06:28Z",
"targeting_value": "96683cc9126741d1",
"updated_at": "2021-02-09T00:06:28Z",
"deleted": false,
"targeting_type": "LOCATION"
}
\],
"request": \[
{
"params": {
"line\_item\_id": "iqwka",
"account_id": "55w3kv",
"operator_type": "EQ",
"targeting_value": "96683cc9126741d1",
"targeting_type": "LOCATION"
},
"operation_type": "Create"
}
\]
}
POST https://ads-api.x.com/8/accounts/55w3kv/line\_item\_curated\_categories?line\_item\_id=iqwka&curated\_category_id=9ddrgesiap6o
{
"request": {
"params": {
"curated\_category\_id": "9ddrgesiap6o",
"line\_item\_id": "iqwka",
"account_id": "55w3kv"
}
},
"data": {
"line\_item\_id": "iqwka",
"curated\_category\_id": "9ddrgesiap6o",
"id": "xq",
"created_at": "2021-03-30T17:26:42Z",
"updated_at": "2021-03-30T17:26:42Z",
"deleted": false
}
}
```
### Content Categories
Content categories, also referred to as Standard Categories can be retrieved from the [GET curated\_categories](/x-ads-api/campaign-management/reference#get-accounts-account-id-curated-categories) endpoint. These categories can then be targeted by the line item using the batch targeting criteria endpoints. The following example illustrates how to select a particular content category, id: sr which maps to “News & Current Events” and apply it to the line item.
**Note**: The entire set of iab\_categories in the [GET curated\_categories](/x-ads-api/campaign-management/reference#get-accounts-account-id-curated-categories) response must be targeted via the targeting criteria endpoint. Failing to do so will result in a validation error.
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
GET https://ads-api.x.com/8/content_categories
{
"name": "News & Current Events",
"id": "sr",
"iab_categories": \[
"IAB12",
"IAB14"
\],
"publishers\_in\_last\_thirty\_days": 124,
"videos\_monetized\_in\_last\_thirty_days": 5429
}
}
POST https://ads-api.x.com/8/batch/accounts/55w3kv/targeting_criteria
\[
{
"operation_type": "Create",
"params": {
"line\_item\_id": "iqwls",
"targeting\_type": "IAB\_CATEGORY",
"targeting_value": "IAB12",
"operator_type": "EQ"
}
},
{
"operation_type": "Create",
"params": {
"line\_item\_id": "iqwls",
"targeting\_type": "IAB\_CATEGORY",
"targeting_value": "IAB14",
"operator_type": "EQ"
}
}
\]
{
"data": \[
{
"line\_item\_id": "iqwls",
"name": "News",
"raw_negated": false,
"raw\_targeting\_value": "5h",
"id": "saib9p",
"raw\_targeting\_type": "IAB_CATEGORY",
"raw\_operator\_type": "EQUAL_TO",
"operator_type": "EQ",
"created_at": "2021-03-30T17:35:50Z",
"targeting_value": "IAB12",
"updated_at": "2021-03-30T17:35:50Z",
"deleted": false,
"targeting\_type": "IAB\_CATEGORY"
},
{
"line\_item\_id": "iqwls",
"name": "Society",
"raw_negated": false,
"raw\_targeting\_value": "5y",
"id": "saib9q",
"raw\_targeting\_type": "IAB_CATEGORY",
"raw\_operator\_type": "EQUAL_TO",
"operator_type": "EQ",
"created_at": "2021-03-30T17:35:50Z",
"targeting_value": "IAB14",
"updated_at": "2021-03-30T17:35:50Z",
"deleted": false,
"targeting\_type": "IAB\_CATEGORY"
}
\],
"request": \[
{
"params": {
"line\_item\_id": "iqwls",
"account_id": "55w3kv",
"operator_type": "EQ",
"targeting_value": "IAB12",
"targeting\_type": "IAB\_CATEGORY"
},
"operation_type": "Create"
},
{
"params": {
"line\_item\_id": "iqwls",
"account_id": "55w3kv",
"operator_type": "EQ",
"targeting_value": "IAB14",
"targeting\_type": "IAB\_CATEGORY"
},
"operation_type": "Create"
}
\]
}
```
##### Associate the account media (video) with the line item
Use the [POST accounts/:account\_id/media\_creatives](/x-ads-api/campaign-management/reference#post-accounts-account-id-media-creatives) endpoint to associate the video with an ad group.
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/accounts/55w3kv/media_creatives
line\_item\_id=4bii5&account\_media\_id=knb
{
"data":{
"account\_media\_id":"74g",
"approval_status":"ACCEPTED",
"created_at":"2016-02-11T22:23:23Z",
"deleted":false,
"id":"qeq",
"landing_url":null,
"line\_item\_id":"4bii5",
"serving_status":"ACTIVE",
"updated_at":"2016-02-11T22:23:23Z"
},
"request":{
"params":{
"line\_item\_id":"4bii5",
"account\_media\_id":"knb"
}
}
}
```
#### Set the CTA and destination URL
It is important to note that unlike most other campaigns on X, the `VIDEO_VIEWS_PREROLL` objective does not utilize Promoted Tweets or Cards. Instead, the video creative is associated with your ad group (line item) and the CTA information is associated with a `preroll_call_to_action` entity. The [POST accounts/:account\_id/preroll\_call\_to\_action](/x-ads-api/creatives/reference#preroll-call-to-actions) endpoint allows you to control the button CTA and the destination URL.
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/accounts/55w3kv/preroll\_call\_to_action
line\_item\_id=4bii5&call\_to\_action=VISIT\_SITE&call\_to\_action\_url=https%3A%2F%2Fx.com%2FAdsAPI
{
"data":{
"id":"aaa111",
"line\_item\_id":"4bii5",
"call\_to\_action":"WATCH_NOW",
"call\_to\_action_url":"https://x.com/AdsAPI",
"created_at":"2016-02-11T22:23:23Z",
"updated_at":"2016-02-11T22:23:23Z",
"deleted":false
},
"request":{
"params":{
"line\_item\_id":"4bii5",
"call\_to\_action":"VISIT_SITE",
"call\_to\_action_url":"https://x.com/AdsAPI"
}
}
}
```
#### Set targeting criteria
The targeting criterion utilized for pre-roll video ads is only available using our batch targeting criteria endpoint [POST batch/accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#post-batch-accounts-account-id-targeting-criteria).
Use `CONTENT_PUBLISHER_USER` as negated targeting to exclude the ad from being paired with a set of users. Provide the X `user_id` or publisher\_user\_id for the handles to exclude.
The [GET publishers](/x-ads-api/campaign-management/reference#publishers) endpoint can be used to retrieve the list of user\_id to exclude for Content Categories. The publisher\_user\_id returned in the [GET curated\_categories](/x-ads-api/campaign-management/reference#curated-categories-2) response can be used to retrieve a similar exclusion list for Curated Categories.
**Note:** A maximum of 5 publisher\_user\_id can be excluded for Curated Categories and 50 user\_id for Content Categories.
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
POST https://ads-api.x.com/8/batch/accounts/55w3kv/targeting_criteria
\[
{
"operation_type": "Create",
"params": {
"line\_item\_id": "iqwls",
"targeting\_type": "CONTENT\_PUBLISHER_ID",
"targeting_value": "1917731",
"operator_type": "NE"
}
}
\]
{
"data": \[
{
"line\_item\_id": "iqwka",
"name": "realsaltlake",
"raw_negated": true,
"raw\_targeting\_value": "aajwo",
"id": "sajk32",
"raw\_targeting\_type": "CONTENT_PUBLISHER",
"raw\_operator\_type": "EQUAL_TO",
"operator_type": "NE",
"created_at": "2021-03-30T18:02:32Z",
"targeting_value": 17288520,
"updated_at": "2021-03-30T18:02:32Z",
"deleted": false,
"targeting\_type": "CONTENT\_PUBLISHER_USER"
}
\],
"request": \[
{
"params": {
"line\_item\_id": "iqwka",
"account_id": "55w3kv",
"operator_type": "NE",
"targeting_value": "17288520",
"targeting\_type": "CONTENT\_PUBLISHER_USER"
},
"operation_type": "Create"
}
\]
}
```
#### Launch campaign
When you’re ready to launch your campaign, simply un-pause using [PUT accounts/:account\_id/campaigns/:id](/x-ads-api/campaign-management/reference#put-accounts-account-id-line-items-line-item-id).
PUT [https://ads-api.x.com/8/accounts/55w3kv/campaigns/f2rp3](https://ads-api.x.com/8/accounts/55w3kv/campaigns/f2rp3)?
entity\_status=ACTIVE
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"campaign_id": "f2rp3",
"account_id": "55w3kv"
}
},
"data": {
"name": "test-curated-categories-api",
"start_time": "2021-02-10T00:00:00Z",
"reasons\_not\_servable": \[
\],
"servable": false,
"purchase\_order\_number": null,
"effective_status": "ACTIVE",
"daily\_budget\_amount\_local\_micro": 55000000,
"end_time": null,
"funding\_instrument\_id": "103hp9",
"duration\_in\_days": null,
"standard_delivery": true,
"total\_budget\_amount\_local\_micro": null,
"id": "f2rp3",
"entity_status": "ACTIVE",
"frequency_cap": null,
"currency": "USD",
"created_at": "2021-02-08T23:55:38Z",
"updated_at": "2021-02-08T23:55:38Z",
"deleted": false
}
}
```
#### Analytics
Analytics for `VIDEO_VIEWS_PREROLL` campaigns are available using our stats endpoints.
### Keyword Targeting in Timelines
Keyword targeting is fundamental to our Promoted Tweets products, giving campaigns better reach. Keyword targeting in timeline enables platforms to target X users based on keywords in their recent Tweets. For example, if an advertiser is targeting the unordered keyword combination “plan + trip”, and a user Tweets, “I’m starting to plan my trip to Cabo, any suggestions?” while the campaign is running, that user may soon afterward see the advertiser’s Promoted Tweet.
#### How does it work?
TL;DR: from an API standpoint, this change is quite simple: you can now target keywords on Promoted Tweets in Timeline. Just set the `targeting_type` to `unordered_keywords` or `phrase_keywords` for line items.
#### Quick Start Guide
* Create a new line item with the placement set to include either `ALL_ON_TWITTER` or `TWITTER_TIMELINE` [POST accounts/:account\_id/line\_items](https://dev.x.com/ads/reference/post/accounts/%3Aaccount_id/line_items)
* Create the targeting criteria for this newly created line item with either `BROAD_KEYWORD` and set your keyword value(s). [POST accounts/:account\_id/targeting\_criteria](https://dev.x.com/ads/reference/post/accounts/%3Aaccount_id/targeting_criteria)
* You can update the keywords with [PUT accounts/:account\_id/targeting\_criteria](https://dev.x.com/ads/reference/put/accounts/%3Aaccount_id/targeting_criteria)
* Once your campaign is running, get the stats on your line item to gauge performance. [GET stats/accounts/:account\_id](https://dev.x.com/ads/reference/get/stats/accounts/%3Aaccount_id)
***
## Full API Reference
For the complete list of endpoints with request/response examples and attribute tables, see the **[Campaign Management API Reference](/x-ads-api/campaign-management/reference)** page.
# Campaign Management API Reference
Source: https://docs.x.com/x-ads-api/campaign-management/reference
Endpoint reference for the X Ads Campaign Management API covering accounts, campaigns, line items, funding instruments, and targeting criteria requests.
## API Reference
This is the full technical reference. For an overview of campaigns, line items, budgeting, targeting concepts, and a step-by-step getting started guide, see the
Campaign Management Overview.
### Accounts
#### GET accounts[](#get-accounts "Permalink to this headline")
Retrieve details for some or all advertising-enabled accounts the authenticating user has access to.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts`
Scope the response to just the desired account IDs by specifying a comma-separated list of identifiers.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope resource by `name`. Performs case-insensitive prefix matching.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
```json theme={null}
GET https://ads-api.x.com/12/accounts?account_ids=18ce54d4x5t
```
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_ids": [
"18ce54d4x5t"
]
}
},
"next_cursor": null,
"data": [
{
"name": "API McTestface",
"business_name": null,
"timezone": "America/Los_Angeles",
"timezone_switch_at": "2016-07-21T07:00:00Z",
"id": "18ce54d4x5t",
"created_at": "2016-07-21T22:42:09Z",
"updated_at": "2017-07-06T16:51:04Z",
"business_id": null,
"approval_status": "ACCEPTED",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id[](#get-accounts-account-id "Permalink to this headline")
Retrieve a specific account that the authenticating user has access to.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "API McTestface",
"business_name": null,
"timezone": "America/Los_Angeles",
"timezone_switch_at": "2016-07-21T07:00:00Z",
"id": "18ce54d4x5t",
"created_at": "2016-07-21T22:42:09Z",
"updated_at": "2017-07-06T16:51:04Z",
"industry_type": "TRAVEL",
"business_id": null,
"approval_status": "ACCEPTED",
"deleted": false
}
}
```
#### POST accounts[](#post-accounts "Permalink to this headline")
Note: **SANDBOX ONLY**
Create an ads account in the sandbox environment.
**SANDBOX ONLY**
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts`
**Parameters**
None
**Example Request**
`POST https://ads-api-sandbox.x.com/12/accounts`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {}
},
"next_cursor": null,
"data": [
{
"name": "Sandbox account",
"business_name": null,
"timezone": "America/Los_Angeles",
"timezone_switch_at": null,
"id": "gq12fh",
"created_at": "2016-07-18T23:02:20Z",
"updated_at": "2016-07-18T23:02:20Z",
"business_id": null,
"approval_status": "ACCEPTED",
"deleted": false
}
]
}
```
#### PUT accounts/:account\_id[](#put-accounts-account-id "Permalink to this headline")
Updates the account name and/or industry type.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The name of the account.
Industry that the account is associated with.
Possible values: `AGENCY`, `BUSINESS_TO_BUSINESS`, `ONLINE_SERVICES`, `EDUCATION`, `FINANCIAL`, `HEALTH`, `GOVERNMENT`, `MEDIA`, `MOBILE`, `RESTAURANT`, `RETAIL`, `TECHNOLOGY`, `TRAVEL`, `OTHER`
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t?name='API McTestface 2'&industry_type=TECHNOLOGY`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
"name"": "API McTestface 2",
"industry_type": "TECHNOLOGY"
}
},
"data": {
"name": "API McTestface 2",
"business_name": null,
"timezone": "America/Los_Angeles",
"timezone_switch_at": "2016-07-21T07:00:00Z",
"id": "18ce54d4x5t",
"created_at": "2016-07-21T22:42:09Z",
"updated_at": "2017-07-06T16:51:04Z",
"industry_type": "TECHNOLOGY",
"business_id": null,
"approval_status": "ACCEPTED",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id[](#delete-accounts-account-id "Permalink to this headline")
**SANDBOX ONLY**
Delete an ads account in the sandbox environment.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts/:account_id`
**Parameters**
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
**Example Request**
`DELETE https://ads-api-sandbox.x.com/12/accounts/gq12fh`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"name": "Sandbox account",
"timezone": "America/Los_Angeles",
"timezone_switch_at": null,
"id": "gq12fh",
"created_at": "2016-07-18T23:02:20Z",
"updated_at": "2017-08-23T18:21:10Z",
"approval_status": "ACCEPTED",
"deleted": true
},
"request": {
"params": {
"account_id": "gq12fh"
}
}
}
```
### Account Apps
[Run in Postman ❯](https://app.getpostman.com/run-collection/1d12b9fc623b8e149f87)
#### GET account\_apps[](#get-account-apps "Permalink to this headline")
Retrieve details for all mobile apps that are associated with the specified ad account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/account_apps`
**Parameters[](#parameters "Permalink to this headline")**
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request. Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/account_apps`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_ids": [
"18ce54d4x5t"
]
}
},
"next_cursor": null,
"data": [
{
"app_store_identifier": "com.twitter.android",
"conversion_tracking_enabled": false,
"deep_link_pattern": "twitter://",
"id": "4x",
"created_at": "2019-06-20T22:36:16Z",
"updated_at": "2021-10-19T20:05:29Z",
"os_type": "Android",
"deleted": false
}
]
}
```
### Account History
#### GET accounts/:account\_id/account\_history[](#get-accounts-account-id-account-history "Permalink to this headline")
Retrieve a summary of changes made to the `entity_id` specified in the request.
This endpoint is currently in beta and requires allowlisting.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/account_history`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
The entity type to retrieve data for.
Possible values: `CAMPAIGN`, `LINE_ITEM`, `PROMOTED_TWEET`, `TARGETING_CRITERIA`, `PROMOTED_ACCOUNT`
The specific entity to retrieve data for.
Scopes the retrieved data to the specified start time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Scopes the retrieved data to the specified end time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
**Note**: Must be expressed in whole hours (0 minutes and 0 seconds).
Scopes the response to a specific user.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/account_history?entity_type=CAMPAIGN&entity_id=fc3h5&count=1`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"entity": "CAMPAIGN",
"entity_id": "fc3h5",
"count": 1
}
},
"next_cursor": "1r2407sb4lc",
"data": [
{
"change_by": {
"user_id": "982978172",
"platform": "API_OTHER"
},
"changes": {},
"change_time": "2021-04-02T20:55:42Z",
"entity_id": "fc3h5",
"entity": "CAMPAIGN",
"entity_data": {
"name": "test_campaign",
"start_time": "2021-04-02T18:59:11Z",
"purchase_order_number": null,
"daily_budget_amount_local_micro": 100000000,
"end_time": null,
"duration_in_days": null,
"standard_delivery": true,
"total_budget_amount_local_micro": 100000000,
"entity_status": "ACTIVE",
"frequency_cap": null,
"created_at": "2021-04-02T20:55:42Z",
"updated_at": "2021-04-02T20:55:42Z",
"deleted": false
},
"change_type": "CREATE"
}
]
}
```
### Advertiser Business Categories
#### GET advertiser\_business\_categories[](#get-advertiser-business-categories "Permalink to this headline")
Request the valid advertiser business `categories` for Ad Groups (`line_items`) to describe an advertiser's brand to publishers.
These categories apply only to `line_items` with the `PREROLL_VIEWS` objective and are separate from the `content_categories` used for targeting criteria.
Each `advertiser_business_categories` represents a collection of [IAB Categories](/x-ads-api/campaign-management/reference#iab-categories). When creating an Ad Group with the `PREROLL_VIEWS` objective, one or two `advertiser_business_categories` must be set for the Ad Group. This can be done by setting the value of the `categories` request parameter on the [line item](/x-ads-api/campaign-management/reference#line-items) endpoint to the set of corresponding `iab_categories` available through this endpoint.
Additional details can be found in the [Video Views Preroll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective)
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/advertiser_business_categories`
**Parameters[](#parameters "Permalink to this headline")**
No request parameters
**Example Request**
`GET https://ads-api.x.com/12/advertiser_business_categories`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {}
},
"next_cursor": null,
"data": [
{
"id": "1jl",
"name": "Consumer Packaged Goods",
"iab_categories": [
"IAB9-26",
"IAB9-18",
"IAB9-29",
"IAB9-1",
"IAB9-8",
"IAB9-22",
"IAB6",
"IAB9-5",
"IAB9-12",
"IAB9-11",
"IAB9-23",
"IAB9-14",
"IAB4",
"IAB9-25",
"IAB9-17",
"IAB23",
"IAB9-24",
"IAB9-13",
"IAB16",
"IAB9-4",
"IAB9-9",
"IAB9-20",
"IAB22",
"IAB9-28",
"IAB9-27",
"IAB9-16",
"IAB9-31",
"IAB9-3",
"IAB9-19",
"IAB10",
"IAB9-2",
"IAB9-6",
"IAB9-21",
"IAB9-10",
"IAB9-15"
]
},
{
"id": "1jm",
"name": "Health & Pharma",
"iab_categories": [
"IAB7"
]
},
{
"id": "1jn",
"name": "Alcohol",
"iab_categories": [
"IAB8-5",
"IAB8-18"
]
},
{
"id": "1jo",
"name": "Dining",
"iab_categories": [
"IAB8-10",
"IAB8-8",
"IAB8-7",
"IAB8-15",
"IAB8-3",
"IAB8-4",
"IAB8-1",
"IAB8-16",
"IAB8-12",
"IAB8-13",
"IAB8-17",
"IAB8-11",
"IAB8-6",
"IAB8-9",
"IAB8-2",
"IAB8-14"
]
},
{
"id": "1jp",
"name": "Financial Services",
"iab_categories": [
"IAB3",
"IAB13",
"IAB21"
]
},
{
"id": "1jq",
"name": "Retail",
"iab_categories": [
"IAB18"
]
},
{
"id": "1jr",
"name": "Travel",
"iab_categories": [
"IAB20"
]
},
{
"id": "1js",
"name": "Gaming",
"iab_categories": [
"IAB9-30"
]
},
{
"id": "1jt",
"name": "Technology",
"iab_categories": [
"IAB19-22",
"IAB19-13",
"IAB19-4",
"IAB19-33",
"IAB19-26",
"IAB19-3",
"IAB19-16",
"IAB19-9",
"IAB19-32",
"IAB19-25",
"IAB19-30",
"IAB19-36",
"IAB19-21",
"IAB5",
"IAB19-12",
"IAB19-28",
"IAB19-17",
"IAB19-8",
"IAB19-7",
"IAB19-24",
"IAB15",
"IAB19-11",
"IAB19-31",
"IAB19-20",
"IAB19-15",
"IAB19-1",
"IAB19-35",
"IAB19-29",
"IAB19-34",
"IAB19-23",
"IAB19-2",
"IAB19-5",
"IAB19-14",
"IAB19-27",
"IAB19-10",
"IAB19-19"
]
},
{
"id": "1ju",
"name": "Telecommunication",
"iab_categories": [
"IAB19-6",
"IAB19-18"
]
},
{
"id": "1jv",
"name": "Auto",
"iab_categories": [
"IAB2"
]
},
{
"id": "1jw",
"name": "Media & Entertainment",
"iab_categories": [
"IAB14-8",
"IAB14-4",
"IAB1-5",
"IAB14-7",
"IAB1-7",
"IAB17",
"IAB14-3",
"IAB1-1",
"IAB12",
"IAB1-6",
"IAB25-1",
"IAB1-2",
"IAB14-2",
"IAB14-6",
"IAB1-3",
"IAB1-4",
"IAB14-5"
]
},
{
"id": "1jx",
"name": "Politics",
"iab_categories": [
"IAB11-4"
]
},
{
"id": "1jy",
"name": "Gambling",
"iab_categories": [
"IAB9-7"
]
},
{
"id": "1jz",
"name": "Dating",
"iab_categories": [
"IAB14-1"
]
},
{
"id": "1k0",
"name": "Non-Profit",
"iab_categories": [
"IAB11-1",
"IAB11-2",
"IAB11-3",
"IAB11-5"
]
}
]
}
```
### Audience Estimate
POST accounts/:account\_id/audience\_estimate[](#post-accounts-account-id-audience-estimate "Permalink to this headline")
#### Determine the approximate audience size of your campaigns.
This endpoint accepts an array of JSON objects containing the parameters for the targeting criteria objects. A list of required and optional targeting criteria parameters are available on the [POST accounts/:account\_id/targeting\_criteria](/x-ads-api/campaign-management/reference#post-accounts-account-id-targeting-criteria) endpoint. Requests must be HTTP POST with a JSON content body with a `Content-Type: application/json` header.
**Note**: It is required that you specify at least one **primary** targeting criterion; you can see a list of all primary targeting criteria in our [campaigns targeting page](/x-ads-api/campaign-management/reference#targeting).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/audience_estimate`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
An array of targeting criteria objects. A list of required and optional targeting criteria parameters are available on the POST targeting criteria endpoint.
Specify the relationship that the targeting criterion should have. For example, to set negated targeting, use `operator_type=NE`.
Possible values: `EQ`, `NE`
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/audience_estimate`
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"targeting_criteria": [
{
"targeting_type": "BROAD_KEYWORD",
"targeting_value": "nba",
"operator_type": "EQ"
},
{
"targeting_type": "BROAD_KEYWORD",
"targeting_value": "tech",
"operator_type": "NE"
},
{
"targeting_type": "LOCATION",
"targeting_value": "96683cc9126741d1",
"operator_type": "EQ"
},
{
"targeting_type": "SIMILAR_TO_FOLLOWERS_OF_USER",
"targeting_value": "14230524"
},
{
"targeting_type": "SIMILAR_TO_FOLLOWERS_OF_USER",
"targeting_value": "90420314"
}
]
}
```
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"targeting_criteria": null,
"account_id": "18ce54d4x5t"
}
},
"data": {
"audience_size": {
"min": 38236294,
"max": 42261167
}
}
}
```
### Authenticated User Access
#### GET accounts/:account\_id/authenticated\_user\_access[](#get-accounts-account-id-authenticated-user-access "Permalink to this headline")
Retrieve the permissions of the currently authenticated user (access\_token) as they relate to the specified ads account. These permissions match those exposed on ads.x.com.
Possible values include:
* `ACCOUNT_ADMIN`: Full access to modify campaigns and view stats, including the ability to add or remove users and change settings
* `AD_MANAGER`: Full access to modify campaigns and view stats, but cannot add or remove users or change settings
* `CREATIVE_MANAGER`: Access to modify creatives and view previews, but no access to create or modify campaigns
* `CAMPAIGN_ANALYST`: Access to view campaigns and view stats, but no access to create or modify campaigns
* `ANALYST` ("Organic Analyst" on ads.x.com): Access to view organic analytics and audience insights, but no access to create, modify, or view campaigns
* `PARTNER_AUDIENCE_MANAGER`: API-only access to view and modify data partner audiences, but no access to campaigns, creatives, or other audience types.
In addition, the `TWEET_COMPOSER` permission indicates that the authenticated user can create nullcasted (or "Promoted-only") Tweets on behalf of the advertiser. This is only available for users with `ACCOUNT_ADMIN`, `AD_MANAGER`, or `CREATIVE_MANAGER` access.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/authenticated_user_access`
**Parameters[](#parameters "Permalink to this headline")**
None
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/authenticated_user_access`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"user_id": "2417045708",
"permissions": [
"ACCOUNT_ADMIN",
"TWEET_COMPOSER"
]
},
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
}
}
```
### Bidding Rules
#### GET bidding\_rules[](#get-bidding-rules "Permalink to this headline")
Retrieve the bidding rules for some or all currencies. The response will indicate the minimum and maximum CPE (cost-per-engagement) bids.
While these bidding rules change rarely, it is suggested that your systems refresh from these endpoints at least monthly.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/bidding_rules`
The type of a currency to filter results by, identified using [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217). This is a three-letter string "USD" or "EUR". Omit this parameter to retrieve all bidding rules associated with the authenticating user.
**Example Request**
`GET https://ads-api.x.com/12/bidding_rules?currency=USD`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"currency": "USD"
}
},
"data_type": "bidding_rule",
"data": [
{
"currency": "USD",
"minimum_cpe_bid_local_micro": 10000,
"maximum_cpe_bid_local_micro": 1000000000,
"minimum_denomination": 10000
}
],
"total_count": 1
}
```
### Campaigns
#### GET accounts/:account\_id/campaigns[](#get-accounts-account-id-campaigns "Permalink to this headline")
Retrieve details for some or all campaigns associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/campaigns`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired campaigns by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the campaigns under specific funding instruments by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
An optional query to scope resource by `name`.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include draft campaigns results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns?campaign_ids=8wku2`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"campaign_ids": [
"8wku2"
]
}
},
"next_cursor": null,
"data": [
{
"name": "test",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [
"PAUSED_BY_ADVERTISER",
"INCOMPLETE"
],
"servable": false,
"purchase_order_number": null,
"effective_status": "UNKNOWN",
"daily_budget_amount_local_micro": 10000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "8wku2",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:38:07Z",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/campaigns/:campaign\_id[](#get-accounts-account-id-campaigns-campaign-id "Permalink to this headline")
Retrieve a specific campaign associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/campaigns/:campaign_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the campaign you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns/8wku2`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"campaign_id": "8wku2",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "test",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [
"PAUSED_BY_ADVERTISER",
"INCOMPLETE"
],
"servable": false,
"purchase_order_number": null,
"effective_status": "UNKNOWN",
"daily_budget_amount_local_micro": 10000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "8wku2",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:38:07Z",
"deleted": false
}
}
```
#### POST accounts/:account\_id/campaigns[](#post-accounts-account-id-campaigns "Permalink to this headline")
Create a new campaign associated with the current account.
**Note**: There is a default limit of 200 active campaigns per account. However, there is no limit to the number of inactive campaigns. This limit can be raised to 8,000 active campaigns. To enable the higher limit, the advertiser must make the request to their X Account Manager.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/campaigns`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The identifier for the funding instrument to create the campaign under.
The name for the campaign. Maximum length: 255 characters.
Select the type of budget optimization to be applied.
Possible values: `LINE_ITEM`
The daily budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000.
**Note**: This should be less than or equal to the `total_budget_amount_local_micro` and is required for most Funding Instrument types.
The campaign status.
Possible values: `ACTIVE`, `DRAFT`, `PAUSED`
The booking reference number. Use this field to help with invoice reconciliation. Maximum length: 50 characters.
**Deprecated at the campaign level.** Since budget optimization is always `LINE_ITEM`, standard versus accelerated delivery is configured on the line item via its `standard_delivery` parameter. See [Budget Pacing](/x-ads-api/campaign-management#budget-pacing) for more information.
The total budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$37.50 is represented as 37500000.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns?funding_instrument_id=lygyi&name=demo&daily_budget_amount_local_micro=140000000&entity_status=PAUSED&budget_optimization=LINE_ITEM`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"name": "demo",
"budget_optimization": "LINE_ITEM",
"daily_budget_amount_local_micro": 140000000,
"funding_instrument_id": "lygyi",
"entity_status": "PAUSED",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "demo",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [
"PAUSED_BY_ADVERTISER",
"INCOMPLETE"
],
"servable": false,
"purchase_order_number": null,
"effective_status": "UNKNOWN",
"daily_budget_amount_local_micro": 140000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "hwtbm",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:38:07Z",
"deleted": false
}
}
```
#### POST batch/accounts/:account\_id/campaigns[](#post-batch-accounts-account-id-campaigns "Permalink to this headline")
Allows the batch creation of new [campaigns](#post-accounts-account-id-campaigns) with a single request.
**Batch Requests**
* The current maximum batch size is 40.
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
Batch API responses return an ordered collection of items. Otherwise, they are identical in structure to their corresponding single-item endpoints.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required campaign parameter) are shown in the response under the `operation_errors` object.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/batch/accounts/:account_id/campaigns`
The per item operation type being performed.
Possible values: `Create`, `Delete`, `Update`
A JSON object containing all the parameters for the campaign objects. For a list of required and optional campaign parameters, see the single POST endpoint above.
**Example Request**
`POST 'Content-Type: application/json' https://ads-api.x.com/12/batch/accounts/18ce54d4x5t/campaigns`
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
[
{
"operation_type":"Create",
"params":{
"name":"batch campaigns",
"funding_instrument_id":"lygyi",
"daily_budget_amount_local_micro":140000000,
"entity_status":"PAUSED",
"budget_optimization":"LINE_ITEM"
}
}
]
```
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "batch campaigns",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [
"PAUSED_BY_ADVERTISER",
"INCOMPLETE"
],
"servable": false,
"purchase_order_number": null,
"effective_status": "UNKNOWN",
"daily_budget_amount_local_micro": 140000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "8yn7m",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:38:07Z",
"deleted": false
}
],
"request": [
{
"params": {
"name": "batch campaigns",
"funding_instrument_id": "lygyi",
"daily_budget_amount_local_micro": 140000000,
"entity_status": "PAUSED",
"budget_optimization":"LINE_ITEM",
"account_id": "18ce54d4x5t"
},
"operation_type": "Create"
}
]
}
```
#### PUT accounts/:account\_id/campaigns/:campaign\_id[](#put-accounts-account-id-campaigns-campaign-id "Permalink to this headline")
Update the specified campaign associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/campaigns/:campaign_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the campaign you are operating with in the request.
Select the type of budget optimization to be applied.
Possible values: `LINE_ITEM`
The daily budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000. When not provided the campaign will spend evenly based upon total budget and for duration of campaign flight time.
**Note**: This should be less than or equal to the `total_budget_amount_local_micro`.
The campaign status.
Possible values: `ACTIVE`, `PAUSED`
The name for the campaign. Maximum length: 255 characters.
The booking reference number. Use this field to help with invoice reconciliation. Maximum length: 50 characters.
**Deprecated at the campaign level.** Since budget optimization is always `LINE_ITEM`, standard versus accelerated delivery is configured on the line item via its `standard_delivery` parameter. See [Budget Pacing](/x-ads-api/campaign-management#budget-pacing) for more information.
The total budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$37.50 is represented as 37500000.
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns/8wku2?total_budget_amount_local_micro=140000000`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"campaign_id": "8wku2",
"daily_budget_amount_local_micro": 140000000,
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "test",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [
"PAUSED_BY_ADVERTISER",
"INCOMPLETE"
],
"servable": false,
"purchase_order_number": null,
"effective_status": "UNKNOWN",
"daily_budget_amount_local_micro": 140000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "8wku2",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:53:54Z",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/campaigns/:campaign\_id[](#delete-accounts-account-id-campaigns-campaign-id "Permalink to this headline")
Delete the specified campaign belonging to the current account.
**Note**: Deleting a campaign is not reversible and subsequent attempts to delete the resource will return HTTP 404.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/campaigns/:campaign_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the campaign you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/campaigns/8yn7m`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"campaign_id": "8yn7m",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "test",
"budget_optimization": "LINE_ITEM",
"reasons_not_servable": [],
"servable": null,
"purchase_order_number": null,
"effective_status": "RUNNING",
"daily_budget_amount_local_micro": 140000000,
"funding_instrument_id": "lygyi",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"id": "8yn7m",
"entity_status": "PAUSED",
"frequency_cap": null,
"currency": "USD",
"created_at": "2022-06-03T21:38:07Z",
"updated_at": "2022-06-03T21:56:35Z",
"deleted": true
}
}
```
### Content Categories
#### GET content\_categories[](#get-content-categories "Permalink to this headline")
Request the valid content `categories` to be set as `targeting_criteria` for a line item.
Each `content_category` maps to one or more [IAB Categories](/x-ads-api/campaign-management/reference#iab-categories). This can be done by setting the `targeting_type` to `IAB_CATEGORY` on the batch `targeting_critera` endpoint to include the set of corresponding `iab_categories` returned by the `content_categories` request. Failure to do so will result in a validation error.
Publisher details for each of these content categories can be retrieved using the [GET publishers](/x-ads-api/campaign-management/reference#publishers) endpoint.
Additional details can be found in the [Video Views Pre-roll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/content_categories`
**Parameters[](#parameters "Permalink to this headline")**
No request parameters
**Example Request**
`GET https://ads-api.x.com/12/content_categories`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {}
},
"next_cursor": null,
"data": [
{
"name": "Automotive (Cars, Trucks, Racing)",
"id": "ru",
"iab_categories": [
"IAB2"
],
"publishers_in_last_thirty_days": 12,
"videos_monetized_in_last_thirty_days": 316
},
{
"name": "Comedy",
"id": "sk",
"iab_categories": [
"IAB1-4"
],
"publishers_in_last_thirty_days": 19,
"videos_monetized_in_last_thirty_days": 174
},
{
"name": "Digital Creators",
"id": "sl",
"iab_categories": [
"IAB25-1"
],
"publishers_in_last_thirty_days": 110,
"videos_monetized_in_last_thirty_days": 1257
},
{
"name": "Entertainment & Pop Culture",
"id": "sm",
"iab_categories": [
"IAB1-1",
"IAB1-2",
"IAB1-3",
"IAB1-5"
],
"publishers_in_last_thirty_days": 120,
"videos_monetized_in_last_thirty_days": 3482
},
{
"name": "Financial & Business News",
"id": "sn",
"iab_categories": [
"IAB3",
"IAB13",
"IAB21"
],
"publishers_in_last_thirty_days": 29,
"videos_monetized_in_last_thirty_days": 1461
},
{
"name": "Food & Drink",
"id": "so",
"iab_categories": [
"IAB8-8",
"IAB8-12",
"IAB8-17",
"IAB8-2",
"IAB8-3",
"IAB8-7",
"IAB8-11",
"IAB8-4",
"IAB8-14",
"IAB8-10",
"IAB8-15",
"IAB8-13",
"IAB8-9",
"IAB8-16",
"IAB8-6",
"IAB8-1"
],
"publishers_in_last_thirty_days": 24,
"videos_monetized_in_last_thirty_days": 516
},
{
"name": "Lifestyle (Fashion, Travel, Wellness)",
"id": "sp",
"iab_categories": [
"IAB16",
"IAB9-21",
"IAB9-4",
"IAB9-25",
"IAB9-8",
"IAB4",
"IAB9-3",
"IAB9-15",
"IAB7",
"IAB6",
"IAB9-11",
"IAB9-16",
"IAB9-7",
"IAB9-20",
"IAB9-24",
"IAB9-17",
"IAB9-12",
"IAB9-31",
"IAB9-27",
"IAB10",
"IAB9-10",
"IAB9-23",
"IAB9-6",
"IAB9-18",
"IAB9-13",
"IAB9-1",
"IAB9-28",
"IAB20",
"IAB9-5",
"IAB9-26",
"IAB22",
"IAB23",
"IAB9-9",
"IAB9-22",
"IAB18",
"IAB9-2",
"IAB9-19",
"IAB9-14",
"IAB9-29"
],
"publishers_in_last_thirty_days": 67,
"videos_monetized_in_last_thirty_days": 2412
},
{
"name": "Music",
"id": "sq",
"iab_categories": [
"IAB1-6"
],
"publishers_in_last_thirty_days": 31,
"videos_monetized_in_last_thirty_days": 518
},
{
"name": "News & Current Events",
"id": "sr",
"iab_categories": [
"IAB12",
"IAB14"
],
"publishers_in_last_thirty_days": 125,
"videos_monetized_in_last_thirty_days": 5507
},
{
"name": "Politics",
"id": "s4",
"iab_categories": [
"IAB11"
],
"publishers_in_last_thirty_days": 19,
"videos_monetized_in_last_thirty_days": 1402
},
{
"name": "Science & Education",
"id": "ss",
"iab_categories": [
"IAB5",
"IAB15"
],
"publishers_in_last_thirty_days": 7,
"videos_monetized_in_last_thirty_days": 132
},
{
"name": "Sports",
"id": "se",
"iab_categories": [
"IAB17"
],
"publishers_in_last_thirty_days": 403,
"videos_monetized_in_last_thirty_days": 18281
},
{
"name": "Technology",
"id": "sg",
"iab_categories": [
"IAB19"
],
"publishers_in_last_thirty_days": 13,
"videos_monetized_in_last_thirty_days": 1089
},
{
"name": "Television",
"id": "sh",
"iab_categories": [
"IAB1-7"
],
"publishers_in_last_thirty_days": 58,
"videos_monetized_in_last_thirty_days": 1307
},
{
"name": "Esports & Video Games",
"id": "s0",
"iab_categories": [
"IAB9-30"
],
"publishers_in_last_thirty_days": 109,
"videos_monetized_in_last_thirty_days": 1844
}
],
"total_count": 15
}
```
### Curated Categories
#### GET accounts/:account\_id/curated\_categories[](#get-accounts-account-id-curated-categories "Permalink to this headline")
Retrieve a list of available Curated Categories for the given `country_codes`
Each `curated_category` is only available in specific countries specified by the `country_codes` in the response.
Additional details can be found in the [Video Views Pre-roll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/curated_categories`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired countries by specifying a comma-separated list of two letter ISO country codes. Up to 200 IDs may be provided.
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/curated_categories?country_codes=US`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"country_codes": [
"US"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"name": "Basketball",
"description": "Run next to the best of everyday basketball content including college teams, professional teams, and the top sports media handles sharing on and off-season basketball video.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"20265254",
"378174762",
"900368808",
"18939563",
"18371803",
"18360370",
"770658432928079872",
"11026952",
"37085464",
"16212685",
"57422635",
"281669945",
"7117962",
"23065057",
"41688179",
"29779226",
"900280416",
"364460082",
"902030382",
"19409270",
"19077044",
"18139461",
"14992591",
"66753565",
"667563",
"16727749",
"40941404",
"18481113",
"791598918",
"16201775",
"15900167",
"45891626",
"191894553",
"2181233851",
"34352904",
"171483987",
"454122399",
"57415242",
"19263978",
"902089998",
"423540866",
"2715223320",
"22185437",
"17292143",
"55590247",
"66757066",
"22642626",
"41604618",
"87275465",
"22643259",
"32414973",
"73406718",
"20346956",
"413422891",
"45412765",
"19537303",
"459511725",
"30954864",
"21308488",
"18552281",
"19924520",
"24903350",
"851142163",
"26270913",
"20444254",
"26074296",
"6395222",
"15537451",
"28672101",
"38053254",
"24925573",
"19564719",
"18164425",
"22815383",
"20196159"
],
"id": "929wbl6ymlfk",
"created_at": "2019-11-08T21:12:47Z",
"updated_at": "2021-03-09T20:36:44Z",
"videos_monetized_in_last_thirty_days": 2446
},
{
"name": "Gaming Personalities",
"description": "Run next to the best of everyday gaming content exclusively from a list of some of online gaming’s biggest and most loved digital creators.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"90779436",
"268270621",
"567167802",
"246596682",
"474919140",
"284422688",
"185909682",
"4767225325",
"2559865245",
"186888760",
"161418822",
"141021153",
"352881953",
"1117931702",
"146556805",
"357294577",
"234526497",
"266687361",
"214201922",
"9451052",
"2163885564",
"2231422037",
"116952434",
"399909209",
"15993650",
"974356091193741312",
"210839744",
"2313002094",
"159916388",
"3258981481",
"231992478",
"182236262",
"386884916",
"22705686",
"4140881832",
"995979576",
"2244953047",
"311775629",
"98821255",
"2733210014",
"2741078150"
],
"id": "94ngssfrr01x",
"created_at": "2019-12-02T20:45:12Z",
"updated_at": "2021-03-09T20:18:13Z",
"videos_monetized_in_last_thirty_days": 448
},
{
"name": "Baseball",
"description": "Run next to the best of everyday baseball content including college teams, professional teams, and the top sports media handles sharing major baseball coverage.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"22016177",
"22798877",
"52803520",
"20710218",
"423532170",
"28603812",
"41144996",
"22819823",
"39389304",
"252273678",
"123307490",
"2319354187",
"41488578",
"37947138",
"302066953",
"159143990",
"35006336",
"53178109",
"40918816",
"39682297",
"39397148",
"39419180",
"53197137",
"52863923",
"21407926",
"31164229",
"19607400",
"39392910",
"241544156",
"43024351",
"37837907",
"165764237",
"69117905",
"87673496",
"23043294",
"52824038",
"52861612",
"33137450",
"30008146",
"39367703",
"21436663",
"188575356",
"40931019",
"41468683",
"40927173",
"172742915"
],
"id": "9lav5usxfmdc",
"created_at": "2020-05-18T20:20:27Z",
"updated_at": "2021-03-09T20:37:46Z",
"videos_monetized_in_last_thirty_days": 190
},
{
"name": "Esports Teams",
"description": "Run next to the programming from the world’s best esports teams, covering both in-event coverage and other year-round complimentary programming.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"759527448757215232",
"61933836",
"477213534",
"907193396049182720",
"895382891408089089",
"862708050116976640",
"115038550",
"3182089458",
"4131266472",
"1145702070961496065",
"2262070855",
"920664872786059264",
"1035653581683220481",
"14229141",
"1101275970995027968",
"20734751",
"1452520626",
"720303639277928448",
"2853641871",
"912696400571486208",
"874362688939413504",
"286505380",
"892808605170245632",
"875087838613733376",
"238431491",
"867053221940011014",
"964529942",
"1172506293174710272",
"535756639",
"2255226817",
"1100825469853696000",
"1122713320086220803",
"1124064709295128581",
"899858978418642944",
"864977592532688896",
"864476897106898944",
"862770685445361665",
"257268592"
],
"id": "9ys3jz3ktreo",
"created_at": "2020-10-01T20:02:35Z",
"updated_at": "2021-03-09T20:36:20Z",
"videos_monetized_in_last_thirty_days": 169
},
{
"name": "Football ",
"description": "Run next to the best of everyday football content including college teams, professional teams, and the top sports media handles sharing on and off-season football video.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"21790466",
"53103297",
"23642374",
"817416193854283776",
"43403778",
"24179879",
"26813914",
"36375662",
"33587536",
"180884045",
"16332223",
"27902825",
"180503626",
"44468807",
"18336787",
"818431566",
"22146282",
"31126587",
"40358743",
"35865630",
"16347506",
"72665816",
"33583496",
"389038362",
"36155311",
"227342532",
"2151130166",
"26791995",
"44666348",
"24109979",
"31504542",
"713143",
"423536031",
"25545388",
"59471027",
"706923475",
"19383279",
"8824902",
"1655877529",
"18734310",
"240734425",
"17076218",
"47964412",
"2802184770",
"19426729",
"56443153",
"23508439",
"25084916",
"764347046",
"19853312",
"348590880"
],
"id": "8tujg1lvi8sn",
"created_at": "2019-08-15T20:48:51Z",
"updated_at": "2021-03-09T20:34:13Z",
"videos_monetized_in_last_thirty_days": 254
},
{
"name": "Men’s Culture + Lifestyle",
"description": "Run next to content from a set of handles curated based on their follower profiles to help you reach a majority male audience, including some of the top handles sharing technology, news, and lifestyle content.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"17764377",
"61933836",
"28370738",
"3224616765",
"22819823",
"18927441",
"734826612684783616",
"14372486",
"7157132",
"15764136",
"590316679",
"7302282",
"895014043932540928",
"7517222",
"3489420013",
"14063426",
"72665816",
"214201922",
"14980903",
"22199141",
"21272440",
"25319414",
"119593082",
"4760694445",
"765905855195803648",
"238431491",
"22178780",
"241544156",
"25093616",
"16877611",
"22146985",
"368703433",
"14342661",
"415605847",
"2181233851",
"890891",
"15764001",
"614754689",
"18479513",
"23508439",
"348590880"
],
"id": "8tujj1ep7t34",
"created_at": "2019-08-15T20:49:47Z",
"updated_at": "2021-03-09T20:39:00Z",
"videos_monetized_in_last_thirty_days": 1330
},
{
"name": "Women’s Culture + Lifestyle",
"description": "Run next to content from a set of handles curated based on their follower profiles to help you reach a majority female audience, including some of the top handles sharing pop culture, news, and lifestyle content.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"23482952",
"20177423",
"19074134",
"15566901",
"32469566",
"19784831",
"16145224",
"16932962",
"14934818",
"29730065",
"24190981",
"30278532",
"15846407",
"24994219",
"23993734",
"40965341",
"16312576",
"75094638",
"549673665",
"18806753",
"75306892",
"1482663290",
"31181674",
"971407531972186112",
"4020532937",
"25087685",
"22515362",
"80943051",
"19247844",
"15279429",
"16824090",
"20710809",
"979831113655996416",
"32432308",
"19472585",
"25589776",
"739963476370673665",
"20188834",
"926269727663673349"
],
"id": "8tujl1p3yn0g",
"created_at": "2019-08-15T20:50:24Z",
"updated_at": "2021-03-09T20:17:53Z",
"videos_monetized_in_last_thirty_days": 1365
},
{
"name": "Light-Hearted",
"description": "Run next to a list of handles curated for the volume of positive, feel-good content and conversation they’ve consistently generated on X.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"20177423",
"22449367",
"9695312",
"19074134",
"4805771380",
"32469566",
"1212860112047460352",
"16402507",
"16932962",
"14934818",
"17446621",
"29730065",
"15846407",
"1604444052",
"180066380",
"16312576",
"549673665",
"18806753",
"16211434",
"545336345",
"971407531972186112",
"4020532937",
"833612154",
"22515362",
"20710809",
"32432308",
"774311630",
"3073349892",
"926269727663673349"
],
"id": "9fg8gmz96qdg",
"created_at": "2020-03-20T19:37:44Z",
"updated_at": "2021-03-09T19:57:40Z",
"videos_monetized_in_last_thirty_days": 1395
},
{
"name": "Soccer",
"description": "Run next to the best of everyday soccer content including college teams, professional teams, and the top sports media handles sharing major soccer coverage.",
"country_codes": [
"US"
],
"publisher_user_ids": [
"21677316",
"20636347",
"4704552148",
"14573900",
"22556296",
"1415791555",
"107146095",
"17288520",
"213474069",
"17493398",
"44990136",
"452155423",
"17744542",
"16303450",
"2841146601",
"2413176055",
"29739264",
"38580532",
"953476292913106945",
"27092557",
"86356439",
"34613288",
"3170659367",
"119593082",
"73412535",
"627586654",
"15891449",
"23011345",
"96951800",
"15997022",
"16960789",
"21919642",
"102965285",
"17224076",
"36432200",
"1410055968"
],
"id": "9ddrgesiap6o",
"created_at": "2020-02-28T22:43:26Z",
"updated_at": "2021-01-26T17:54:55Z",
"videos_monetized_in_last_thirty_days": 421
}
],
"total_count": 9
}
```
#### GET accounts/:account\_id/curated\_categories/:curated\_category\_id[](#get-accounts-account-id-curated-categories-curated-category-id "Permalink to this headline")
Retrieve details for a specific `curated_category_id`
Each `curated_category` is only available in specific countries specified by the `country_codes` in the response.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/curated_categories/:curated_category_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Curated Category you are operating with in the request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/curated_categories/9ddrgesiap6o`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"id": "9ddrgesiap6o",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "Soccer",
"description": "Run next to the best of everyday soccer content including college teams, professional teams, and the top sports media handles sharing major soccer coverage.",
"country_codes": [],
"publisher_user_ids": [
"21677316",
"20636347",
"4704552148",
"14573900",
"22556296",
"1415791555",
"107146095",
"17288520",
"213474069",
"17493398",
"44990136",
"452155423",
"17744542",
"16303450",
"2841146601",
"2413176055",
"29739264",
"38580532",
"953476292913106945",
"27092557",
"86356439",
"34613288",
"3170659367",
"119593082",
"73412535",
"627586654",
"15891449",
"23011345",
"96951800",
"15997022",
"16960789",
"21919642",
"102965285",
"17224076",
"36432200",
"1410055968"
],
"id": "9ddrgesiap6o",
"created_at": "2020-02-28T22:43:26Z",
"updated_at": "2021-01-26T17:54:55Z",
"videos_monetized_in_last_thirty_days": 421
}
}
```
### Features
#### GET accounts/:account\_id/features[](#get-accounts-account-id-features "Permalink to this headline")
Retrieve the collection of granted features accessible by this ads account. Features are indicated by a descriptive feature key and are only exposed on this endpoint if they are introduced in beta or an otherwise limited release and are available in the Ads API. Features that do not meet this criteria will not be exposed on this endpoint.
**Note**: This endpoint serves to aid Ads API ecosystem development by improving visibility into client access to beta releases. API developers can not request access to features on behalf of an advertiser. These requests can only be made by the advertiser to their X account manager.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/features`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
An optional parameter that enables querying for a specific feature key. Requests may include multiple comma-separated keys.
**Note**: Only the features that are accessible by this account will be included in the response.
Possible values: `REACH_AND_FREQUENCY_ANALYTICS`, `REACH_FREQUENCY_CAP`, `WEBSITE_CLICKS_CPM_BILLING`
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/features`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"data": [
"CITY_TARGETING",
"CONVERSATION_CARD",
"PROMOTED_MEDIA_POLLS",
"REACH_AND_FREQUENCY_ANALYTICS",
"REACH_FREQUENCY_CAP",
"UNIVERSAL_LOOKALIKE"
]
}
```
#### POST accounts/:account\_id/features[](#post-accounts-account-id-features "Permalink to this headline")
**SANDBOX ONLY**
Add a feature to a sandbox account.
The up to date list of account features may be retrieved via the [GET accounts/:account\_id/features](#get-accounts-account-id-features) endpoint.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts/:account_id/features`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A comma-separated list of account features to add to the account.
Possible values: `AGE_TARGETING`, `ALLOW_SKIPPABLE_VIDEOS_FOR_PREROLL_VIEWS_OBJECTIVE`, `AWARENESS_OBJECTIVE`, `BRAND_TPN`, `CHARGE_FOR_GOOD_CLICK`, `CONVERSATION_CARD`, `CONVERSATION_CARD_FOUR_OPTIONS`, `CONVERSATION_CARD_UNLOCK`, `CPI_CHARGING`, `DIRECT_MESSAGE_CARD`, `DR_TAP`, `ENGAGER_RETARGETING`, `EVENT_TARGETING`, `INSTALLED_APP_CATEGORY_TARGETING`, `MOBILE_CONVERSION_TRANSACTION_VALUE`, `OPTIMIZED_ACTION_BIDDING`, `REACH_AND_FREQUENCY_ANALYTICS`, `REACH_FREQUENCY_CAP`, `VALIDATED_AGE_TARGETING`, `VIDEO_VIEWS_MIDROLL_OBJECTIVE`, `PREROLL_VIEWS_OBJECTIVE`, `VIDEO_APP_DOWNLOAD_CARD`
**Example Request**
`POST https://ads-api-sandbox.x.com/12/accounts/gq180y/features?feature_keys=VALIDATED_AGE_TARGETING`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "gq180y",
"feature_keys": [
"VALIDATED_AGE_TARGETING"
]
}
},
"data": [
"ALLOW_SKIPPABLE_VIDEOS_FOR_PREROLL_VIEWS_OBJECTIVE",
"AWARENESS_OBJECTIVE",
"CPI_CHARGING",
"EVENT_TARGETING",
"INSTALLED_APP_CATEGORY_TARGETING",
"MOBILE_CONVERSION_TRANSACTION_VALUE",
"OPTIMIZED_ACTION_BIDDING",
"VALIDATED_AGE_TARGETING",
"VIDEO_APP_DOWNLOAD_CARD"
]
}
```
#### DELETE accounts/:account\_id/features[](#delete-accounts-account-id-features "Permalink to this headline")
**SANDBOX ONLY**
Remove a feature from a sandbox account.
The up to date list of account features may be retrieved via the [GET accounts/:account\_id/features](#get-accounts-account-id-features) endpoint.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts/:account_id/features`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A comma-separated list of account features to remove from the account.
Possible values: `AGE_TARGETING`, `ALLOW_SKIPPABLE_VIDEOS_FOR_PREROLL_VIEWS_OBJECTIVE`, `AWARENESS_OBJECTIVE`, `BRAND_TPN`, `CHARGE_FOR_GOOD_CLICK`, `CONVERSATION_CARD`, `CONVERSATION_CARD_FOUR_OPTIONS`, `CONVERSATION_CARD_UNLOCK`, `CPI_CHARGING`, `DIRECT_MESSAGE_CARD`, `DR_TAP`, `ENGAGER_RETARGETING`, `EVENT_TARGETING`, `INSTALLED_APP_CATEGORY_TARGETING`, `MOBILE_CONVERSION_TRANSACTION_VALUE`, `OPTIMIZED_ACTION_BIDDING`, `REACH_AND_FREQUENCY_ANALYTICS`, `REACH_FREQUENCY_CAP`, `VALIDATED_AGE_TARGETING`, `VIDEO_VIEWS_MIDROLL_OBJECTIVE`, `PREROLL_VIEWS_OBJECTIVE`, `VIDEO_APP_DOWNLOAD_CARD`
**Example Request**
`DELETE https://ads-api-sandbox.x.com/12/accounts/gq180y/features?feature_keys=PREROLL_VIEWS_OBJECTIVE`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "gq180y",
"feature_keys": [
"PREROLL_VIEWS_OBJECTIVE"
]
}
},
"data": [
"CPI_CHARGING",
"EVENT_TARGETING",
"INSTALLED_APP_CATEGORY_TARGETING",
"MOBILE_CONVERSION_TRANSACTION_VALUE",
"OPTIMIZED_ACTION_BIDDING",
"VIDEO_APP_DOWNLOAD_CARD"
]
}
```
### Funding Instruments
#### GET accounts/:account\_id/funding\_instruments[](#get-accounts-account-id-funding-instruments "Permalink to this headline")
Retrieve details for some or all funding instruments associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/funding_instruments`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request. Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired funding instruments by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/funding_instruments`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"start_time": "2016-07-22T04:24:04Z",
"description": "Visa ending in 0650",
"credit_limit_local_micro": 200000000,
"end_time": null,
"id": "lygyi",
"entity_status": "ACTIVE",
"account_id": "18ce54d4x5t",
"reasons_not_able_to_fund": [],
"io_header": null,
"currency": "USD",
"funded_amount_local_micro": 645940000,
"created_at": "2016-07-22T04:24:04Z",
"type": "CREDIT_CARD",
"able_to_fund": true,
"updated_at": "2017-04-05T00:25:13Z",
"credit_remaining_local_micro": null,
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/funding\_instruments/:funding\_instrument\_id[](#get-accounts-account-id-funding-instruments-funding-instrument-id "Permalink to this headline")
Retrieve a specific funding instrument associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/funding_instruments/:id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the funding instrument you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/funding_instruments/lygyi`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"funding_instrument_id": "lygyi",
"account_id": "18ce54d4x5t"
}
},
"data": {
"start_time": "2016-07-22T04:24:04Z",
"description": "Visa ending in 0650",
"credit_limit_local_micro": 200000000,
"end_time": null,
"id": "lygyi",
"entity_status": "ACTIVE",
"account_id": "18ce54d4x5t",
"reasons_not_able_to_fund": [],
"io_header": null,
"currency": "USD",
"funded_amount_local_micro": 645940000,
"created_at": "2016-07-22T04:24:04Z",
"type": "CREDIT_CARD",
"able_to_fund": true,
"updated_at": "2017-04-05T00:25:13Z",
"credit_remaining_local_micro": null,
"deleted": false
}
}
```
#### POST accounts/:account\_id/funding\_instruments[](#post-accounts-account-id-funding-instruments "Permalink to this headline")
**SANDBOX ONLY**
Create a funding instrument in the sandbox environment.
There is no risk of incurring costs while using a sandbox funding instrument.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts/:account_id/funding_instruments`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The currency, expressed in [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217).
The date for the funding instrument to become active and usable, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
The type of funding instrument to create.
Possible values: `AGENCY_CREDIT_LINE`, `CREDIT_CARD`, `CREDIT_LINE`, `INSERTION_ORDER`, `PARTNER_MANAGED`
The date for the funding instrument to become inactive, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).
The total credit available against this funding instrument.
**Note**: Only applicable to some funding instrument types.
The total budget amount allocated to this funding instrument.
**Note**: Only applicable to some funding instrument types.
**Example Request**
`POST https://ads-api-sandbox.x.com/12/accounts/gq1844/funding_instruments?currency=USD&start_time=2017-07-10T00:00:00Z&type=INSERTION_ORDER&end_time=2018-01-10T00:00:00Z&funded_amount_local_micro=140000000000`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"start_time": "2017-07-10T00:00:00Z",
"description": "(no payment method has been set up yet)",
"credit_limit_local_micro": null,
"end_time": "2018-01-10T00:00:00Z",
"id": "hxtet",
"entity_status": "ACTIVE",
"account_id": "gq1844",
"reasons_not_able_to_fund": [],
"io_header": null,
"currency": "USD",
"funded_amount_local_micro": 140000000000,
"created_at": "2017-09-09T05:23:28Z",
"type": "INSERTION_ORDER",
"able_to_fund": true,
"updated_at": "2017-09-09T05:23:28Z",
"credit_remaining_local_micro": null,
"deleted": false
},
"request": {
"params": {
"start_time": "2017-07-10T00:00:00Z",
"end_time": "2018-01-10T00:00:00Z",
"account_id": "gq1844",
"currency": "USD",
"funded_amount_local_micro": 140000000000,
"type": "INSERTION_ORDER"
}
}
}
```
#### DELETE accounts/:account\_id/funding\_instruments/:funding\_instrument\_id[](#delete-accounts-account-id-funding-instruments-funding-instrument-id "Permalink to this headline")
**SANDBOX ONLY**
Delete a funding instrument in the sandbox environment.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api-sandbox.x.com/12/accounts/:account_id/funding_instruments/:funding_instrument_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the funding instrument you are operating with in the request.
**Example Request**
`DELETE https://ads-api-sandbox.x.com/12/accounts/gq1844/funding_instruments/hxt82`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"start_time": "2017-08-30T19:23:47Z",
"description": "(no payment method has been set up yet)",
"credit_limit_local_micro": 500000000,
"end_time": null,
"id": "hxt82",
"entity_status": "ACTIVE",
"account_id": "gq1844",
"reasons_not_able_to_fund": [
"DELETED"
],
"io_header": null,
"currency": "USD",
"funded_amount_local_micro": null,
"created_at": "2017-08-30T19:23:47Z",
"type": "CREDIT_CARD",
"able_to_fund": false,
"updated_at": "2017-09-09T02:08:30Z",
"credit_remaining_local_micro": null,
"deleted": true
},
"request": {
"params": {
"funding_instrument_id": "hxt82",
"account_id": "gq1844"
}
}
}
```
### IAB Categories
#### GET iab\_categories[](#get-iab-categories "Permalink to this headline")
Request the valid app `categories` for ad groups (`line_items`).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/iab_categories`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of categories. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/iab_categories?count=2`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"id": "IAB1",
"parent_id": null,
"name": "Arts & Entertainment"
},
{
"id": "IAB1-1",
"parent_id": "IAB1",
"name": "Books & Literature"
}
],
"next_cursor": "uxa8",
"request": {
"params": {
"count": 2
}
}
}
```
### Line Items
#### GET accounts/:account\_id/line\_items[](#get-accounts-account-id-line-items "Permalink to this headline")
Retrieve details for some or all line items associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_items`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the line items under specific campaigns by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the line items under specific funding instruments by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Scope the response to just the desired line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
An optional query to scope resource by `name`.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include draft campaigns results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/line_items?line_item_ids=itttx`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"line_item_ids": [
"itttx"
]
}
},
"next_cursor": null,
"data": [
{
"advertiser_user_id": "756201191646691328",
"name": "li-18",
"placements": [
"ALL_ON_TWITTER"
],
"start_time": "2021-02-16T00:00:00Z",
"bid_amount_local_micro": 320000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"goal": "ENGAGEMENT",
"daily_budget_amount_local_micro": null,
"product_type": "PROMOTED_TWEETS",
"end_time": null,
"funding_instrument_id": "lygyi",
"bid_strategy": "MAX",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "itttx",
"entity_status": "PAUSED",
"automatic_tweet_promotion": null,
"frequency_cap": null,
"android_app_store_identifier": null,
"categories": [],
"currency": "USD",
"pay_by": "ENGAGEMENT",
"created_at": "2021-02-23T23:37:54Z",
"ios_app_store_identifier": null,
"updated_at": "2022-06-01T02:01:18Z",
"campaign_id": "f4z6x",
"creative_source": "MANUAL",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/line\_items/:line\_item\_id[](#get-accounts-account-id-line-items-line-item-id "Permalink to this headline")
Retrieve a specific line item associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_items/:line_item_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/line_items/itttx`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_id": "itttx",
"account_id": "18ce54d4x5t"
}
},
"data": {
"advertiser_user_id": "756201191646691328",
"name": "li-18",
"placements": [
"ALL_ON_TWITTER"
],
"start_time": "2021-02-16T00:00:00Z",
"bid_amount_local_micro": 320000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"goal": "ENGAGEMENT",
"daily_budget_amount_local_micro": null,
"product_type": "PROMOTED_TWEETS",
"end_time": null,
"funding_instrument_id": "lygyi",
"bid_strategy": "MAX",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "itttx",
"entity_status": "PAUSED",
"automatic_tweet_promotion": null,
"frequency_cap": null,
"android_app_store_identifier": null,
"categories": [],
"currency": "USD",
"pay_by": "ENGAGEMENT",
"created_at": "2021-02-23T23:37:54Z",
"ios_app_store_identifier": null,
"updated_at": "2022-06-01T02:01:18Z",
"campaign_id": "f4z6x",
"creative_source": "MANUAL",
"deleted": false
}
}
```
#### POST accounts/:account\_id/line\_items[](#post-accounts-account-id-line-items "Permalink to this headline")
Create a line item associated with the specified campaign belonging to the current account.
All line items within a campaign must be of the same `product_type` and `objective`.
When using the `PROMOTED_ACCOUNT` product type, associating a Tweet with the `line_item` will add timeline placements on mobile in addition to the standard `PROMOTED_ACCOUNT` placement.
Setting either `android_app_store_identifier` or `ios_app_store_identifier` will automatically add the targeting criteria for the line item matching the mobile app being promoted; for example, passing in `ios_app_store_identifier` would add `PLATFORM` [targeting criteria](/x-ads-api/campaign-management/reference#targeting-options) for `iOS`.
**Note**: There is a limit of 100 line items per campaign and 256 active line items across all campaigns.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_items`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The identifier for the campaign to create the line item under.
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the line item will stop serving.
The campaign objective for this line item.
Possible values: `APP_ENGAGEMENTS`, `APP_INSTALLS`, `REACH`, `FOLLOWERS`, `ENGAGEMENTS`, `VIDEO_VIEWS`, `PREROLL_VIEWS`, `WEBSITE_CLICKS`
The placement location(s) for this line item to display in. Specify a comma-separated list of placement values.
Possible values: `ALL_ON_TWITTER`, `PUBLISHER_NETWORK`, `TAP_BANNER`, `TAP_FULL`, `TAP_FULL_LANDSCAPE`, `TAP_NATIVE`, `TAP_MRECT`, `TWITTER_PROFILE`, `TWITTER_REPLIES`, `TWITTER_SEARCH`, `TWITTER_TIMELINE`
The type of promoted product that this line item will contain.
Possible values: `MEDIA`, `PROMOTED_ACCOUNT`, `PROMOTED_TWEETS`
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the line item will begin serving.
The website domain for this advertiser, without the protocol specification.
**Note**: Required when the line item's placement is set to `PUBLISHER_NETWORK`.
The Google App Store identifier for promoted applications.
**Note**: `APP_INSTALLS` and `APP_ENGAGEMENTS` objectives require setting at least one app store identifier -- either `android_app_store_identifier` or `ios_app_store_identifier`.
The bid amount to be associated with this line item. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000.
**Note**: Required if `bid_strategy` is set to either `MAX` or `TARGET`. Only values greater than zero are accepted.
The relevant IAB categories for this advertiser. See [GET iab\_categories](/x-ads-api/campaign-management/reference#iab-categories).
**Note**: Required when the line item's placement is set to `PUBLISHER_NETWORK`.
The numeric portion of the Apple App Store identifier for promoted applications.
**Note**: `APP_INSTALLS` and `APP_ENGAGEMENTS` objectives require setting at least one app store identifier -- either `android_app_store_identifier` or `ios_app_store_identifier`.
The identifier of the primary web event tag. Allows more accurate tracking of engagements for the campaign pertaining to this line item.
**Note**: Required when the line item's goal is set to `WEBSITE_CONVERSIONS`.
The X user identifier for the handle promoting a `PREROLL_VIEWS` ad. Only certain client applications may use this parameter.
Used to expand the reach of campaigns by targeting users similar to those already targeted.
**Note**: By default, no expansion will be applied.
Possible values: `BROAD`, `DEFINED`, `EXPANDED`
The bidding mechanism.
`AUTO` automatically optimizes bidding based on daily budget and campaign flight dates.
`MAX` sets the maximum allowable bid and is **not** available when the objective is set to `REACH` or `FOLLOWERS`.
`TARGET` attempts to make daily bid averages within 20% of the specified `bid_amount_local_micro` and is available when the objective is set to `REACH`, `FOLLOWERS`, or `WEBSITE_CLICKS`.
**Note**: If set to `AUTO`, `bid_amount_local_micro` will be ignored.
**Note**: Default based on objective.
Possible values: `AUTO`, `MAX`, `TARGET`
The time period within which the `frequency_cap` is achieved.
Possible values: `1`, `7`, `30`
The line item status.
Possible values: `ACTIVE`, `DRAFT`, `PAUSED`
The maximum number of times an ad could be delivered to a user.
**Note**: Only supported for `REACH`, `ENGAGEMENTS`, `VIDEO_VIEWS`, and `PREROLL_VIEWS` objectives.
The optimization setting to use with this line item.
The `APP_PURCHASES` option is available for `APP_INSTALL`. The `APP_CLICKS` and `APP_INSTALLS` options are available for both `APP_INSTALL` and `APP_ENGAGEMENTS` objectives and may require using a supported [MACT partner](https://business.x.com/en/help/campaign-setup/create-an-app-installs-or-app-engagement-campaign/mobile-app-conversion-tracking.html).
The `SITE_VISITS` option is only available with the `WEBSITE_CLICKS` objective.
**Note**: Default based on objective.
Possible values: `APP_CLICKS`, `APP_INSTALLS`, `APP_PURCHASES`, `ENGAGEMENT`, `FOLLOWERS`, `LINK_CLICKS`, `MAX_REACH`, `PREROLL`, `PREROLL_STARTS`, `REACH_WITH_ENGAGEMENT`, `SITE_VISITS`, `VIDEO_VIEW`, `VIEW_3S_100PCT`, `VIEW_6S`, `VIEW_15S`, `WEBSITE_CONVERSIONS`
The name for the line item.
Min, Max length: 1, 255
The unit to charge this line item by. This setting can only be modified for line items using the `APP_INSTALLS` objective.
**Note**: The default `pay_by` is automatically set based upon the campaign objective and line item's bid unit.
The `APP_INSTALLS` goal supports both `APP_CLICK` and `IMPRESSION` values. `IMPRESSION` is the default value.
The `LINK_CLICKS` goal supports both `LINK_CLICK` and `IMPRESSION` values. `IMPRESSION` is the default value but is not supported when setting `TARGET` for `bid_strategy`.
The `SITE_VISITS` goal supports `IMPRESSION` values.
Possible values: `APP_CLICK`, `IMPRESSION`, `LINK_CLICK`
Enable standard or accelerated delivery. See [Budget Pacing](/x-ads-api/campaign-management#budget-pacing) for more information on standard versus accelerated delivery. Only available when `budget_optimization` is set to `LINE_ITEM` for the parent campaign.
The total budget amount to be allocated to the line item. The currency associated with the specified funding instrument will be used. For USD, \$37.50 is represented as 37500000.
The daily budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000. When not provided the campaign will spend evenly based upon total budget and for duration of campaign flight time. Only available when `budget_optimization` is set to `LINE_ITEM` for the parent campaign.
**Note**: This should be less than or equal to the `total_budget_amount_local_micro`.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/line_items?campaign_id=hwtq0&objective=ENGAGEMENTS&product_type=PROMOTED_TWEETS&placements=ALL_ON_TWITTER&bid_amount_local_micro=3210000&entity_status=PAUSED&daily_budget_amount_local_micro=1000000&start_time=2022-06-15`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"placements": [
"ALL_ON_TWITTER"
],
"start_time": "2022-06-15T00:00:00Z",
"bid_amount_local_micro": 3210000,
"daily_budget_amount_local_micro": 1000000,
"product_type": "PROMOTED_TWEETS",
"objective": "ENGAGEMENTS",
"entity_status": "PAUSED",
"account_id": "18ce54d4x5t",
"campaign_id": "hwtq0"
}
},
"data": {
"advertiser_user_id": "756201191646691328",
"name": null,
"placements": [
"ALL_ON_TWITTER"
],
"start_time": "2022-06-15T00:00:00Z",
"bid_amount_local_micro": 3210000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"goal": "ENGAGEMENT",
"daily_budget_amount_local_micro": 1000000,
"product_type": "PROMOTED_TWEETS",
"end_time": null,
"bid_strategy": "MAX",
"duration_in_days": null,
"standard_delivery": true,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "ml5vs",
"entity_status": "PAUSED",
"automatic_tweet_promotion": null,
"frequency_cap": null,
"android_app_store_identifier": null,
"categories": [],
"currency": "USD",
"pay_by": "ENGAGEMENT",
"created_at": "2022-06-03T23:47:20Z",
"ios_app_store_identifier": null,
"updated_at": "2022-06-03T23:47:20Z",
"campaign_id": "hwtq0",
"creative_source": "MANUAL",
"deleted": false
}
}
```
#### POST batch/accounts/:account\_id/line\_items[](#post-batch-accounts-account-id-line-items "Permalink to this headline")
Allows the batch creation of new [line items](#post-accounts-account-id-line-items) with a single request.
**Batch Requests**
* The current maximum batch size is 40.
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
Batch API responses return an ordered collection of items. Otherwise, they are identical in structure to their corresponding single-item endpoints.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required line item parameter) are shown in the response under the `operation_errors` object.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/batch/accounts/:account_id/line_items`
The per item operation type being performed.
Possible values: `Create`, `Delete`, `Update`
A JSON object containing all the parameters for the line item objects. For a list of required and optional line item parameters, see the single POST endpoint above.
**Example Request**
`POST 'Content-Type: application/json' https://ads-api.x.com/12/batch/accounts/18ce54d4x5t/line_items`
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
[
{
"operation_type":"Create",
"params":{
"campaign_id":"8yn7m",
"objective":"ENGAGEMENTS",
"product_type":"PROMOTED_TWEETS",
"placements":"ALL_ON_TWITTER",
"bid_amount_local_micro":3210000,
"entity_status":"PAUSED"
}
}
]
```
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"advertiser_user_id": "756201191646691328",
"name": null,
"placements": [
"ALL_ON_TWITTER"
],
"start_time": null,
"bid_amount_local_micro": 3210000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"goal": "ENGAGEMENT",
"daily_budget_amount_local_micro": null,
"product_type": "PROMOTED_TWEETS",
"end_time": null,
"funding_instrument_id": "lygyi",
"bid_strategy": "MAX",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "9cqi0",
"entity_status": "PAUSED",
"automatic_tweet_promotion": null,
"frequency_cap": null,
"android_app_store_identifier": null,
"categories": [],
"currency": "USD",
"pay_by": "ENGAGEMENT",
"created_at": "2017-07-07T17:42:20Z",
"ios_app_store_identifier": null,
"updated_at": "2017-07-07T17:42:20Z",
"campaign_id": "8yn7m",
"creative_source": "MANUAL",
"deleted": false
}
],
"request": [
{
"params": {
"placements": [
"ALL_ON_TWITTER"
],
"bid_amount_local_micro": 3210000,
"product_type": "PROMOTED_TWEETS",
"objective": "ENGAGEMENTS",
"entity_status": "PAUSED",
"account_id": "18ce54d4x5t",
"campaign_id": "8yn7m"
},
"operation_type": "Create"
}
]
}
```
#### PUT accounts/:account\_id/line\_items/:line\_item\_id[](#put-accounts-account-id-line-items-line-item-id "Permalink to this headline")
Update the specified line item associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_items/:line_item_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
The website domain for this advertiser, without the protocol specification.
**Note**: Required when the line item's placement is set to `PUBLISHER_NETWORK`.
The Twitter user identifier for the handle promoting a `PREROLL_VIEWS` ad. Only certain client applications may use this parameter.
The Google App Store identifier for the promoted application.
**Note**: `APP_INSTALLS` and `APP_ENGAGEMENTS` objectives require setting at least one app store identifier -- either `android_app_store_identifier` or `ios_app_store_identifier`.
Used to expand the reach of campaigns by targeting users similar to those already targeted.
Possible values: `BROAD`, `DEFINED`, `EXPANDED`
The bid amount to be associated with this line item. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000.
**Note**: Required if `bid_strategy` is set to either `MAX` or `TARGET`. Only values greater than zero are accepted.
The bidding mechanism.
`AUTO` automatically optimizes bidding based on daily budget and campaign flight dates.
`MAX` sets the maximum allowable bid and is **not** available when the objective is set to `REACH` or `FOLLOWERS`.
`TARGET` attempts to make daily bid averages within 20% of the specified `bid_amount_local_micro` and is available when the objective is set to `REACH` or `WEBSITE_CLICKS`.
**Note**: If set to `AUTO`, `bid_amount_local_micro` will be ignored.
**Note**: Default based on objective.
Possible values: `AUTO`, `MAX`, `TARGET`
The relevant IAB categories for this advertiser. See [GET iab\_categories](/x-ads-api/campaign-management/reference#iab-categories).
**Note**: Required when the line item's placement is set to `PUBLISHER_NETWORK`.
The time period within which the `frequency_cap` is achieved.
Possible values: `1`, `7`, `30`
The line item status.
Possible values: `ACTIVE`, `PAUSED`
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the line item will stop serving.
The maximum number of times an ad could be delivered to a user.
**Note**: Only supported for `REACH`, `ENGAGEMENTS`, `VIDEO_VIEWS`, and `PREROLL_VIEWS` objectives.
The optimization setting to use with this line item. The `APP_PURCHASES` option is available for `APP_INSTALL`. The `APP_CLICKS` and `APP_INSTALLS` options are available for `APP_INSTALL` and `APP_ENGAGEMENTS` and may require using a supported [MACT partner](https://business.x.com/en/help/campaign-setup/create-an-app-installs-or-app-engagement-campaign/mobile-app-conversion-tracking.html).
**Note**: Default based on objective.
Possible values: `APP_CLICKS`, `APP_INSTALLS`, `APP_PURCHASES`, `ENGAGEMENT`, `FOLLOWERS`, `LINK_CLICKS`, `MAX_REACH`, `PREROLL`, `PREROLL_STARTS`, `REACH_WITH_ENGAGEMENT`, `VIDEO_VIEW`, `VIEW_3S_100PCT`, `VIEW_6S`, `VIEW_15S`, `WEBSITE_CONVERSIONS`
The numeric portion of the Apple App Store identifier for promoted applications.
**Note**: `APP_INSTALLS` and `APP_ENGAGEMENTS` objectives require setting at least one app store identifier -- either `android_app_store_identifier` or `ios_app_store_identifier`.
The name for the line item.
The unit to charge this line item by. This setting can only be modified for line items using the `APP_INSTALLS` objective.
**Note**: The default `pay_by` is automatically set based upon the campaign objective and line item's bid unit.
The `APP_INSTALLS` goal supports both `APP_CLICK` and `IMPRESSION` values. `IMPRESSION` is the default value.
The `LINK_CLICKS` goal supports both `LINK_CLICK` and `IMPRESSION` values. `IMPRESSION` is the default value but is not supported when setting `TARGET` for `bid_strategy`.
The `SITE_VISITS` goal supports `IMPRESSION` values.
Possible values: `APP_CLICK`, `IMPRESSION`, `LINK_CLICK`
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the line item will begin serving.
The total budget amount to be allocated to the line item. The currency associated with the specified funding instrument will be used. For USD, \$37.50 is represented as 37500000.
The daily budget amount to be allocated to the campaign. The currency associated with the specified funding instrument will be used. For USD, \$5.50 is represented as 5500000. When not provided the campaign will spend evenly based upon total budget and for duration of campaign flight time. Only available when `budget_optimization` is set to `LINE_ITEM` for the parent campaign.
**Note**: This should be less than or equal to the `total_budget_amount_local_micro`.
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/line_items/9cqi0?bid_amount_local_micro=140000`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_id": "9cqi0",
"bid_amount_local_micro": 140000,
"account_id": "18ce54d4x5t"
}
},
"data": {
"advertiser_user_id": "756201191646691328",
"name": null,
"placements": [
"ALL_ON_TWITTER"
],
"start_time": "2017-07-10T00:00:00Z",
"bid_amount_local_micro": 140000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"goal": "ENGAGEMENT",
"daily_budget_amount_local_micro": null,
"product_type": "PROMOTED_TWEETS",
"end_time": null,
"bid_strategy": "MAX",
"duration_in_days": null,
"standard_delivery": null,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "9cqi0",
"entity_status": "PAUSED",
"automatic_tweet_promotion": null,
"frequency_cap": null,
"android_app_store_identifier": null,
"categories": [],
"currency": "USD",
"pay_by": "ENGAGEMENT",
"created_at": "2017-07-07T17:42:20Z",
"ios_app_store_identifier": null,
"updated_at": "2022-06-03T23:51:36Z",
"campaign_id": "8yn7m",
"creative_source": "MANUAL",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/line\_items/:line\_item\_id[](#delete-accounts-account-id-line-items-line-item-id "Permalink to this headline")
Delete the specified line item belonging to the current account.
**Note**: Deleting a line item is not reversible and subsequent attempts to delete the resource will return HTTP 404.
**Note**: When a line item is deleted, its child promoted\_tweets are only returned in the GET accounts/:account\_id/promoted\_tweets and GET accounts/:account\_id/promoted\_tweets/:promoted\_tweet\_id endpoints if `with_deleted=true` is specified in the request. These promoted\_tweets are not actually deleted, though (`"deleted": false` in the response). We do not cascade deletes.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_items/:line_item_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/line_items/9f2ix`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"bid_strategy": "MAX",
"advertiser_user_id": "756201191646691328",
"name": "Untitled",
"placements": [],
"start_time": null,
"bid_amount_local_micro": 100000,
"advertiser_domain": null,
"target_cpa_local_micro": null,
"primary_web_event_tag": null,
"pay_by": "ENGAGEMENT",
"product_type": "PROMOTED_TWEETS",
"end_time": "2017-07-21T00:00:00Z",
"duration_in_days": 1,
"total_budget_amount_local_micro": null,
"objective": "ENGAGEMENTS",
"id": "9f2ix",
"entity_status": "ACTIVE",
"goal": "ENGAGEMENT",
"frequency_cap": 5,
"categories": [],
"currency": "USD",
"created_at": "2017-07-14T00:01:50Z",
"updated_at": "2017-08-09T07:41:08Z",
"campaign_id": "90r8n",
"creative_source": "MANUAL",
"deleted": true
},
"request": {
"params": {
"line_item_id": "9f2ix",
"account_id": "18ce54d4x5t"
}
}
}
```
### Line Item Curated Categories
Additional details on usage can be found at the [Video Views Pre-roll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective)
#### GET accounts/:account\_id/line\_item\_curated\_categories[](#get-accounts-account-id-line-item-curated-categories "Permalink to this headline")
Retrieve details for some or all line item curated categories associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_item_curated_categories`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/abc1/line_item_curated_categories`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "abc1"
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "by5pw",
"curated_category_id": "7op29tp2jzeo",
"id": "1",
"created_at": "2018-06-29T04:19:53Z",
"updated_at": "2018-06-29T04:19:53Z",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/line\_item\_curated\_categories/:line\_item\_curated\_category\_id[](#get-accounts-account-id-line-item-curated-categories-line-item-curated-category-id "Permalink to this headline")
Retrieves details for a specific line item curated category associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_item_curated_categories/:line_item_curated_category_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item curated category you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/abc1/line_item_curated_categories/yav`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_curated_category_id": "yav",
"account_id": "abc1"
}
},
"data": {
"line_item_id": "by5pw",
"curated_category_id": "7op29tp2jzeo",
"id": "yav",
"created_at": "2018-06-29T04:19:53Z",
"updated_at": "2018-06-29T04:19:53Z",
"deleted": false
}
}
```
#### POST accounts/:account\_id/line\_item\_curated\_categories[](#post-accounts-account-id-line-item-curated-categories "Permalink to this headline")
Associate a [curated category](/x-ads-api/campaign-management/reference#curated-categories-2) object with the specified line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_item_curated_categories`
**Parameters[](#parameters "Permalink to this headline")**
| Name | Description |
| :-------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| account\_id `required` | The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests excluding [GET accounts](/x-ads-api/campaign-management/reference#get-accounts). The specified account must be associated with the authenticated user.
Type: string
Example: `18ce54d4x5t` |
| curated\_category\_id `required` | A reference to the curated category entity you are operating with in the request.
Type: string
Example: `10miy` |
| line\_item\_id `required` | A reference to the line item you are operating with in the request.
Type: string
Example: `8v7jo` |
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/line_item_curated_categories?line_item_id=iqwka&curated_category_id=9ddrgesiap6o`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"curated_category_id": "9ddrgesiap6o",
"line_item_id": "iqwka",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "iqwka",
"curated_category_id": "9ddrgesiap6o",
"id": "xq",
"created_at": "2021-03-30T17:26:42Z",
"updated_at": "2021-03-30T17:26:42Z",
"deleted": false
}
}
```
#### PUT accounts/:account\_id/line\_item\_curated\_categories/:line\_item\_curated\_category\_id[](#put-accounts-account-id-line-item-curated-categories-line-item-curated-category-id "Permalink to this headline")
Update the specified line item curated category.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_item_curated_categories/:line_item_curated_category_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item curated category you are operating with in the request.
\| curated\_category\_id `optional` | A reference to the curated category entity you are operating with in the request.
Type: string
Example: `10miy` |
\| line\_item\_id `optional` | A reference to the line item you are operating with in the request.
Type: string
Example: `8v7jo` |
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/line_item_curated_categories/xq?curated_category_id=8tujl1p3yn0g`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_curated_category_id": "xq",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "iqwka",
"curated_category_id": "8tujl1p3yn0g",
"id": "xq",
"created_at": "2021-03-30T17:26:42Z",
"updated_at": "2021-03-30T18:22:52Z",
"deleted": true
}
}
```
#### DELETE accounts/:account\_id/line\_item\_curated\_categories/:line\_item\_curated\_category\_id[](#delete-accounts-account-id-line-item-curated-categories-line-item-curated-category-id "Permalink to this headline")
Delete the specified line item curated category.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/line_item_curated_categories/:line_item_curated_category_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item curated category you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/line_item_curated_categories/xq`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_curated_category_id": "xq",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "iqwka",
"curated_category_id": "9ddrgesiap6o",
"id": "xq",
"created_at": "2021-03-30T17:26:42Z",
"updated_at": "2021-03-30T18:22:52Z",
"deleted": true
}
}
```
### Line Item Placements
#### GET line\_items/placements[](#get-line-items-placements "Permalink to this headline")
Retrieve valid `placement` and `product_type` combinations.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/line_items/placements`
Scope the response to just the valid placements for the specified product type.
Possible values: `MEDIA`, `PROMOTED_ACCOUNT`, `PROMOTED_TWEETS`
**Example Request**
`GET https://ads-api.x.com/12/line_items/placements?product_type=PROMOTED_ACCOUNT`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"product_type": "PROMOTED_ACCOUNT",
"placements": [
[
"ALL_ON_TWITTER"
],
[
"TWITTER_TIMELINE"
]
]
}
],
"request": {
"params": {
"product_type": "PROMOTED_ACCOUNT"
}
}
}
```
### Media Creatives
#### GET accounts/:account\_id/media\_creatives[](#get-accounts-account-id-media-creatives "Permalink to this headline")
Retrieve details for some or all media creatives associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_creatives`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the media creatives associated with the specified campaign.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the media creatives associated with the specified line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Scope the response to just the desired media creatives by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/media_creatives?media_creative_ids=1bzq3`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_creative_ids": [
"1bzq3"
]
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "8v7jo",
"landing_url": "https://dev.x.com",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "1bzq3",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T06:00:42Z",
"account_media_id": "10miy",
"updated_at": "2019-01-11T20:21:26Z",
"approval_status": "ACCEPTED",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/media\_creatives/:media\_creative\_id[](#get-accounts-account-id-media-creatives-media-creative-id "Permalink to this headline")
Retrieves details for a specific media creative associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_creatives/:media_creative_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the media creative you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/media_creatives/1bzq3`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"media_creative_id": "1bzq3",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "8v7jo",
"landing_url": "https://dev.x.com",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "1bzq3",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T06:00:42Z",
"account_media_id": "10miy",
"updated_at": "2019-01-11T20:21:26Z",
"approval_status": "ACCEPTED",
"deleted": false
}
}
```
#### POST accounts/:account\_id/media\_creatives[](#post-accounts-account-id-media-creatives "Permalink to this headline")
Associate an [account media](/x-ads-api/creatives/reference#account-media) object with the specified line item.
Use this endpoint to promote in-stream ads (when the account media `creative_type` is `PREROLL`) or image ads (such as `BANNER` or `INTERSTITIAL`) on the Twitter Audience Platform.
**Note**: In order to add media assets to the Account Media resource, use the [POST accounts/:account\_id/media\_library](/x-ads-api/creatives/reference#account-media) endpoint.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_creatives`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the account media entity you are operating with in the request.
A reference to the line item you are operating with in the request.
The URL of the website to direct a user to. This should only be used with TAP images (or "display creatives"). This value will be ignored if used with preroll assets. To associate a URL with a preroll asset, use the [POST accounts/:account\_id/preroll\_call\_to\_actions](/x-ads-api/creatives/reference#post-accounts-account-id-preroll-call-to-actions) endpoint.
**Note**: Required when the line item's objective is set to `WEBSITE_CLICKS`.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/media_creatives?line_item_id=8v7jo&account_media_id=10miy`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_id": "8v7jo",
"account_media_id": "10miy",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "8v7jo",
"landing_url": "https://dev.x.com",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "1bzq3",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T06:00:42Z",
"account_media_id": "10miy",
"updated_at": "2019-01-11T20:21:26Z",
"approval_status": "ACCEPTED",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/media\_creatives/:media\_creative\_id[](#delete-accounts-account-id-media-creatives-media-creative-id "Permalink to this headline")
Delete the specified media creative belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_creatives/:media_creative_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the media creative you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/media_creatives/1bzq3`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"media_creative_id": "1bzq3",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "8v7jo",
"landing_url": "https://dev.x.com",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "1bzq3",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T06:00:42Z",
"account_media_id": "10miy",
"updated_at": "2021-04-16T21:02:55Z",
"approval_status": "ACCEPTED",
"deleted": true
}
}
```
### Promoted Accounts
#### GET accounts/:account\_id/promoted\_accounts[](#get-accounts-account-id-promoted-accounts "Permalink to this headline")
Retrieve details for some or all promoted accounts associated with one or more line items under the current account.
Use [GET users/lookup](https://developer.x.com/en/docs/x-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup) to obtain user data for the user accounts identified by `user_id` in the response.
An HTTP 400 will be returned if none of the specified line items are configured to contain promoted accounts.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_accounts`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the promoted accounts associated with the specified line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Scope the response to just the desired promoted accounts by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_accounts?promoted_account_ids=19pl2`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promoted_account_ids": [
"19pl2"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "9bpb2",
"user_id": "756201191646691328",
"id": "19pl2",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T05:54:13Z",
"updated_at": "2017-07-05T05:54:13Z",
"approval_status": "ACCEPTED",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/promoted\_accounts/:promoted\_account\_id[](#get-accounts-account-id-promoted-accounts-promoted-account-id "Permalink to this headline")
Retrieve a specific reference to an account associated with a line item under the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_accounts/:promoted_account_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the promoted account you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_accounts/19pl2`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promoted_account_id": "19pl2",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "9bpb2",
"user_id": "756201191646691328",
"id": "19pl2",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T05:54:13Z",
"updated_at": "2017-07-05T05:54:13Z",
"approval_status": "ACCEPTED",
"deleted": false
}
}
```
#### POST accounts/:account\_id/promoted\_accounts[](#post-accounts-account-id-promoted-accounts "Permalink to this headline")
Associate an account (`user_id`) with the specified line item.
If the specified line item is not configured to be associated with Promoted Accounts, an HTTP 400 `INCOMPATIBLE_LINE_ITEM` error will be returned. If the specified user is ineligible for promotion, an HTTP 400 will be returned and no users will be promoted. If the provided user is already promoted, the request will be ignored.
For more information on Promoted Accounts, see our [campaign management](/x-ads-api/campaign-management/reference#advertiser-api) page.
**Note**: It is not possible to update (PUT) promoted accounts entities.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_accounts`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
A reference to the user you are operating with in the request. Use [GET users/lookup](https://developer.x.com/en/docs/x-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-lookup) to retrieve a user ID for a screen name.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_accounts?line_item_id=9bpb2&user_id=756201191646691328`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "9bpb2",
"user_id": "756201191646691328",
"id": "19pl2",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T05:54:13Z",
"updated_at": "2017-07-05T05:54:13Z",
"approval_status": "ACCEPTED",
"deleted": false
},
"request": {
"params": {
"user_id": "756201191646691328",
"line_item_id": "9bpb2",
"account_id": "18ce54d4x5t"
}
}
}
```
#### DELETE accounts/:account\_id/promoted\_accounts/:promoted\_account\_id[](#delete-accounts-account-id-promoted-accounts-promoted-account-id "Permalink to this headline")
Disassociate an account from the specified line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_accounts/:promoted_account_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The identifier refers to the instance of a Promoted Account associated with a line item.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_accounts/19pl2`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "9bpb2",
"user_id": "756201191646691328",
"id": "19pl2",
"entity_status": "ACTIVE",
"created_at": "2017-07-05T05:54:13Z",
"updated_at": "2017-08-23T18:53:15Z",
"approval_status": "ACCEPTED",
"deleted": true
},
"request": {
"params": {
"promoted_account_id": "19pl2",
"account_id": "18ce54d4x5t"
}
}
}
```
### Promoted Tweets
#### GET accounts/:account\_id/promoted\_tweets[](#get-accounts-account-id-promoted-tweets "Permalink to this headline")
Retrieve references to Tweets associated with line items under the current account.
Use the [GET accounts/:account\_id/tweets](/x-ads-api/creatives/reference#get-accounts-account-id-tweets) endpoint to fetch the Tweet objects. Use the `tweet_id` values for each promoted\_tweets object.
**Note**: When parent line items are deleted, promoted\_tweets are only returned if `with_deleted=true` is specified in the request. These promoted\_tweets are not actually deleted, though (`"deleted": false` in the response).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the Tweets associated with specific line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Scope the response to just the desired promoted Tweets by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_tweets?promoted_tweet_ids=1efwlo`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promoted_tweet_ids": [
"1efwlo"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "96uzp",
"id": "1efwlo",
"entity_status": "ACTIVE",
"created_at": "2017-06-29T05:06:57Z",
"updated_at": "2017-06-29T05:08:46Z",
"approval_status": "ACCEPTED",
"tweet_id": "880290790664060928",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/promoted\_tweets/:promoted\_tweet\_id[](#get-accounts-account-id-promoted-tweets-promoted-tweet-id "Permalink to this headline")
Retrieve a specific reference to a Tweet associated with a line item under the current account.
**Note**: When parent line items are deleted, promoted\_tweets are only returned if `with_deleted=true` is specified in the request. These promoted\_tweets are not actually deleted, though (`"deleted": false` in the response).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_tweets/:promoted_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the promoted Tweet you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_tweets/1efwlo`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promoted_tweet_id": "1efwlo",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "96uzp",
"id": "1efwlo",
"entity_status": "ACTIVE",
"created_at": "2017-06-29T05:06:57Z",
"updated_at": "2017-06-29T05:08:46Z",
"approval_status": "ACCEPTED",
"tweet_id": "880290790664060928",
"deleted": false
}
}
```
#### POST accounts/:account\_id/promoted\_tweets[](#post-accounts-account-id-promoted-tweets "Permalink to this headline")
Associate one or more Tweets with the specified line item. Not all Tweets are appropriate for promotion, depending on the campaign objective. Please see [Objective-based Campaigns](/x-ads-api/campaign-management/reference#objective-based-campaigns) for more information.
When using the `PROMOTED_ACCOUNT` product type, associating a Tweet with the `line_item` will add timeline placements on mobile in addition to the standard `PROMOTED_ACCOUNT` placement.
**Note**: It is not possible to update (PUT) promoted Tweet entities.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
A comma-separated list of identifiers corresponding to specific Tweets. Up to 50 IDs may be provided.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_tweets?line_item_id=8v7jo&tweet_ids=822333526255120384`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"line_item_id": "8v7jo",
"id": "1e8i2k",
"entity_status": "ACTIVE",
"created_at": "2017-06-24T04:21:36Z",
"updated_at": "2017-06-24T04:21:36Z",
"approval_status": "ACCEPTED",
"tweet_id": "822333526255120384",
"deleted": false
}
],
"request": {
"params": {
"line_item_id": "8v7jo",
"tweet_ids": [
822333526255120384
],
"account_id": "18ce54d4x5t"
}
},
"total_count": 1
}
```
#### DELETE accounts/:account\_id/promoted\_tweets/:promoted\_tweet\_id[](#delete-accounts-account-id-promoted-tweets-promoted-tweet-id "Permalink to this headline")
Disassociate a Tweet from the specified line item.
**Note**: A deleted promoted\_tweets entity will be displayed as "Paused" in the ads.x.com UI. Similarly, "pausing" from the UI will disassociate the Tweet from its line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promoted_tweets/:promoted_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The identifier refers to the instance of a Promoted Tweet associated with a line item. This comes from the `id` field from a response item to [GET accounts/:account\_id/promoted\_tweets](#get-accounts-account-id-promoted-tweets), not the `tweet_id` of the Tweet in question. Supplied within the resource's path.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/promoted_tweets/1gp8a5`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "9pl99",
"id": "1gp8a5",
"entity_status": "ACTIVE",
"created_at": "2017-08-17T17:02:21Z",
"updated_at": "2017-08-18T06:43:48Z",
"approval_status": "ACCEPTED",
"tweet_id": "844796297743757315",
"deleted": true
},
"request": {
"params": {
"promoted_tweet_id": "1gp8a5",
"account_id": "18ce54d4x5t"
}
}
}
```
### Promotable Users
#### GET accounts/:account\_id/promotable\_users[](#get-accounts-account-id-promotable-users "Permalink to this headline")
Retrieve details for some or all promotable users associated with the current account.
The promotable user type is either `FULL` or `RETWEETS_ONLY`. This controls the type of content that is allowed to be promoted by the account. Advertisers must obtain permission to promote another user's content and contact Twitter to get them added to your account as a `RETWEETS_ONLY` promotable user.
Provided the permissions are set correctly, you can make requests to the promoted product endpoints that directly reference the Tweet ID of the Tweet you'd like to promote. You can use the [POST accounts/:account\_id/promoted-tweets](/x-ads-api/campaign-management/reference#promoted-tweets) endpoint to promote published Tweets and the [POST accounts/:account\_id/scheduled-promoted-tweets](/x-ads-api/campaign-management/reference#promoted-tweets) endpoint to promote another Twitter Ads account's Scheduled Tweets.
You do not have to retweet the target Tweet. When you promote a Tweet with this approach, the `tweet_id` that is returned will be different from the Tweet ID that was provided. Behind the scenes, the Tweet is being retweeted as a nullcasted Tweet and then promoted. The `tweet_id` that is returned corresponds to this new Tweet.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promotable_users`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired promotable users by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promotable_users?promotable_user_ids=l310s`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promotable_user_ids": [
"l310s"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"user_id": "756201191646691328",
"id": "l310s",
"created_at": "2016-07-21T22:42:09Z",
"updated_at": "2016-07-21T22:42:09Z",
"deleted": false,
"promotable_user_type": "FULL"
}
]
}
```
#### GET accounts/:account\_id/promotable\_users/:promotable\_user\_id[](#get-accounts-account-id-promotable-users-promotable-user-id "Permalink to this headline")
Retrieve a specific promotable user associated with the current account.
The promotable user type is either `FULL` or `RETWEETS_ONLY`. This controls the type of content that is allowed to be promoted by the account.
Advertisers must obtain permission to promote another user's content. Provided the permissions are set correctly, you can make requests to the promoted product endpoints that directly reference the Tweet ID of the Tweet you'd like to promote.
You do not have to retweet the target Tweet. When you promote a Tweet with this approach, the `tweet_id` that is returned will be different from the Tweet ID that was provided. Behind the scenes, the Tweet is being retweeted as a nullcasted Tweet and then promoted. The `tweet_id` that is returned corresponds to this new Tweet.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/promotable_users/:promotable_user_id`
A reference to the promotable user you are operating on within the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/promotable_users/l310s`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"promotable_user_id": "l310s",
"account_id": "18ce54d4x5t"
}
},
"data": {
"user_id": "2417045708",
"id": "l310s",
"created_at": "2017-03-10T17:51:24Z",
"updated_at": "2017-03-10T17:51:24Z",
"deleted": false,
"promotable_user_type": "RETWEETS_ONLY"
}
}
```
### Publishers
#### GET publishers[](#get-publishers "Permalink to this headline")
Retrieve a list of Content Category publishers' details
Additional details can be found in the [Video Views Preroll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective)
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/publishers`
**Parameters[](#parameters "Permalink to this headline")**
No request parameters
**Example Request**
`GET https://ads-api.x.com/12/publishers`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {}
},
"next_cursor": null,
"data": [
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "PeoplesSports",
"user_id": "1353868435021721602",
"monetization_restricted": true,
"content_category_ids": [
"se"
]
},
{
"monetizable_country_codes": [
"JP"
],
"promotion_eligible_country_codes": [
"JP"
],
"username": "NewYork_Jack",
"user_id": "1331177123436851206",
"monetization_restricted": true,
"content_category_ids": [
"sk"
]
},
{
"monetizable_country_codes": [
"JP"
],
"promotion_eligible_country_codes": [
"JP"
],
"username": "twispatv",
"user_id": "1331165719128461314",
"monetization_restricted": true,
"content_category_ids": [
"sm"
]
},
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "LAThieves",
"user_id": "1316808678897455105",
"monetization_restricted": true,
"content_category_ids": [
"s0"
]
},
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "Quicktake_EE",
"user_id": "1305900477427724290",
"monetization_restricted": true,
"content_category_ids": [
"sr"
]
},
{
"monetizable_country_codes": [
"BR"
],
"promotion_eligible_country_codes": [
"BR"
],
"username": "eufloribella",
"user_id": "1300812459054436354",
"monetization_restricted": true,
"content_category_ids": [
"sm"
]
},
{
"monetizable_country_codes": [
"EG"
],
"promotion_eligible_country_codes": [
"KW",
"EG",
"SA",
"AE",
"LB",
"QA"
],
"username": "Egypt2021EN",
"user_id": "1296077573399678977",
"monetization_restricted": true,
"content_category_ids": [
"se"
]
},
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "ClubShayShay",
"user_id": "1283068366706454529",
"monetization_restricted": true,
"content_category_ids": [
"se"
]
},
{
"monetizable_country_codes": [
"IN",
"KW",
"ID",
"EG",
"SG",
"TH",
"MY",
"PH",
"ES",
"US",
"AU",
"SA",
"AE",
"LB",
"GB",
"FR",
"KR",
"BR",
"MX",
"QA",
"CA",
"JP"
],
"promotion_eligible_country_codes": [
"KW",
"EG",
"SA",
"AE",
"LB",
"QA"
],
"username": "hiaahsanshow",
"user_id": "1253421442143641601",
"monetization_restricted": false,
"content_category_ids": [
"sh"
]
},
{
"monetizable_country_codes": [
"TH"
],
"promotion_eligible_country_codes": [
"TH"
],
"username": "HoneKrasae",
"user_id": "1240684293719904256",
"monetization_restricted": true,
"content_category_ids": [
"sr"
]
},
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "Sportskind",
"user_id": "1232708694418300930",
"monetization_restricted": true,
"content_category_ids": [
"se"
]
},
{
"monetizable_country_codes": [
"IN",
"KW",
"ID",
"EG",
"SG",
"TH",
"MY",
"PH",
"ES",
"US",
"AU",
"SA",
"AE",
"LB",
"GB",
"FR",
"KR",
"BR",
"MX",
"QA",
"CA",
"JP"
],
"promotion_eligible_country_codes": [
"KW",
"EG",
"SA",
"AE",
"LB",
"QA"
],
"username": "almeerathShow",
"user_id": "1229410512762437633",
"monetization_restricted": false,
"content_category_ids": [
"sh"
]
},
{
"monetizable_country_codes": [
"US"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "SeeYourVoiceFOX",
"user_id": "1225490734653947904",
"monetization_restricted": true,
"content_category_ids": [
"sh"
]
},
{
"monetizable_country_codes": [
"IN",
"KW",
"ID",
"EG",
"SG",
"TH",
"MY",
"PH",
"ES",
"US",
"AU",
"SA",
"AE",
"LB",
"GB",
"FR",
"KR",
"BR",
"MX",
"QA",
"CA",
"JP"
],
"promotion_eligible_country_codes": [
"US"
],
"username": "AUProSports",
"user_id": "1219303449768185859",
"monetization_restricted": false,
"content_category_ids": [
"se"
]
}
]
}
```
### Recommendations
#### GET accounts/:account\_id/recommendations[](#get-accounts-account-id-recommendations "Permalink to this headline")
Status: *Closed Beta*
Retrieve campaign recommendations associated with this ads account. Currently there is a limit of 1 recommendation per funding instrument.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/5/accounts/:account_id/recommendations`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
**Example Request**
`GET https://ads-api.x.com/5/accounts/18ce54d4x5t/recommendations`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"total_count": 1,
"data": [
{
"funding_instrument_id": "gpvzb",
"id": "62ce8zza1q0w",
"account_id": "18ce54d4x5t",
"status": "PENDING",
"message": "Recommendation for testing",
"created_at": "2016-11-14T23:07:54Z",
"updated_at": "2016-11-14T23:07:54Z"
}
]
```
#### GET accounts/:account\_id/recommendations/:recommendation\_id[](#get-accounts-account-id-recommendations-recommendation-id "Permalink to this headline")
Status: *Closed Beta*
Retrieve a specific campaign recommendation associated with this ads account.
The campaign recommendation contains a full set of changes suggested for the campaign structure represented as an object tree. The response tree is intended to work in conjunction with the Batch API endpoints, but it can also be mapped to single update endpoints as appropriate (Create for POST, Update for PUT, Delete for DELETE).
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/5/accounts/:account_id/recommendations/:recommendation_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the recommendation ID you are operating within the request.
**Example Request**
`GET https://ads-api.x.com/5/accounts/18ce54d4x5t/recommendations/62ce8zza1q0w`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"recommendation_id": "62ce8zza1q0w",
"account_id": "18ce54d4x5t"
}
},
"data_type": "recommendations",
"data": {
"changes": [
{
"entity_type": "campaigns",
"params": {
"start_time": "2016-11-08T22:00:00Z",
"daily_budget_amount_local_micro": 2200000,
"end_time": "2016-11-16T07:59:00Z",
"total_budget_amount_local_micro": 12000000,
"id": "64m0d"
},
"operation_type": "Update",
"dependent_entities": [
{
"entity_type": "line_items",
"params": {
"name": "Campaign for recommendations",
"placements": [
"TWITTER_TIMELINE"
],
"bid_amount_local_micro": 1430000,
"id": "6f5kq",
"include_sentiment": "ALL"
},
"operation_type": "Update",
"dependent_entities": [
{
"entity_type": "targeting_criteria",
"params": {
"id": "a8po6p"
},
"operation_type": null,
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "election results",
"targeting_value": "election results",
"targeting_type": "PHRASE_KEYWORD"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"id": "101ftp"
},
"operation_type": "Delete",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "Male",
"targeting_value": 1,
"targeting_type": "GENDER"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "San Francisco-Oakland-San Jose CA, US",
"targeting_value": "",
"targeting_type": "LOCATION"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"id": "101fto"
},
"operation_type": "Delete",
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"line_item_id": "6f5kq",
"display_properties": [],
"paused": false,
"approval_status": "ACCEPTED",
"tweet_id": "91125952589766656"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "Partner audience targeting",
"targeting_value": "v2cx",
"targeting_type": "NEGATIVE_BEHAVIOR"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "AGE_21_TO_34",
"targeting_value": "AGE_21_TO_34",
"targeting_type": "AGE"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"id": "a8po6o"
},
"operation_type": "Delete",
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"line_item_id": "6f5kq",
"display_properties": [],
"paused": false,
"approval_status": "ACCEPTED",
"tweet_id": "991101965843460096"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"line_item_id": "6f5kq",
"display_properties": [],
"paused": false,
"approval_status": "ACCEPTED",
"tweet_id": "991127212156096516"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "debate",
"targeting_value": "debate",
"targeting_type": "NEGATIVE_PHRASE_KEYWORD"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"line_item_id": "6f5kq",
"name": "60004, IL, US",
"targeting_value": "",
"targeting_type": "LOCATION"
},
"operation_type": "Create",
"dependent_entities": []
},
{
"entity_type": "targeting_criteria",
"params": {
"id": "a8po6n"
},
"operation_type": null,
"dependent_entities": []
},
{
"entity_type": "promoted_tweets",
"params": {
"id": "101ftn"
},
"operation_type": null,
"dependent_entities": []
}
]
}
]
}
],
"funding_instrument_id": "gpvzb",
"id": "62ce8zza1q0w",
"account_id": "18ce54d4x5t",
"status": "PENDING",
"message": "Recommendation for testing",
"created_at": "2016-11-14T23:07:54Z",
"updated_at": "2016-11-14T23:07:54Z"
}
}
```
### Scheduled Promoted Tweets
#### GET accounts/:account\_id/scheduled\_promoted\_tweets[](#get-accounts-account-id-scheduled-promoted-tweets "Permalink to this headline")
Retrieve details for some or all scheduled promoted Tweets associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_promoted_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the scheduled Tweets associated with specific line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Scope the response to just the desired scheduled promoted Tweets by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_promoted_tweets?scheduled_promoted_tweet_ids=1xboq`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"scheduled_promoted_tweet_ids": [
"1xboq"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "8xdpe",
"id": "1xboq",
"created_at": "2017-06-01T19:53:32Z",
"updated_at": "2017-06-01T20:00:06Z",
"scheduled_tweet_id": "870366669373194240",
"tweet_id": "870369382207070208",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/scheduled\_promoted\_tweets/:scheduled\_promoted\_tweet\_id[](#get-accounts-account-id-scheduled-promoted-tweets-scheduled-promoted-tweet-id "Permalink to this headline")
Retrieve a specific scheduled promoted Tweet associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_promoted_tweets/:scheduled_promoted_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the scheduled promoted Tweet you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_promoted_tweets/1xboq`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"scheduled_promoted_tweet_id": "1xboq",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "8xdpe",
"id": "1xboq",
"created_at": "2017-06-01T19:53:32Z",
"updated_at": "2017-06-01T20:00:06Z",
"scheduled_tweet_id": "870366669373194240",
"tweet_id": "870369382207070208",
"deleted": false
}
}
```
#### POST accounts/:account\_id/scheduled\_promoted\_tweets[](#post-accounts-account-id-scheduled-promoted-tweets "Permalink to this headline")
Associate a scheduled Tweet with the specified line item.
**Note**: It is not possible to update (PUT) scheduled promoted Tweet entities.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_promoted_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
A reference to the scheduled Tweet you are operating with in the request.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_promoted_tweets?line_item_id=8xdpe&scheduled_tweet_id=870358555227860992`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8xdpe",
"id": "1xtfl",
"created_at": "2017-06-08T07:25:26Z",
"updated_at": "2017-06-08T07:25:26Z",
"scheduled_tweet_id": "870358555227860992",
"tweet_id": null,
"deleted": false
},
"request": {
"params": {
"line_item_id": "8xdpe",
"scheduled_tweet_id": 870358555227860992,
"account_id": "18ce54d4x5t"
}
}
}
```
#### DELETE accounts/:account\_id/scheduled\_promoted\_tweets/:scheduled\_promoted\_tweet\_id[](#delete-accounts-account-id-scheduled-promoted-tweets-scheduled-promoted-tweet-id "Permalink to this headline")
Disassociate a scheduled Tweet from the specified line item.
**Note**: `scheduled_promoted_tweets` can only be deleted *before* the scheduled Tweet's `scheduled_at` time.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_promoted_tweets/:scheduled_promoted_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the scheduled promoted Tweet you are operating with in the request. This is the `id` attribute from a [GET accounts/:account\_id/scheduled\_promoted\_tweets](#get-accounts-account-id-scheduled-promoted-tweets) response object.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_promoted_tweets/1xtfl`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8xdpe",
"id": "1xtfl",
"created_at": "2017-06-08T07:25:26Z",
"updated_at": "2017-06-15T05:14:12Z",
"scheduled_tweet_id": "870358555227860992",
"tweet_id": null,
"deleted": true
},
"request": {
"params": {
"scheduled_promoted_tweet_id": "1xtfl",
"account_id": "18ce54d4x5t"
}
}
}
```
### Targeting Criteria
#### GET accounts/:account\_id/targeting\_criteria[](#get-accounts-account-id-targeting-criteria "Permalink to this headline")
Retrieve details for some or all of the targeting criteria associated with line items under the current account.
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the targeting criteria under the specified line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An [ISO-639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code. When passed, an additional `localized_name` attribute will be returned in the response for objects where a localized name is available.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Scope the response to just the desired targeting criteria by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/targeting_criteria?line_item_ids=8u94t`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"line_item_ids": [
"8u94t"
]
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "8u94t",
"name": "Custom audience targeting",
"id": "dpl3a6",
"operator_type": "EQ",
"created_at": "2017-05-26T03:29:35Z",
"targeting_value": "249yj",
"updated_at": "2017-05-26T03:29:35Z",
"deleted": false,
"targeting_type": "CUSTOM_AUDIENCE"
}
]
}
```
#### GET accounts/:account\_id/targeting\_criteria/:targeting\_criterion\_id[](#get-accounts-account-id-targeting-criteria-targeting-criterion-id "Permalink to this headline")
Retrieve a specific targeting criterion associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/targeting_criteria/:targeting_criterion_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the targeting criterion you are operating with in the request.
An [ISO-639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code. When passed, an additional `localized_name` attribute will be returned in the response for objects where a localized name is available.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/targeting_criteria/eijd4y`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"targeting_criterion_id": "eijd4y",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "619jl",
"name": "🤖",
"id": "eijd4y",
"created_at": "2017-07-06T16:51:04Z",
"targeting_value": "🤖",
"updated_at": "2017-07-06T16:51:04Z",
"deleted": false,
"targeting_type": "BROAD_KEYWORD"
}
}
```
#### POST accounts/:account\_id/targeting\_criteria[](#post-accounts-account-id-targeting-criteria "Permalink to this headline")
See the [Targeting Options](/x-ads-api/campaign-management/reference#targeting-options) page to find `targeting_value`s for specific targeting types. We recommend that you refresh all data weekly, to ensure that you are working with the latest set of targeting type values. We change values and available targeting criteria from time to time; while the majority of these don't change often, some do. There is no guarantee that these values will not change.
Use the `BROAD_KEYWORD`, `EXACT_KEYWORD`, `PHRASE_KEYWORD`, or `UNORDERED_KEYWORD` targeting types with the keywords specified in the `targeting_value`. Exclude keywords by using the `operator_type` request parameter set to `NE`. See [targeting keyword types](/x-ads-api/campaign-management/reference#targeting) for a detailed description of each type.
**Note**: It is only possible to target a single age bucket per line item.
**Note**: To target a Custom Audience, that audience must be targetable. i.e., `targerable` *must* equal `true`.
**Note**: When using targeting type `TV_SHOW`, there must be at least one `LOCATION` targeting criterion on the line item prior to setting the `TV_SHOW` targeting and all `LOCATION` must be within the same locale as the `TV_SHOW` being targeted.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/targeting_criteria`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
Specify the relationship that the targeting criterion should have. For example, to exclude keywords, use `operator_type=NE`.
Possible values: `EQ`, `NE`, `GTE`, `LT`
The type of targeting that will be applied to this line item.
**Note**: It is only possible to target a single `AGE` bucket per line item.
Possible keyword-based values include: `BROAD_KEYWORD`, `EXACT_KEYWORD`, `PHRASE_KEYWORD`, `UNORDERED_KEYWORD`.
Possible custom audience values include: `CUSTOM_AUDIENCE`, `CUSTOM_AUDIENCE_EXPANDED`.
Possible installed app store category values: `APP_STORE_CATEGORY`, `APP_STORE_CATEGORY_LOOKALIKE`.
Possible Twitter Audience Platform (TAP) app exclusion: `APP_LIST` (may only be used with `operator_type=NE`).
Specify which user, which interest, which location, which event, which platform, which platform version, which device, which keyword or phrase, which gender, which custom audience, which app store category, or which exclusion of an app list this targeting will be applied to, depending on the selected targeting\_type.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/targeting_criteria?line_item_id=619jl&targeting_type=BROAD_KEYWORD&targeting_value=technology`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "619jl",
"name": "technology",
"id": "fbyjlr",
"created_at": "2017-09-06T07:31:21Z",
"targeting_value": "technology",
"updated_at": "2017-09-06T07:31:21Z",
"deleted": false,
"targeting_type": "BROAD_KEYWORD"
},
"request": {
"params": {
"line_item_id": "619jl",
"targeting_type": "BROAD_KEYWORD",
"targeting_value": "technology",
"account_id": "18ce54d4x5t"
}
}
}
```
#### POST batch/accounts/:account\_id/targeting\_criteria[](#post-batch-accounts-account-id-targeting-criteria "Permalink to this headline")
Allows the batch creation of new Targeting Criteria with a single request.
**Batch Requests**
* The current maximum batch size is 500.
* All parameters are sent in the request body and a `Content-Type` of `application/json` is required.
* Batch requests fail or succeed together as a group and all API responses for both error and success preserve the item order of the initial request.
**Batch Responses**
Batch API responses return an ordered collection of items. Otherwise, they are identical in structure to their corresponding single-item endpoints.
**Batch Errors**
* Request-level errors (eg. max batch size exceeded) are shown in the response under the `errors` object.
* Item-level errors (eg. missing required Targeting Criteria parameter) are shown in the response under the `operation_errors` object.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/batch/accounts/:account_id/targeting_criteria`
The per item operation type being performed.
Possible values: `Create`, `Delete`
A JSON object containing all the parameters for the targeting criteria objects. For a list of required and optional targeting criteria parameters, see [here](#post-accounts-account-id-targeting-criteria).
In addition, this endpoint supports an `operator_type` parameter that works in conjunction with certain `targeting_type` values. The possible values for this parameter are `EQ` for equal to, `GTE` for greater than or equal to, `LT` for less than, and `NE` for not equal to.
**Example Request**
`POST https://ads-api.x.com/12/batch/accounts/18ce54d4x5t/targeting_criteria`
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
[
{
"operation_type":"Create",
"params":{
"line_item_id":"6f9an",
"targeting_type":"LOCATION",
"targeting_value":"5122804691e5fecc"
}
},
{
"operation_type":"Delete",
"params":{
"targeting_criterion_id":"al2rua"
}
}
]
```
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data_type": "targeting_criterion",
"data": [
{
"line_item_id": "6f9an",
"name": "San Francisco-Oakland-San Jose CA, US",
"id": "al7vt2",
"location_type": "CITY",
"operator_type": "EQ",
"created_at": "2016-11-11T22:59:50Z",
"targeting_value": "5122804691e5fecc",
"updated_at": "2016-11-11T22:59:50Z",
"deleted": false,
"targeting_type": "LOCATION"
},
{
"line_item_id": "6keuo",
"name": "accounts",
"id": "al2rua",
"operator_type": "EQ",
"created_at": "2016-11-11T17:50:19Z",
"targeting_value": "accounts",
"updated_at": "2016-11-11T22:59:50Z",
"deleted": true,
"targeting_type": "BROAD_KEYWORD"
}
],
"request": [
{
"params": {
"line_item_id": "6f9an",
"targeting_type": "LOCATION",
"targeting_value": "5122804691e5fecc",
"account_id": "18ce54d4x5t"
},
"operation_type": "Create"
},
{
"params": {
"targeting_criterion_id": "al2rua",
"account_id": "18ce54d4x5t"
},
"operation_type": "Delete"
}
]
}
```
#### DELETE accounts/:account\_id/targeting\_criteria/:targeting\_criterion\_id[](#delete-accounts-account-id-targeting-criteria-targeting-criterion-id "Permalink to this headline")
Delete the specified targeting criterion belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/targeting_criteria/:targeting_criterion_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the targeting criterion you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/targeting_criteria/dpl3a6`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8u94t",
"name": "Custom audience targeting",
"id": "dpl3a6",
"created_at": "2017-05-26T03:29:35Z",
"targeting_value": "249yj",
"updated_at": "2017-08-30T18:38:58Z",
"deleted": true,
"targeting_type": "CUSTOM_AUDIENCE"
},
"request": {
"params": {
"targeting_criterion_id": "dpl3a6",
"account_id": "18ce54d4x5t"
}
}
}
```
### Targeting Options
* [App Store Categories](#get-targeting-criteria-app-store-categories)
* [Conversation](#get-targeting-criteria-conversations)
* [Devices](#get-targeting-criteria-devices)
* [Events](#get-targeting-criteria-events)
* [Interests](#get-targeting-criteria-interests)
* [Languages](#get-targeting-criteria-languages)
* [Locations](#get-targeting-criteria-locations)
* [Network Operators](#get-targeting-criteria-network-operators)
* [Platform Versions](#get-targeting-criteria-platform-versions)
* [Platforms](#get-targeting-criteria-platforms)
* [TV Markets](#get-targeting-criteria-tv-markets)
* [TV Shows](#get-targeting-criteria-tv-shows)
#### GET targeting\_criteria/app\_store\_categories[](#get-targeting-criteria-app-store-categories "Permalink to this headline")
Discover available app store category-based targeting criteria for Promoted Products. App store categories are available for the iOS App Store and the Google Play store only.
Installed app category targeting allows targeting of users based on the categories of apps they have installed or have indicated interest in.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/app_store_categories`
An optional query to scope a targeting criteria. Omit this parameter to retrieve all.
Scope the results by a specific app store.
Possible values: `ANDROID`, `IOS`
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/app_store_categories?q=music&os_type=IOS`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "Games: Music",
"targeting_type": "APP_STORE_CATEGORY",
"targeting_value": "qouq",
"os_type": "IOS"
},
{
"name": "Music",
"targeting_type": "APP_STORE_CATEGORY",
"targeting_value": "qov2",
"os_type": "IOS"
}
],
"request": {
"params": {
"q": "music",
"os_type": "IOS"
}
}
}
```
#### GET targeting\_criteria/conversations[](#get-targeting-criteria-conversations "Permalink to this headline")
Discover available conversation-based targeting criteria for Promoted Products.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/conversations`
An optional query to scope to a certain conversation type.
Possible values: `ACTORS`, `ATHLETES`, `BOOK_GENRES`, `BOOKS`, `BRAND_CATEGORIES`, `BRANDS`, `CELEBRITIES`, `COACHES`, `DIGITAL_CREATORS`, `ENTERTAINMENT_BRANDS`, `ENTERTAINMENT_PERSONALITIES`, `FICTIONAL_CHARACTERS`, `JOURNALISTS`, `LIFESTYLES`, `MOVIE_GENRES`, `MOVIES`, `MUSIC_GENRES`, `MUSICIANS`, `NEWS_STORIES`, `NEWS`, `PERSONS`, `PLACES`, `PODCASTS`, `POLITICAL_AFFILIATIONS`, `POLITICIANS`, `PRODUCTS`, `RADIO_STATIONS`, `SPORTS_LEAGUES`, `SPORTS_PERSONALITIES`, `SPORTS_TEAMS`, `SPORTS`, `TRENDS`, `TV_SHOWS`, `VIDEO_GAME_PLATFORMS`, `VIDEO_GAME_PUBLISHERS`, `VIDEO_GAMES`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/conversations?count=2`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"count": 2
}
},
"next_cursor": "1f7m7",
"data": [
{
"targeting_type": "CONVERSATION",
"targeting_value": "a1",
"name": "NFL",
"conversation_type": "SPORTS"
},
{
"targeting_type": "CONVERSATION",
"targeting_value": "a2",
"name": "NBA",
"conversation_type": "SPORTS"
}
]
}
```
#### GET targeting\_criteria/devices[](#get-targeting-criteria-devices "Permalink to this headline")
Discover available device-based targeting criteria for Promoted Products. Device targeting is available for Promoted Tweets.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/devices`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
An optional query to scope a targeting criteria. Omit this parameter to retrieve all.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/devices?count=2&q=iphone`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "iPhone 3GS",
"manufacturer": "Apple",
"os_type": "iOS",
"targeting_value": "1q",
"targeting_type": "DEVICE"
},
{
"name": "iPhone 4",
"manufacturer": "Apple",
"os_type": "iOS",
"targeting_value": "1r",
"targeting_type": "DEVICE"
}
],
"request": {
"params": {
"q": "iphone",
"count": 2
}
}
}
```
#### GET targeting\_criteria/events[](#get-targeting-criteria-events "Permalink to this headline")
Discover available event-based targeting criteria for Promoted Products. Only one event can be targeted per line item.
**Note**: Events often exist across timezones, leading to complications when considering event times from cross-timezone perspectives. To simplify this, all event `start_time` and `end_time` values on this endpoint are represented in UTC±00:00, irrespective of the event's locale and timezone. This design should be kept in mind when querying and interacting with event `start_time` and `end_time` values. For example, Independence Day for the US is represented as `start_time=2017-07-04T00:00:00Z` and `end_time=2017-07-05T00:00:00Z` in UTC±00:00, and thus avoids the issue of this holiday existing across multiple timezones within the US.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/events`
An optional query to scope to certain event types.
Possible values: `CONFERENCE`, `HOLIDAY`, `MUSIC_AND_ENTERTAINMENT`, `OTHER`, `POLITICS`, `RECURRING`, `SPORTS`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
An optional query to scope a targeting criteria search to particular countries with the 2 letter ISO country code. If this parameter is not specified, all events are returned.
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the campaign will end.
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the line item will begin serving.
**Note**: Defaults to the current time.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/events?count=1`
**Example Response**
```json title="HOLIDAY" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"count": 1
}
},
"data_type": "events",
"data": [
{
"reach": {
"total_reach": null
},
"name": "New Year's",
"start_time": "2017-12-31T00:00:00Z",
"top_users": [],
"top_tweets": [],
"top_hashtags": [],
"gender_breakdown_percentage": {},
"end_time": "2018-01-02T00:00:00Z",
"country_code": null,
"device_breakdown_percentage": {},
"targeting_value": "1ex",
"is_global": true,
"event_type": "HOLIDAY",
"country_breakdown_percentage": {}
}
],
"next_cursor": "uww0"
}
```
#### GET targeting\_criteria/interests[](#get-targeting-criteria-interests "Permalink to this headline")
Discover available interest-based targeting criteria for Promoted Products. Interests change infrequently, however we suggest you refresh this list at least once weekly.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/interests`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope a targeting criteria. Omit this parameter to retrieve all.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/interests?q=books`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "Books and literature/Biographies and memoirs",
"targeting_type": "INTEREST",
"targeting_value": "1001"
}
],
"request": {
"params": {
"q": "books",
"count": 1
}
},
"next_cursor": "6by4n4"
}
```
#### GET targeting\_criteria/languages[](#get-targeting-criteria-languages "Permalink to this headline")
Discover languages available for targeting.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/languages`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope a targeting criteria. Omit this parameter to retrieve all.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/languages?q=english`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "English",
"targeting_type": "LANGUAGE",
"targeting_value": "en"
}
],
"request": {
"params": {
"q": "english"
}
},
"next_cursor": null
}
```
#### GET targeting\_criteria/locations[](#get-targeting-criteria-locations "Permalink to this headline")
Discover available location-based targeting criteria for Promoted Products. Geo-targeting is available for Promoted Accounts and Promoted Tweets at the country level, state/region level, city level, and postal code level. Postal code targeting must be used if you wish to retrieve analytics at the postal code level.
**Note**: To retrieve specific targetable cities, such as San Francisco or New York, use the `CITIES` enum with the `location_type` request parameter.
To target Designated Market Areas (DMAs), use the `METROS` enum.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/locations`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
An optional query to scope a targeting criteria search to a specific country with the 2 letter ISO country code. Omit this parameter to retrieve results for all countries.
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the results by a specific kind of location. More granular targeting than `COUNTRIES` may not be available in all locations.
Possible values: `COUNTRIES`, `REGIONS`, `METROS`, `CITIES`, `POSTAL_CODES`
An optional query to scope a targeting criteria search. Omit this parameter to retrieve all results.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/locations?location_type=CITIES&q=los angeles`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "Los Angeles, Los Angeles CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "3b77caf94bfc81fe",
"targeting_type": "LOCATION"
},
{
"name": "East Los Angeles, Los Angeles CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "67571a7baaa5906b",
"targeting_type": "LOCATION"
},
{
"name": "Lake Los Angeles, Los Angeles CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "ea9bfbd43c93400f",
"targeting_type": "LOCATION"
},
{
"name": "Los Gatos, San Francisco-Oakland-San Jose CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "a2de7c70b82b0ca0",
"targeting_type": "LOCATION"
},
{
"name": "Los Altos, Monterey-Salinas CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "6a4364ea6f987c10",
"targeting_type": "LOCATION"
},
{
"name": "Los Banos, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "b1b6fc646de75904",
"targeting_type": "LOCATION"
},
{
"name": "Los Alamitos, Los Angeles CA, CA, USA",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "0799ff0a3c1006e9",
"targeting_type": "LOCATION"
},
{
"name": "Los Angeles, US",
"country_code": "US",
"location_type": "CITIES",
"targeting_value": "019940ae78c7b3bc",
"targeting_type": "LOCATION"
}
],
"request": {
"params": {
"location_type": "CITIES",
"q": "los angeles"
}
},
"next_cursor": null
}
```
#### GET targeting\_criteria/network\_operators[](#get-targeting-criteria-network-operators "Permalink to this headline")
Discover available network operator-based targeting criteria for Promoted Products.
This endpoint enables you to lookup targetingable carriers, such as AT\&T, Verizon, Sprint, T-Mobile, etc., in multiple countries.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/network_operators`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
An optional query to scope a targeting criteria search to a specific country with the 2 letter ISO country code. If this parameter is not specified only partner audiences for the United States are returned.
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope a targeting criteria search. Omit this parameter to retrieve all results.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/network_operators?count=5&country_code=US`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"country_code": "US",
"targeting_type": "NETWORK_OPERATOR",
"name": "Advantage",
"targeting_value": "2l"
},
{
"country_code": "US",
"targeting_type": "NETWORK_OPERATOR",
"name": "Aeris",
"targeting_value": "1b"
},
{
"country_code": "US",
"targeting_type": "NETWORK_OPERATOR",
"name": "Airadigm",
"targeting_value": "2t"
},
{
"country_code": "US",
"targeting_type": "NETWORK_OPERATOR",
"name": "Airlink PCS",
"targeting_value": "14"
},
{
"country_code": "US",
"targeting_type": "NETWORK_OPERATOR",
"name": "Airpeak",
"targeting_value": "1i"
}
],
"request": {
"params": {
"country_code": "US",
"count": 5
}
},
"next_cursor": "o7x9iet1a5u608olj4"
}
```
#### GET targeting\_criteria/platform\_versions[](#get-targeting-criteria-platform-versions "Permalink to this headline")
Discover available mobile OS version-based targeting criteria for Promoted Products. Platform version targeting is available for Promoted Accounts and Promoted Tweets. This allows targeting down to the point release of a mobile operating system version, such as Android 8.0 or iOS 10.0.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/platform_versions`
An optional query to scope a targeting criteria search. Omit this parameter to retrieve all results.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/platform_versions`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{...},
{
"name": "Ice Cream Sandwich",
"number": "4.0",
"os_type": "Android",
"targeting_type": "PLATFORM_VERSION",
"targeting_value": "17"
},
{
"name": "Jelly Bean",
"number": "4.1",
"os_type": "Android",
"targeting_type": "PLATFORM_VERSION",
"targeting_value": "18"
},
{...}
],
"data_type": "targeting_criterion",
"request": {
"params": {}
}
}
```
#### GET targeting\_criteria/platforms[](#get-targeting-criteria-platforms "Permalink to this headline")
Discover available platform-based targeting criteria for Promoted Products.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/platforms`
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
An optional query to scope a targeting criteria search. Omit this parameter to retrieve all results.
Using a [ISO-639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code. When passed, an additional localized\_name attribute will be returned in the response.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/platforms`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "iOS",
"targeting_type": "PLATFORM",
"targeting_value": "0"
},
{
"name": "Android",
"targeting_type": "PLATFORM",
"targeting_value": "1"
},
{
"name": "BlackBerry phones and tablets",
"targeting_type": "PLATFORM",
"targeting_value": "2"
},
{
"name": "Mobile web on other devices",
"targeting_type": "PLATFORM",
"targeting_value": "3"
},
{
"name": "Desktop and laptop computers",
"targeting_type": "PLATFORM",
"targeting_value": "4"
}
],
"request": {
"params": {}
}
}
```
#### GET targeting\_criteria/tv\_markets[](#get-targeting-criteria-tv-markets "Permalink to this headline")
Discover available TV markets where TV shows can be targeted. Returns markets by locale that can used to query the [GET targeting\_criteria/tv\_shows](/x-ads-api/campaign-management/reference#get-targeting-criteria-tv-shows) endpoint.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/tv_markets`
**Parameters[](#parameters "Permalink to this headline")**
None
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/tv_markets`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "France",
"country_code": "FR",
"locale": "fr-FR"
},
{
"name": "Chile",
"country_code": "CL",
"locale": "es-CL"
},
{
"name": "Germany",
"country_code": "DE",
"locale": "de-DE"
},
{
"name": "Netherlands",
"country_code": "NL",
"locale": "nl-NL"
},
{
"name": "United States",
"country_code": "US",
"locale": "en-US"
},
{
"name": "Venezuela",
"country_code": "VE",
"locale": "es-VE"
},
{
"name": "Brazil",
"country_code": "BR",
"locale": "pt-BR"
},
{
"name": "Mexico",
"country_code": "MX",
"locale": "es-MX"
},
{
"name": "Colombia",
"country_code": "CO",
"locale": "es-CO"
},
{
"name": "United Kingdom",
"country_code": "GB",
"locale": "en-GB"
},
{
"name": "Argentina",
"country_code": "AR",
"locale": "es-AR"
},
{
"name": "Japan",
"country_code": "JP",
"locale": "ja-JP"
},
{
"name": "Canada",
"country_code": "CA",
"locale": "en-CA"
},
{
"name": "Spain",
"country_code": "ES",
"locale": "es-ES"
},
{
"name": "Italy",
"country_code": "IT",
"locale": "it-IT"
},
{
"name": "United States - Hispanic",
"country_code": "US",
"locale": "es-US"
},
{
"name": "Ireland",
"country_code": "IE",
"locale": "en-IE"
}
],
"request": {
"params": {}
}
}
```
#### GET targeting\_criteria/tv\_shows[](#get-targeting-criteria-tv-shows "Permalink to this headline")
Discover available TV show-based targeting criteria for Promoted Products. TV show targeting is available for Promoted Tweets in certain markets. See the [GET targeting\_criteria/tv\_markets](/x-ads-api/campaign-management/reference#get-targeting-criteria-tv-markets) endpoint for available markets.
**Note**: Any audience that contains fewer than 1,000 users will appear with an `estimated_users` value of `1000`.
**Note**: TV channel and genre targeting options are no longer supported.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/targeting_criteria/tv_shows`
A required parameter that specifies the tv\_market\_locale to query for available TV shows. TV markets are queried based on `locale` returned from the [GET targeting\_criteria/tv\_markets](/x-ads-api/campaign-management/reference#get-targeting-criteria-tv-markets).
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 50
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope a targeting criteria search. Omit this parameter to retrieve all results.
**Example Request**
`GET https://ads-api.x.com/12/targeting_criteria/tv_shows?locale=en-US&q=news&count=1`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"name": "NewsWatch",
"targeting_value": 10027243420,
"genre": "PAID",
"locales": [
{
"language": "en",
"country": "US"
}
]
}
],
"next_cursor": "c-22838-zdQDJrTxSvOYfQOhb2IlGQ",
"request": {
"params": {
"locale": {
"countryCode": "US",
"languageCode": "en"
},
"count": 1,
"q": "news"
}
}
}
```
### Targeting Suggestions
#### GET accounts/:account\_id/targeting\_suggestions[](#get-accounts-account-id-targeting-suggestions "Permalink to this headline")
Get up to 50 keyword or user targeting suggestions to complement your initial selection.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/targeting_suggestions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specify the type of suggestions to return.
Possible values: `KEYWORD`, `USER_ID`
Comma separated collection of either keywords or user IDs used to seed the suggestions.
**Note**: These two types of suggestions cannot be mixed.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 50
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/targeting_suggestions?suggestion_type=KEYWORD&targeting_values=developers&count=2"`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": [
{
"suggestion_type": "KEYWORD",
"suggestion_value": "devs"
},
{
"suggestion_type": "KEYWORD",
"suggestion_value": "software"
}
],
"request": {
"params": {
"suggestion_type": "KEYWORD",
"targeting_values": [
"developers"
],
"count": 2,
"account_id": "18ce54d4x5t"
}
}
}
```
### Tax Settings
#### GET accounts/:account\_id/tax\_settings[](#get-accounts-account-id-tax-settings "Permalink to this headline")
Retrieve tax setting details associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tax_settings`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/tax_settings`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"data": {
"tax_id": "GB896391250",
"address_city": "London",
"business_relationship": "SELF",
"address_street1": "21 March St",
"address_last_name": null,
"address_company": "ABC, Inc.",
"tax_category": "BUSINESS_WITH_VAT",
"address_postal_code": "SW1A 1AA",
"bill_to": "NOT_SET",
"address_region": "London",
"address_country": "GB",
"address_first_name": null,
"invoice_jurisdiction": "NOT_SET",
"address_street2": null,
"address_email": null
}
}
```
#### PUT accounts/:account\_id/tax\_settings[](#put-accounts-account-id-tax-settings "Permalink to this headline")
Update the tax settings for the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tax_settings`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The city for the account owner's address.
The two-letter country code for the account owner's address.
The email associated with the account owner's address.
The first name for the account owner's address.
The last name for the account owner's address.
The company name for the account owner's address.
The postal code for the account owner's address.
The region for the account owner's address.
The street line for the account owner's address.
The second street line for the account owner's address.
The entity that is billed.
Possible values: `ADVERTISER`, `AGENCY`
Whether the account is owned by the advertiser or by the agency.
Possible values: `AGENCY`, `SELF`
The city for the advertiser's address.
Set this when the ads account is owned by an agency.
The two-letter country code for the advertiser's address.
Set this when the ads account is owned by an agency.
The email associated with the advertiser's address.
Set this when the ads account is owned by an agency.
The first name for the advertiser's address.
Set this when the ads account is owned by an agency.
The last name for the advertiser's address.
Set this when the ads account is owned by an agency.
The company name for the advertiser's address.
Set this when the ads account is owned by an agency.
The postal code for the advertiser's address.
Set this when the ads account is owned by an agency.
The region for the advertiser's address.
Set this when the ads account is owned by an agency.
The street line for the advertiser's address.
Set this when the ads account is owned by an agency.
The second street line for the advertiser's address.
Set this when the ads account is owned by an agency.
Invoice jurisdiction.
Possible values: `LOI_SAPIN`, `NONE`, `NOT_SET`
Whether the taxation should be individual or business.
Possible values: `BUSINESS_NO_VAT`, `BUSINESS_WITH_VAT`, `INDIVIDUAL`
VAT exemption ID.
VAT registration ID.
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/tax_settings?address_name=ABC, Co.`
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"address_name": "ABC Co."
}
},
"data": {
"tax_id": "GB896391250",
"address_city": "London",
"business_relationship": "SELF",
"address_street1": "21 March St",
"address_last_name": null,
"address_company": "ABC, Co.",
"tax_category": "BUSINESS_WITH_VAT",
"address_postal_code": "SW1A 1AA",
"bill_to": "NOT_SET",
"address_region": "London",
"address_country": "GB",
"address_first_name": null,
"invoice_jurisdiction": "NOT_SET",
"address_street2": null,
"address_email": null
}
}
```
### Tracking Tags
#### GET accounts/:account\_id/tracking\_tags[](#get-accounts-account-id-tracking-tags "Permalink to this headline")
Retrieve details for some or all tracking tags associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tracking_tags`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the tracking tags associated with specific line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Scope the response to just the desired tracking tags by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/tracking_tags?tracking_tag_ids=3m82`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"tracking_tag_ids": [
"3m82"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "fdwcl",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309",
"tracking_tag_type": "IMPRESSION_TAG",
"id": "3m82",
"created_at": "2019-06-26T17:04:26Z",
"updated_at": "2019-06-26T17:04:26Z",
"deleted": false
}
]
}
```
#### GET accounts/:account\_id/tracking\_tags/:tracking\_tag\_id[](#get-accounts-account-id-tracking-tags-tracking-tag-id "Permalink to this headline")
Retrieve a specific tracking tag associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tracking_tags/:tracking_tag_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the tracking tag you are operating with in the request.
Include deleted results in your request.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/tracking_tags/555j`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"with_deleted": true,
"tracking_tag_id": "555j",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "72v2x",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N6344.2061500TWITTER-OFFICIAL/B23028778.279118262;dc_trk_aid=473354132;dc_trk_cid=119658253",
"tracking_tag_type": "IMPRESSION_TAG",
"id": "555j",
"created_at": "2020-08-13T23:02:03Z",
"updated_at": "2020-08-13T23:02:03Z",
"deleted": false
}
}
```
#### POST accounts/:account\_id/tracking\_tags[](#post-accounts-account-id-tracking-tags "Permalink to this headline")
Associate a tracking tag with the specified line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tracking_tags`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the line item you are operating with in the request.
The type of tracking tag.
Possible value: `IMPRESSION_TAG`, `CLICK_TRACKER`
The tracking tag url provided by the tracking partner.
**Example Request**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/tracking_tags?line_item_id=fdwcl&tracking_tag_type=IMPRESSION_TAG&tracking_tag_url=https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"line_item_id": "fdwcl",
"tracking_tag_type": "IMPRESSION_TAG",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "fdwcl",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309",
"tracking_tag_type": "IMPRESSION_TAG",
"id": "3m82",
"created_at": "2019-06-26T17:04:26Z",
"updated_at": "2019-06-26T17:04:26Z",
"deleted": false
}
}
```
#### PUT accounts/:account\_id/tracking\_tags/:tracking\_tag\_id[](#put-accounts-account-id-tracking-tags-tracking-tag-id "Permalink to this headline")
Associate a tracking tag with the specified line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tracking_tags/:tracking_tag_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The tracking tag url provided by the tracking partner.
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/tracking_tags/3m82?tracking_tag_url=https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"tracking_tag_id": "3m82",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "fdwcl",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N1234.2061500TWITTER-OFFICIAL/B9156151.125630439;dc_trk_aid=1355;dc_trk_cid=8675309",
"tracking_tag_type": "IMPRESSION_TAG",
"id": "3m82",
"created_at": "2019-06-26T17:04:26Z",
"updated_at": "2022-01-26T17:04:26Z",
"deleted": false
}
}
```
#### DELETE accounts/:account\_id/tracking\_tags/:tracking\_tag\_id[](#delete-accounts-account-id-tracking-tags-tracking-tag-id "Permalink to this headline")
Disassociate a tracking tag from the specified line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tracking_tags/:tracking_tag_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the tracking tag you are operating with in the request.
**Example Request**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/tracking_tags/555j`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"tracking_tag_id": "555j",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "72v2x",
"tracking_tag_url": "https://ad.doubleclick.net/ddm/trackimp/N6344.2061500TWITTER-OFFICIAL/B23028778.279118262;dc_trk_aid=473354132;dc_trk_cid=119658253",
"tracking_tag_type": "IMPRESSION_TAG",
"id": "555j",
"created_at": "2020-08-13T23:02:03Z",
"updated_at": "2021-08-29T17:12:58Z",
"deleted": true
}
}
```
### User Settings
([https://app.getpostman.com/run-collection/1d12b9fc623b8e149f87](https://app.getpostman.com/run-collection/1d12b9fc623b8e149f87))
#### GET accounts/:account\_id/user\_settings/:user\_id[](#get-accounts-account-id-user-settings-user-id "Permalink to this headline")
Retrieves user settings.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/user_settings/:user_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the user you are operating with in the request. Use GET users/lookup to retrieve a user ID for a screen name.
**Example Request**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/user_settings/756201191646691328`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"user_id": "756201191646691328"
}
},
"data": {
"notification_email": "user@domain.com",
"contact_phone": "",
"contact_phone_extension": ""
}
}
```
#### PUT accounts/:account\_id/user\_settings/:user\_id[](#put-accounts-account-id-user-settings-user-id "Permalink to this headline")
Updates user settings. Requires user context. Not accessible by account admins.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/user_settings/:user_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the user you are operating with in the request. Use GET users/lookup to retrieve a user ID for a screen name.
Email to use for account notifications.
Contact phone number.
Extension for contact `contact_phone`.
**Example Request**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/user_settings/756201191646691328?notification_email='user@domain.com'&subscribe_email_types=ACCOUNT_PERFORMANCE,PERFORMANCE_IMPROVEMENT"`
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"user_id": "756201191646691328"
"notification_email": "user@domain.com",
"subscribed_campaign_events": [
"ACCOUNT_PERFORMANCE",
"PERFORMANCE_IMPROVEMENT"
]
}
},
"data": {
"notification_email": "user@domain.com",
"contact_phone": "",
"Contact_phone_extension": ""
}
}
```
# Catalog Management
Source: https://docs.x.com/x-ads-api/catalog-management
Set up product catalogs, manage products in bulk, create product sets for targeting, and configure scheduled feeds for Dynamic Product Ads on X.
**Programmatically manage product catalogs, products, product sets, and scheduled feeds for Dynamic Product Ads.**
## Quick links
* [Full API Reference](/x-ads-api/catalog-management/reference) — All Catalog Management endpoints and objects
* [Product Specifications Guide](https://business.x.com/en/help/shopping-specs.html) — Detailed product feed requirements and best practices
## Overview
The Catalog API is a commerce solution that gives advertisers the ability to set up product feeds, group products into sets, and holistically manage catalog products. The Catalog API enables programmatic catalog management and grants advertisers more control over how their catalogs are ingested and updated.
A catalog holds everything regarding the user's product and product set and is associated with the user's handle. **Currently, one user can only create one catalog.**
The Catalog API supports two ways to ingest products:
1. **Scheduled Feed**: Add a feed URL (CSV, TSV, or XML) that will be periodically fetched. X supports files up to 8GB.
2. **Batch Products API**: View, create, update, and delete product attributes with batch (JSON) requests.
X merchants can create product sets based on filter rules. This allows attaching additional metadata to products and creating special product sets for organic commerce features or Dynamic Product Ads. The Catalog API and X Shopping Manager support two types of product sets:
1. **Manual**: Select up to 50 products and set a name and description.
2. **Filter**: Add up to 30 filters to automatically generate sets (price, Google product category, product type, inventory, sale price, custom fields, etc.).
### Prerequisites
Catalog API endpoints are currently available via **early-access only**. To apply for access, please reach out to your X representative or fill out the appropriate form.
You must accept the terms of service via [X Shopping Manager](https://ads.x.com/shopping_manager).
For product specifications and Shopping Manager details, see the [Product specifications guide](https://business.x.com/en/help/shopping-specs.html).
### Rate Limits
#### Product Catalog
| Endpoint | Rate limit |
| :-------------------------------------------------------------------------------------------------------------------------------------- | :------------------- |
| [GET /product\_catalogs](/x-ads-api/catalog-management/reference#get-product_catalogs) | 1,000 per 15 minutes |
| [POST /product\_catalogs](/x-ads-api/catalog-management/reference#post-product_catalogs) | 20 per 15 minutes |
| [PUT /product\_catalogs/:product\_catalog\_id](/x-ads-api/catalog-management/reference#put-product_catalogs%2Fproduct_catalog_id) | 20 per 15 minutes |
| [DELETE /product\_catalogs/:product\_catalog\_id](/x-ads-api/catalog-management/reference#delete-product_catalogs%2Fproduct_catalog_id) | 20 per 15 minutes |
#### Batch Products API
| Endpoint | Rate limit |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------- |
| [GET /product\_catalogs/:product\_catalog\_id/products](/x-ads-api/catalog-management/reference#get-product_catalogs%2Fproduct_catalog_id%2Fproducts) | 1,000 per 15 minutes |
| [PUT /product\_catalogs/:product\_catalog\_id/products](/x-ads-api/catalog-management/reference#put-product_catalogs%2Fproduct_catalog_id%2Fproducts) | 600 per 15 minutes |
| [DELETE /product\_catalogs/:product\_catalog\_id/products](/x-ads-api/catalog-management/reference#delete-product_catalogs%2Fproduct_catalog_id%2Fproducts) | 150 per 15 minutes |
#### Product Sets
| Endpoint | Rate limit |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------- |
| [GET /product\_catalogs/:product\_catalog\_id/product\_sets](/x-ads-api/catalog-management/reference#product-sets) | 2,000 per 15 minutes |
| [POST /product\_catalogs/:product\_catalog\_id/product\_sets](/x-ads-api/catalog-management/reference#post-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets) | 100 per 15 minutes |
| [PUT /product\_catalogs/:product\_catalog\_id/product\_sets/:product\_set\_id](/x-ads-api/catalog-management/reference#put-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets%2Fproduct_set_id) | 500 per 15 minutes |
| [DELETE /product\_catalogs/:product\_catalog\_id/product\_sets/:product\_set\_id](/x-ads-api/catalog-management/reference#delete-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets%2Fproduct_set_id) | 100 per 15 minutes |
#### Scheduled Feeds
| Endpoint | Rate limit |
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------- |
| [GET /product\_catalogs/:product\_catalog\_id/scheduled\_feeds](/x-ads-api/catalog-management/reference#get-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds) | 1,000 per 15 minutes |
| [POST /product\_catalogs/:product\_catalog\_id/scheduled\_feeds](/x-ads-api/catalog-management/reference#post-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds) | 20 per 15 minutes |
| [PUT /product\_catalogs/:product\_catalog\_id/scheduled\_feeds/:scheduled\_feed\_id](/x-ads-api/catalog-management/reference#put-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds%2Fscheduled_feed_id) | 20 per 15 minutes |
| [DELETE /product\_catalogs/:product\_catalog\_id/scheduled\_feeds/:scheduled\_feed\_id](/x-ads-api/catalog-management/reference#delete-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds%2Fscheduled_feed_id) | 20 per 15 minutes |
## Full API Reference
For the complete reference (Product Catalogs, Products, Product Sets, and Scheduled Feeds endpoints), see the **[Catalog Management API Reference](/x-ads-api/catalog-management/reference)** page.
# Catalog Management API Reference
Source: https://docs.x.com/x-ads-api/catalog-management/reference
Complete technical reference for all Catalog Management endpoints in the X Ads API — Product Catalogs, Products, Product Sets, and Scheduled Feeds.
## API Reference
This is the full technical reference. For an overview of Catalog Management concepts, product feeds, and Dynamic Product Ads, see the
Catalog Management Overview.
These endpoints are currently available via early-access only. To apply for access, please fill out this form or reach out to your X representative.
### Product Catalogs
#### GET product\_catalogs[](#get-product_catalogs "Permalink to this headline")
Retrieve details for some or all product catalogs associated with the authenticated user (default) or the user specified in the `user_id` parameter.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs`
A reference to the user you are operating with in the request. Use GET users/lookup to retrieve a user ID for a screen name.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
GET https://ads-api.x.com/12/product_catalogs
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {}
},
"next_cursor": null,
"data": [
{
"id": "1547080201384865792",
"name": "Catalog Name"
}
]
}
```
#### POST product\_catalogs[](#post-product_catalogs "Permalink to this headline")
Create a product catalog. One user can only create one catalog that holds all products. X merchants need to create a catalog before uploading products.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs`
Name of your product catalog.
A reference to the user you are operating with in the request. Use GET users/lookup to retrieve a user ID for a screen name.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
POST https://ads-api.x.com/12/product_catalogs?name=catalog_123_abc_def
```
**Example Response[](#example-response "Permalink to this headline")**
```json theme={null}
{
"request": {
"params": {
"name": "catalog_123_abc_def"
}
},
"data": {
"id": "1559934724822351872",
"name": "catalog_123_abc_def"
}
}
```
#### PUT product\_catalogs/:product\_catalog\_id[](#put-product_catalogs%2Fproduct_catalog_id "Permalink to this headline")
Update a product catalog.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id`
Identifier of your product catalog.
Name of your product catalog.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
PUT https://ads-api.x.com/12/product_catalogs/1547080201384865792?name=My Catalog
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"id": "1547080201384865792",
"name": "My Catalog"
}
},
"data": {
"id": "1547080201384865792",
"name": "My Catalog"
}
}
```
#### DELETE product\_catalogs/:product\_catalog\_id[](#delete-product_catalogs%2Fproduct_catalog_id "Permalink to this headline")
Delete a product catalog. **This is a permanent deletion.**
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id`
Identifier of your product catalog.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
DELETE https://ads-api.x.com/12/product_catalogs/1559919496399204352
```
**Example Response[](#example-response "Permalink to this headline")**
```json theme={null}
{
"request": {
"params": {
"id": "1559919496399204352"
}
},
"data": {
"id": "1559919496399204352",
"name": "catalog dos"
}
}
```
### Products
X merchants are able to send a synchronous batch request to view, create, edit, and delete products, instead of having to upload a feed file.
There are two types of products: individual products vs product groups. A product group is a group of multiple variants and is created when the user provides an `item_group_id` and has multiple variants for the product. When you call a fetch endpoint for products that includes grouped products, only the product that you submitted first will be returned.
#### GET product\_catalogs/:product\_catalog\_id/products[](#get-product_catalogs%2Fproduct_catalog_id%2Fproducts "Permalink to this headline")
Retrieve details for some or all products associated with the specified Product Catalog.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/products`
This is a X-generated item group identifier.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 100
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Please refer to the [product specifications guide](https://business.x.com/en/help/shopping-specs.html) for details about responses.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
GET https://ads-api.x.com/12/product_catalogs/1547080201384865792/products?count=1
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792",
"count": 1
}
},
"next_cursor": "1547080787865939970",
"data": [
{
"inventory": 5,
"custom_label_2": null,
"item_group_key": null,
"additional_image_link": null,
"size": null,
"mobile_link": null,
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"price": "20.00 USD",
"gtin": null,
"age_group": "teen",
"availability": "in stock",
"product_type": "",
"color": null,
"custom_label_3": null,
"item_group_id": null,
"brand": "X",
"product_key": "1547080787865939969",
"mpn": null,
"id": "123abc",
"custom_label_4": null,
"condition": "new",
"custom_label_0": null,
"sale_price": null,
"custom_label_1": null,
"link": "https://www.x.com/twtr_blue",
"sale_price_effective_date": null,
"image_link": "https://t.co/jeans_1.jpg",
"title": "My shoes",
"google_product_category": "Apparel & Accessories > Shoes",
"gender": "female"
}
]
}
```
#### PUT product\_catalogs/:product\_catalog\_id/products[](#put-product_catalogs%2Fproduct_catalog_id%2Fproducts "Permalink to this headline")
Add new products or update existing ones via a batch request. In a single request, up to 25 products can be supported.
A PUT request needs all of the required fields from the attribute list below. If we do not recognize the `id`, we create a new product. If we recognize the `id` in your catalog, we update the corresponding existing product.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/products`
**Request Attributes (JSON body)**[](#request-attributes-json-body "Permalink to this headline")
Unique ID for the item. Use the SKU if possible. If there are multiple instances of the same ID, all instances will be ignored.
Unique product object identifier generated by X.
The name of the product. Should be the same name as the product from the landing product page given through `link` or `mobile_link` attributes. Max 150 characters.
The description of the product. This field does not support HTML and must be in plain text. Max 5000 characters.
Current availability of your item.
Possible values: `in stock`, `available for order`, `preorder`, `out of stock`, `discontinued`
Condition of the item being sold.
Possible values: `new`, `used`, `refurbished`
Price of the item. Format as a number followed by the 3-digit ISO currency code (ISO 4217), with a space between cost and currency. Use `.` as the decimal point.
URL of the product page where people can buy the item. Must include `https`.
URL for the primary image of your item. Must be JPG, GIF, WEBP, or PNG. Minimum 500x500px. Max file size 5MB.
The brand name of the item. Required if `gtin` and `mpn` are not available.
Global Trade Item Number (UPC, EAN, JAN, or ISBN). Required if `brand` and `mpn` are not available.
Manufacturer Part Number. Required if `gtin` and `brand` are not available.
URL of a mobile-optimized product page. Must include `https`.
Comma-separated list of up to 10 additional image URLs. Follow the same specs as `image_link`.
Category according to Google's product taxonomy (path or ID).
Your business's custom product taxonomy. Subcategories separated by `>` (with spaces).
Quantity available to sell. Must be ≥ 1 when `availability` is `in stock`.
Discounted price (must be lower than `price`). Same format as `price`.
Time range for the sale period in ISO-8601 format: `YYYY-MM-DDTHH:MM+HH:MM/YYYY-MM-DDTHH:MM+HH:MM`.
Groups product variants together (size, color, age\_group, gender). Required if the product has variants.
X-generated item group identifier.
Gender for item sizing.
Possible values: `female`, `male`, `unisex`
Primary color of the product (do not use hex codes).
Size of the item (word, abbreviation, or number).
Associated age group.
Possible values: `adult`, `all ages`, `teen`, `kids`, `toddler`, `infant`, `newborn`
Extra custom label.
Extra custom label.
Extra custom label.
Extra custom label.
Extra custom label.
**Response Parameters[](#response-parameters "Permalink to this headline")**
Warnings about your request.
Error messages about your request.
Unique product object identifier generated by X.
Unique ID for the item.
Status of your request.
Possible values: `CREATE_SUCCESS`, `UPDATE_SUCCESS`, `ERROR`, `NO_CHANGE`
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
PUT https://ads-api.x.com/12/product_catalogs/1547080201384865792/products
```
**JSON Body**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"products": [
{
"id": "test-12345",
"title": "Test Product 1",
"description": "The product which was added from the upsert endpoint",
"availability": "in stock",
"condition": "new",
"link": "https://www.x.com/twtr_blue",
"image_link": "https://www.kurzweilai.net/images/Naam-Limits-of-Earth-Part1-001-earth-600x600.jpg",
"brand": "x",
"gtin": "1432563728",
"mpn": "3268793T",
"mobile_link": "https://www.x.com/twtr_blue",
"google_product_category": "Apparel & Accessories > Clothing > Dresses",
"product_type": "Apparel & Accessories > Clothing > Dresses",
"inventory": 2,
"price": "60.00 USD",
"gender": "female",
"color": "blue",
"size": "medium",
"sale_price": "50.00 USD",
"sale_price_effective_date": "2022-10-04T17:20:31.000Z/2022-10-10T04:00:00.000Z",
"age_group": "adult",
"custom_label_0": "custom value"
}
]
}
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792"
}
},
"data": {
"products_response": [
{
"warnings": [],
"errors": [],
"product_key": "1576769414321651714",
"id": "test-123456",
"status": "CREATE_SUCCESS"
}
]
}
}
```
#### DELETE product\_catalogs/:product\_catalog\_id/products[](#delete-product_catalogs%2Fproduct_catalog_id%2Fproducts "Permalink to this headline")
Delete existing products. **This is a permanent deletion.**
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/products`
**Request Parameters (JSON body)**[](#request-parameters-json-body-1 "Permalink to this headline")
Array of unique product object identifiers generated by X.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
DELETE https://ads-api.x.com/12/product_catalogs/1569782857975087104/products
```
**JSON Body**
```json theme={null}
{
"product_keys": [
"1576769414321651714",
"1577536549830344705"
]
}
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_keys": [
"1576769414321651714",
"1577536549830344705"
]
}
},
"data": {
"delete_products": [
{
"product_key": "1576769414321651714",
"failed_product_key": null,
"message": null
},
{
"product_key": "1577536549830344705",
"failed_product_key": null,
"message": null
}
]
}
}
```
### Product Sets
Product Sets are collections of products which represent a subset of your catalog (e.g. "Fall Sale Products"). You can use product sets to run Dynamic Product Ads (DPA) featuring the specific products included in that collection, rather than all products in your catalog.
#### GET product\_catalogs/:product\_catalog\_id/product\_sets/:product\_set\_id[](#get-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets%2Fproduct_set_id "Permalink to this headline")
Retrieve details for a specific Product Set associated with the specified Product Catalog.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/product_sets/:product_set_id`
Unique ID for the product set.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
GET https://ads-api.x.com/12/product_catalogs/1547080201384865792/product_sets/1560456755976343552
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792",
"id": "1560456755976343552"
}
},
"data": {
"name": "Test Product Set API",
"description": "Price and Custom Filter",
"product_ids": [
"123abc",
"myshoes2"
],
"processing_status": "DONE",
"id": "1560456755976343552",
"filters": [
{
"attribute": "price",
"operator": "LESS_THAN",
"value": "120.00 USD"
},
{
"attribute": "custom_field_5",
"operator": "MATCH",
"value": "test"
}
],
"type": "FILTERED"
}
}
```
#### POST product\_catalogs/:product\_catalog\_id/product\_sets[](#post-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets "Permalink to this headline")
Create a new product set.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/product_sets`
**Request Parameters (JSON body)**[](#request-parameters-json-body-2 "Permalink to this headline")
Name of the product set.
Description of the product set.
Type of product set.
Possible values: `MANUAL`, `FILTERED`
Required when `type` is `FILTERED`. Array of filter objects with `attribute`, `operator`, and `value`.
Supported attributes: `price`, `product_type`, `google_product_category`, `sale_price`, `inventory`, `custom_label_0` through `custom_label_4`.
Supported operators: `GREATER_THAN`, `EQUAL_TO`, `LESS_THAN`, `MATCH`, `NOT_CONTAINS`, `CONTAINS`.
Required when `type` is `MANUAL`. Array of X-generated product keys.
**Response Parameters[](#response-parameters "Permalink to this headline")**
Status of product set creation when using `FILTERED` type.
Possible values: `DONE`, `PROCESSING`, `FAILED`
**Example Request (MANUAL type)**[](#example-request-manual-type "Permalink to this headline")
```json theme={null}
POST https://ads-api.x.com/12/product_catalogs/1569782857975087104/product_sets
```
**JSON Body**
```json theme={null}
{
"name": "manual API product set",
"type": "MANUAL",
"product_keys": [
"1569784751351013380"
]
}
```
**Example Response**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1569782857975087104",
"name": "manual API product set",
"type": "MANUAL",
"product_keys": [
"1569784751351013380"
]
}
},
"data": {
"name": "manual API product set",
"description": null,
"product_ids": [
"sdkljsdijf"
],
"processing_status": "DONE",
"id": "1573806483589849088",
"filters": [],
"type": "MANUAL"
}
}
```
**Example Request (FILTERED type)**[](#example-request-filtered-type "Permalink to this headline")
```json theme={null}
POST https://ads-api.x.com/12/product_catalogs/1569782857975087104/product_sets
```
**JSON Body**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "filtered API product set",
"description": "price above 100 USD",
"type": "FILTERED",
"filters": [
{
"attribute": "price",
"operator": "GREATER_THAN",
"value": "100.00 USD"
}
]
}
```
**Example Response**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1569782857975087104",
"name": "filtered API product set",
"description": "price above 100 USD",
"type": "FILTERED",
"filters": [
{
"attribute": "price",
"operator": "GREATER_THAN",
"value": "100.00 USD"
}
]
}
},
"data": {
"name": "filtered API product set",
"description": "price above 100 USD",
"product_ids": [
"nike-sb-dunk-high-pro-medium-grey-pink",
"sdkljsdijf"
],
"processing_status": "DONE",
"id": "1573831671954096128",
"filters": [
{
"attribute": "price",
"operator": "GREATER_THAN",
"value": "100.00 USD"
}
],
"type": "FILTERED"
}
}
```
#### PUT product\_catalogs/:product\_catalog\_id/product\_sets/:product\_set\_id[](#put-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets%2Fproduct_set_id "Permalink to this headline")
Update an existing product set. **Note**: Updating `FILTERED` product sets is not supported. The example below shows a `MANUAL` product set update.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/product_sets/:product_set_id`
**Request Parameters (JSON body)**[](#request-parameters-json-body-3 "Permalink to this headline")
Unique ID for the product set.
Name of the product set.
Description of the product set.
Array of X-generated product keys (for MANUAL sets).
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
PUT https://ads-api.x.com/12/product_catalogs/1549442554172694528/product_sets/1564499160082001920
```
**JSON Body**
```json theme={null}
{
"name": "Update name product catalogs",
"product_keys": ["1576768397127606272", "1547080787865939969"]
}
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1576873894266273792",
"id": "1564499160082001920",
"product_keys": [
"1576768397127606272",
"1547080787865939969"
],
"name": "Update name product catalogs"
}
},
"data": {
"name": "Update name product catalogs",
"description": "Manual product Sets description",
"product_ids": [
"test-12345",
"123abc"
],
"processing_status": "DONE",
"id": "1564499160082001920",
"filters": [],
"type": "MANUAL"
}
}
```
#### DELETE product\_catalogs/:product\_catalog\_id/product\_sets/:product\_set\_id[](#delete-product_catalogs%2Fproduct_catalog_id%2Fproduct_sets%2Fproduct_set_id "Permalink to this headline")
Delete an existing product set. **This is a permanent deletion.**
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/product_sets/:product_set_id`
Unique ID for the product set.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
DELETE https://ads-api.x.com/12/product_catalogs/1547080201384865792/product_sets/1559806000097787904
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792",
"id": "1559806000097787904"
}
},
"data": {
"name": "Filtered Product",
"description": "Filtered product Set",
"product_ids": [],
"processing_status": "DONE",
"id": "1559806000097787904",
"filters": [
{
"attribute": "price",
"operator": "GREATER_THAN",
"value": "100.00 USD"
}
],
"type": "FILTERED"
}
}
```
### Scheduled Feeds
Scheduled Feeds configure the file location and frequency with which X ingests product data into a user's catalog. Only one product feed is supported per user.
Importing a scheduled feed is an **additive** action — removing products from the feed does **not** delete them from the catalog.
#### GET product\_catalogs/:product\_catalog\_id/scheduled\_feeds[](#get-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds "Permalink to this headline")
Retrieve details for scheduled feeds associated with the specified Product Catalog.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/scheduled_feeds`
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
GET https://ads-api.x.com/12/product_catalogs/1547080201384865792/scheduled_feeds
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792"
}
},
"next_cursor": null,
"data": [
{
"start_time": "01:30",
"product_catalog_id": "1547080201384865792",
"feed_url": "https://test212/file.csv",
"feed_format": "CSV",
"id": "1564821386714947589",
"created_at": "2022-08-31T03:44:26.000Z",
"frequency": "DAILY",
"repeat": null,
"updated_at": "2022-09-27T08:47:23.000Z",
"time_zone": "America/New_York"
}
]
}
```
#### POST product\_catalogs/:product\_catalog\_id/scheduled\_feeds[](#post-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds "Permalink to this headline")
Create a scheduled product feed.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/scheduled_feeds`
Host feed URL for your product file. Can be up to 8GB.
Format of the product feed file.
Possible values: `CSV`, `TSV`, `XML`
How often X should ingest the feed.
Possible values: `HOURLY`, `DAILY`, `WEEKLY`
Required for `WEEKLY` or `HOURLY` frequency.
* `WEEKLY`: `MONDAY`–`SUNDAY`
* `HOURLY`: `1`, `2`, `3`, `4`, `6`, `8`, `12`
* `DAILY`: Do not include this parameter.
Time to import the feed file (HH:MM format).
IANA time zone for `start_time`.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
POST https://ads-api.x.com/12/product_catalogs/1547080201384865792/scheduled_feeds?feed_url=https://test212/file.csv&feed_format=CSV&frequency=WEEKLY&time_zone=America/New_York&repeat=SATURDAY&start_time=01:30
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"start_time": "01:30",
"product_catalog_id": "1547080201384865792",
"feed_url": "https://test212/file.csv",
"feed_format": "CSV",
"frequency": "WEEKLY",
"repeat": "SATURDAY",
"time_zone": "America/New_York"
}
},
"data": {
"start_time": "01:30",
"product_catalog_id": "1547080201384865792",
"feed_url": "https://test212/file.csv",
"feed_format": "CSV",
"id": "1576851765428822016",
"created_at": "2022-10-03T08:28:52.000Z",
"frequency": "WEEKLY",
"repeat": "SATURDAY",
"updated_at": "2022-10-03T08:28:52.000Z",
"time_zone": "America/New_York"
}
}
```
#### PUT product\_catalogs/:product\_catalog\_id/scheduled\_feeds/:scheduled\_feed\_id[](#put-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds%2Fscheduled_feed_id "Permalink to this headline")
Update an existing scheduled product feed.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/scheduled_feeds/:scheduled_feed_id`
Unique ID for the scheduled feed.
Host feed URL for your product file (up to 8GB).
Format of the product feed file.
Possible values: `CSV`, `TSV`, `XML`
Ingestion frequency.
Possible values: `HOURLY`, `DAILY`, `WEEKLY`
Repeat value (see POST for valid values per frequency).
Time to import the feed (HH:MM).
IANA time zone for `start_time`.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
PUT https://ads-api.x.com/12/product_catalogs/1547080201384865792/scheduled_feeds/1577629831247720448?start_time=07:30
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792",
"start_time": "07:30",
"id": "1577629831247720448"
}
},
"data": {
"start_time": "07:30",
"product_catalog_id": "1547080201384865792",
"feed_url": "https://test212/file.csv",
"feed_format": "CSV",
"id": "1577629831247720448",
"created_at": "2022-10-05T12:00:37.000Z",
"frequency": "WEEKLY",
"repeat": "SATURDAY",
"updated_at": "2022-10-05T12:03:07.000Z",
"time_zone": "America/New_York"
}
}
```
#### DELETE product\_catalogs/:product\_catalog\_id/scheduled\_feeds/:scheduled\_feed\_id[](#delete-product_catalogs%2Fproduct_catalog_id%2Fscheduled_feeds%2Fscheduled_feed_id "Permalink to this headline")
Delete an existing scheduled product feed. **This is a permanent deletion.**
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/product_catalogs/:product_catalog_id/scheduled_feeds/:scheduled_feed_id`
Unique ID for the scheduled feed.
**Example Request[](#example-request "Permalink to this headline")**
```json theme={null}
DELETE https://ads-api.x.com/12/product_catalogs/1547080201384865792/scheduled_feeds/1576854236993708032
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"product_catalog_id": "1547080201384865792",
"id": "1576854236993708032"
}
},
"data": {
"start_time": "07:30",
"product_catalog_id": "1547080201384865792",
"feed_url": "https://test212/file.csv",
"feed_format": "CSV",
"id": "1576854236993708032",
"created_at": "2022-10-03T08:38:41.000Z",
"frequency": "DAILY",
"repeat": null,
"updated_at": "2022-10-03T08:50:10.000Z",
"time_zone": "America/New_York"
}
}
```
# Creatives
Source: https://docs.x.com/x-ads-api/creatives
Overview of creative assets on X Ads, including promoted Tweets, cards, images, GIFs, and videos that can be uploaded and attached to ad campaigns.
**Manage all types of promotable content (Tweets, media, cards, polls, etc.) for your X advertising campaigns.**
## Quick links
* [Full API Reference](/x-ads-api/creatives/reference) — Complete reference for all creative endpoints and objects
* [Guides](#guides) — Media Library, Scheduled Tweets, Identifying Cards/Media, Carousels, etc.
## Overview
Creatives are any entity that can be promoted in a campaign. Posts can include text, images, GIFs, videos, or cards. Cards can include images or videos.
Image, GIF, or video creatives are uploaded using either the [POST media/upload](/x-api/media/upload-media#post-media-upload) — a simple upload endpoint that only supports images — or the POST media/upload (chunked) endpoints. These can be added to
cards:
* POST accounts/:account\_id/cards
Tweets:
* POST accounts/:account\_id/tweets - To add cards to Tweets, use the card\_uri parameter.
Scheduled Tweets:
* POST accounts/:account\_id/scheduled\_tweets
For additional details on cards, please see the Cards page. The Promoted Video page provides details on associating videos with cards or Tweets.
### Cards
The Ads API supports several card types that can be used in Tweets, which can then be promoted in campaigns. **Note**: once Tweeted, card details are publicly visible. This may include information about the user who owns the card.
#### Image
The following image specifications apply to assets used in [Cards](/x-ads-api/creatives/reference#cards-2). Images must be 3MB or less and have a width of at least 800px. In addition, we support the following width:height aspect ratios.
* Website: 1:1 and 1.91:1
* Image App Download: 1:1 and 1.91:1
* Poll: 1.91:1
* Image Conversation: 1.91:1
* Image Direct Message: 1.91:1
We support the following image formats: .bmp, .jpeg, and .png.
#### Video
The following video specifications apply to assets used in [Cards](/x-ads-api/creatives/reference#cards-2). We support the following width:height aspect ratios.
* Video Website: 16:9 and 1:1
* Video App Download: 16:9 and 1:1
* Poll: 16:9
* Video Conversation: 16:9
* Video Direct Message: 16:9
### Promoted Video
This document provides a brief overview of the process for uploading and promoting video through the Ads API.
The Ads API supports Promoted Video in [Tweets](/x-ads-api/creatives/reference#tweets-2) and in the following cards:
* [Video Website](https://devcommunity.x.com/t/ads-api-version-11/168814)
* [Video App Download](https://devcommunity.x.com/t/ads-api-version-11/168814)
* [Video Conversation](/x-ads-api/creatives/reference#video-conversation-cards)
First, upload the video using the [POST media/upload (chunked)](/x-api/media/initialize-media-upload) endpoint. Using the `media_id`, associate the video with an ads account using the POST accounts/:account\_id/videos endpoint. The video's `id`, sometimes referred to as the `media_key`, will be used in subsequent requests. This is a string that begins with an int, is followed by an underscore, and ends with a long value. As an example, see: `13_875943225764098048`.
#### Promoted Video in Tweets
To create a Tweet, use the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#get-accounts-account-id-tweets) endpoint along with the video's `id`. In this step, you can also provide a video title, description, and call-to-action (CTA). These values are user-facing.
#### Promoted Video in Cards
Video App Download and Video Conversation cards support the ability to add a poster images. Upload an image to use in these cards using the [POST media/upload](/x-api/media/upload-media) endpoint.
Create the card using one of the following endpoints:
* [POST accounts/:account\_id/cards/video\_website](https://devcommunity.x.com/t/ads-api-version-11/168814)
* [POST accounts/:account\_id/cards/video\_app\_download](https://devcommunity.x.com/t/ads-api-version-11/168814)
* [POST accounts/:account\_id/cards/video\_conversation](https://devcommunity.x.com/t/ads-api-version-11/168814)
using the video's `id` and, optionally, the image's `media_id` (for the poster image).
Finally, create the Tweet using the POST accounts/:account\_id/tweet endpoint. Cards are attached to Tweets using the `card_uri` parameter.
#### General Information
For detailed guidance on video uploading through the API, please see the [Video Upload Guide](/x-api/media/quickstart/media-upload-chunked).
Videos can also be promoted as pre-roll assets. See the [Video Views Pre-roll Objective Guide](/x-ads-api/campaign-management/reference#video-views-preroll-objective) for a detailed explanation.
* (As of 2015-10-22) When uploading videos to be used in promoted content, the `media_category` parameter must be set with a value of `amplify_video` for all `INIT` command requests to the [POST media/upload (chunked)](/x-api/media/initialize-media-upload) endpoint. Using this new param ensures that the video is asynchronously pre-processed and prepared for use in promoted content. The `STATUS` command can be used to check completion of asynchronous processing after video upload.
* The maximum promoted video length currently allowed is 10 mins with a file size of 500MB or less.
* Uploaded video should be either mp4 or mov.
* Uploaded video generally processes quickly, but processing times can vary depending on video length and file size.
* Uploaded poster images should be in png or jpg format. There are no aspect ratio or size requirements, but the poster image will be adjusted to fit the video player.
## Guides
### Scheduled Tweets
#### Introduction
Scheduled Tweets allow an advertiser or user to create a Tweet that can be scheduled to go live at a later date. In addition to being able create and manage these Tweets, the API allows the ability to associate these Tweets with a line item, to be promoted once the Tweet goes live. This allows advertisers to stage create native Tweets and plan their campaign creatives in advance of any key initiatives. For example, staging a Tweet creative to live immediately upon a new product announcement.
The full set of functionality provided by the Scheduled Tweets API endpoints are listed below:
* Create, modify and view newly scheduled Tweets
* Associate a Scheduled Tweet with a line item
* Query and manage existing scheduled Tweets
* Once a Scheduled Tweet goes live, retrieve the live Tweet `id`
#### API Endpoints
The entire set of endpoints related to the above functionality is listed below:
#### Scheduled Tweet Management
* [GET accounts/:account\_id/scheduled\_tweets](/x-ads-api/creatives/reference#get-accounts-account-id-scheduled-tweets) (retrieve a list of all Scheduled Tweets)
* [GET accounts/:account\_id/scheduled\_tweets/:scheduled\_tweet\_id](/x-ads-api/creatives/reference#get-accounts-account-id-scheduled-tweets) (lookup a specific Scheduled Tweet using its `id`)
* [POST accounts/:account\_id/scheduled\_tweets](/x-ads-api/creatives/reference#post-accounts-account-id-scheduled-tweets) (create a new Scheduled Tweet)
* [PUT accounts/:account\_id/scheduled\_tweets/:scheduled\_tweet\_id](/x-ads-api/creatives/reference#example-request-39) (modify an existing Scheduled Tweet)
* [DELETE accounts/:account\_id/scheduled\_tweets/:scheduled\_tweet\_id](/x-ads-api/creatives/reference#example-request-40) (delete a Scheduled Tweet using its `id`)
* [GET accounts/:account\_id/scheduled\_tweets/preview/:scheduled\_tweet\_id](/x-ads-api/creatives/reference#scheduled-tweets-2) (preview an existing Scheduled Tweet)
#### Scheduled Promoted Tweets
* [GET accounts/:account\_id/scheduled\_promoted\_tweets](/x-ads-api/campaign-management/reference#get-accounts-account-id-scheduled-promoted-tweets) (retrieve a list of all Scheduled Promoted Tweets)
* [GET accounts/:account\_id/scheduled\_promoted\_tweets/:scheduled\_promoted\_tweet\_id](/x-ads-api/campaign-management/reference#get-accounts-account-id-scheduled-promoted-tweets-scheduled-promoted-tweet-id) (lookup a Promoted Scheduled Tweet using its `id`)
* [POST accounts/:account\_id/scheduled\_promoted\_tweets](/x-ads-api/campaign-management/reference#post-accounts-account-id-scheduled-promoted-tweets) (create a new Scheduled Promoted Tweet)
* [DELETE accounts/:account\_id/scheduled\_promoted\_tweets/:scheduled\_promoted\_tweet\_id](/x-ads-api/campaign-management/reference#delete-accounts-account-id-scheduled-promoted-tweets-scheduled-promoted-tweet-id) (delete an existing Scheduled Promoted Tweet using its `id`)
#### Scheduled Tweet View
* [GET accounts/:account\_id/scheduled\_tweets/preview/:scheduled\_tweet\_id](/x-ads-api/creatives/reference#scheduled-tweets-2) (view an existing Scheduled Tweet)
Due to the nature of Scheduled Tweets being separate entities from “live” Tweets, there are two different sets of validations run on any creates or edits to these Tweets. The first set of validation rules are run during the Scheduled Tweet creation step, specifically:
#### Scheduled Tweet Create:
* Validate that the authenticated user has access to create organic Tweets for a given @handle Promoted-Only Tweet create privileges requires authenticated user to be an account user with [Tweet composer permissions](https://developer.x.com/content/developer-twitter/en/docs/ads/campaign-management/api-reference/authenticated-user-access#get-accounts-account-id-authenticated-user-access)
* Validate that there are no more than 30 Tweets that are scheduled to be created within a 15 minute window of the scheduled\_at time. A SCHEDULED\_TWEET\_LIMIT\_EXCEEDED error message indicates that too many Scheduled Tweets have been scheduled within the same future, 15 minute time frame. Advertisers will need to remove an existing Scheduled Tweet or move the scheduled\_at time earlier or later.
#### Scheduled Tweet goes "live":
* These validation rules are run at the scheduled\_at time and are identical to those applied on regular Tweet creation in the API. For example, a Scheduled Tweet will not go live and the scheduled\_status will be set to FAILED if the Scheduled Tweet contains both an image and a gif
#### Workflow
**Create a new Scheduled Tweet**
A new Scheduled Tweet can be created using the [POST accounts/:account\_id/scheduled\_tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/scheduled-tweets#post-accounts-account-id-scheduled-tweets) endpoint. This endpoint has the following required parameters, `scheduled_at` time along with the Tweet `text` if no media entities are included in the Tweet. In addition, this endpoint provides a few additional options that allow you to create a scheduled Tweet on behalf of another @handle via the `as_user_id` param along with the ability to add a card (`card_uri`) and any media (`media_ids`). Note, a Tweet can only contain entities of the same type, i.e., either Video, Gif or Image. The `nullcast` param controls whether the Tweet is a “Promoted-Only” Tweet or not. All newly created Scheduled Tweets are "Promoted-Only" (`nullcast=true`) by default. If `nullcast=false` then an Organic Scheduled Tweet is created
Once a Scheduled Tweet is successfully created, the response will contain an `id` field, which refers to the unique identifier of the Scheduled Tweet itself. In addition to this field, another field called `tweet_id` is also returned. This field is `null` initially, however once the Tweet goes live this field is populated with the ID of the “live” Tweet.
```
twurl -H 'ads-api.x.com' -X POST "/6/accounts/:account_id/scheduled_tweets" -d 'scheduled_at=2017-12-24T23:59:00Z&text=Happy Holidays!'
```
This will create the following Scheduled Tweet:
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"text": "Happy Holidays!",
"scheduled_at": "2017-12-24T23:59:00Z"
}
},
"data": {
"completed_at": null,
"id_str": "917507899668099072",
"text": "Happy Holidays!",
"user_id": "3271358660",
"scheduled_status": "SCHEDULED",
"id": 917507899668099100,
"nullcast": true,
"created_at": "2017-10-09T21:51:44Z",
"scheduled_at": "2017-12-24T23:59:00Z",
"card_uri": null,
"updated_at": "2017-10-09T21:51:44Z",
"tweet_id": null,
"media_keys": []
}
}
```
Once this Scheduled Tweet goes live, the `tweet_id` field will be populated with the "live" Tweet's ID.
**View a Scheduled Tweet**
The [GET accounts/:account\_id/tweet\_previews](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/tweet-previews#get-accounts-account-id-tweet-previews) endpoint can then be used with the Scheduled Tweet `id` from the previous step to generate a preview of the Tweet. The API response will contain an iframe URL that is ready to be used to render a preview for the Scheduled Tweet. The relevant CSS and images will be served directly via X.
```
twurl -H ads-api.x.com -X GET "/6/accounts/18ce54bgxky/tweet_previews?tweet_type=SCHEDULED&tweet_ids=917507899668099072
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"tweet_type": "SCHEDULED",
"tweet_ids": [
"917507899668099072"
],
"account_id": "18ce54bgxky"
}
},
"data": [
{
"tweet_id": "1126633863155871744",
"preview": "<\iframe class='tweet-preview' src='https://ton.smf1.x.com/ads-manager/tweet-preview/index.html?data=H4sIAAAAAAAAAK1WTW%2FjNhD9Kyyv9dqSZdmOgALJbhJsCyxaIDkUWBUEJY0lNhSpklRSN%2FV%2F71CyZbm297S%2BWJxPzpt5I71T9wbgaELeaW6AOygYxyN9rlryhW9JcEPmUbKIkuiG%2FBjgj8yD8IZOqChoEobz5TKK1ssojOP1KlwtFl7BrDMY4oIW%2FTatlMzB3z7JZ940W%2FJZS1Hwrf0Btc60Kve3oMmGSwsTWgjbSL7tXJjhqgSafA0mYfzHhIJywgmwNHmnFbeV4yU%2Bf0WN3daZlvtDa8Gw2htrdRCZXrlDU92aHIPStA2CKOekMrD5KaWVc02SztIZps%2Bh0rIAg27TXNcpJQYk2ii90VLqt7R3ht%2B4cQoMeVClUIAPd03Th01nvDfx0ClmoJFYk0aouGst82gqROaKskf03KCr7LLvXnXN02K3QTHFaziovYdH0seL5qswitfLZTBq6FGIRfSe9Lm1FTfkY%2BX%2FFcpPAlNRC7eufdFSY1%2BxASh84oo8YitzYXM9IZ%2FuaNcQ1HjMbQc61l0VXDmYlsJVbTYVGq0KwPCi2cf5tQFFnjR2zyDU6YycwX%2Fr3oRzvfKpwTaSZ8NfQUoU%2FUsetanxAV79VElhHbm1oIrSiILcvvgquqSN0Q7y8Uz2TQdjWa5bhZP8IUShEeh8IvIxkVB7SY%2FyKctaIL%2B0kgQrMp8n0SKJ10eWxZ4t%2FBXHUzg4idu6nOnNxsIQ1Yka2D9aDc0sQTNQPJP%2B2sgqvPUrGLERozL68ToNLRELvBj4VuZaOSOy1mmsdAi2dxaWOeyhlRzVl6TYozMnhHIjJLCM5y%2BlwaweHOn96afg%2FuHhnl60ETUvgR1HpJsQntkptrcuO0bOOhuLg1NBPfyH6Swrpw2W9O24rBu8kwH8DuEdns9Kv1hLc5rsxBaTLcN1HIdhHIVRuFov5wtMXH748vO2%2BP0jUzjFXE7%2FbMa3%2BFZl3z1ZxhWyjv2fwlfy9NaY6LhO0lm4WC3WcRSvlqO4UqiXYT7C%2B7vwcT7SWlFAxg3LtMHNfH2ODnZ4kIPVPRo9jnN1r5eDNup%2BIy2y5GxuDrQqYMNb6dje9or44HOyQYTnWs%2FXXoD7%2Ba8WrGO4hwZuK%2B2Qt%2F32tAPhB%2B4xt238qjVQtpIbuuvIP6wbjfAIhStncO3eZ0f9keMHmYHuo%2BCwFoJ%2BDfktdEF0JPfebbxgct30b%2BdhY%2B51u%2FGm2U2IR7rW%2FbJU%2FdcBfpEchHjwoO52%2FwENmVvErwgAAA%3D%3D'>"
}
]
}
```
A sample view of the newly created Scheduled Tweet is shown above
**Associate a Scheduled Tweet with a line item**
While Scheduled Tweets can be used to create Organic Tweets, we also allow partners to create a “Promoted-Only” (`nullcast=true`) Tweet either one of which can be associated with a line item. In order to facilitate this, we provide a [POST accounts/:account\_id/scheduled\_promoted\_tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/campaign-management/api-reference/scheduled-promoted-tweets#post-accounts-account-id-scheduled-promoted-tweets) endpoint as well. This endpoint only allows a single Promoted Scheduled Tweet to be associated with a line item in a single API call. In order to associate multiple Scheduled Tweets to the same line item, multiple API calls are necessary.
Please note that it is not possible to modify an existing Scheduled Promoted Tweet.
```
twurl -H 'ads-api.x.com' -X POST "/6/accounts/:account_id/scheduled_promoted_tweets" -d 'line_item_id=a44qc&scheduled_tweet_id=917507899668099072'
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "a44qc",
"id": "26576",
"created_at": "2017-10-09T22:24:16Z",
"updated_at": "2017-10-09T22:24:16Z",
"scheduled_tweet_id": "917507899668099072",
"tweet_id": null,
"deleted": false
},
"request": {
"params": {
"line_item_id": "a44qc",
"scheduled_tweet_id": 917507899668099100,
"account_id": "aaaaa"
}
}
}
```
This endpoint only creates an association between a given Scheduled Tweet and a line item. Once the campaign/line item flight dates are current, the line item with automatically start serving the corresponding “live” Tweet. While we do validate during this step that the Scheduled Tweet is in the `SCHEDULED` state, and that the given Scheduled Tweet is valid for the given objective, no other validations are run. Any remaining validation rules that apply to the line item and Scheduled Tweet are run when the Tweet goes “live”
In order to ensure that there are no issues with campaign serving it is recommend that the Scheduled Tweet be `scheduled_at` a time prior to the campaign/line item flight dates.
For example, let's say the Scheduled Tweet is set to go live after the campaign start date (and that there is only a single Tweet associated with a single line item), then the campaign will be `ACTIVE`, however given that the Scheduled Tweet is not live yet, there will be no creatives available for serving.
**Scheduled Tweet Management**
The remaining sets of endpoints allow API consumers to manage all their Scheduled Tweets and Scheduled Promoted Tweets. These APIs can be used to either return a list of all Scheduled Tweets optionally filtered by a given state as well as lookup a given Scheduled Tweet by its `id`.
#### What happens when a Scheduled Tweet goes live?
Once a given Scheduled Tweet is about to go live, or in other words at the `scheduled_at` time, the following updates are made:
* The “live” Tweet is created however this may have a latency of upto 1 second
* The `tweet_id` is added to the following entities:
* Scheduled Tweet
* Promoted Scheduled Tweet
* A new Promoted Tweet entity is created
#### Best Practices
The following best practices are recommended when creating or promoting Scheduled Tweets:
* Ensure that the Tweet is valid when creating the Scheduled Tweet (for example, a Tweet can only have either an Image, Video or Gif and not any combination of the three)
* Ensure that the campaign flight dates (i.e., the `start_time` and `end_time`) align with the `scheduled_at` time for the Scheduled Tweet
* Scheduled Tweets should not be scheduled for more than one year in the future (365 days)
* Tweet preview is currently not supported for Scheduled Tweets (this is ability to preview Scheduled Tweets prior to creation)
### Media Library
#### Introduction
The Media Library endpoints provide the ability to manage images, GIFs, and videos for X Ads accounts. Media assets in the library can be used in Tweets and to create cards. They can also be reused in multiple [creatives](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/overview), eliminating the need to upload the same asset multiple times.
#### API Endpoints
* [POST media/upload](/x-api/media/upload-media) or [POST media/upload (chunked)](/x-api/media/initialize-media-upload) (upload media)
* [POST accounts/:account\_id/media\_library](https://developer.x.com/x-ads-api/creatives/reference#get-accounts-account-id-media-library#post-accounts-account-id-media-library) (add media to the Media Library)
#### Adding to the Library
Adding media to the library is a two-step process. First, upload the asset using either the [POST media/upload](/x-api/media/upload-media) endpoint or the [POST media/upload (chunked)](/x-api/media/initialize-media-upload) set of endpoints. (See the [Chunked media upload](/x-api/media/quickstart/media-upload-chunked) guide for details on our multi-part upload process.)
```
twurl -X POST -H upload.x.com "/1.1/media/upload.json?additional_owners=756201191646691328" --file latte.jpeg --file-field "media"
```
```json theme={null}
{
"media_id":966947208837742592,
"media_id_string":"966947208837742592",
"size":74194,
"expires_after_secs":86400,
"image":{
"image_type":"image/jpeg",
"w":800,
"h":418
}
}
```
Next, using the media ID, add the media to the ads account’s library using the [POST accounts/:account\_id/media\_library](https://developer.x.com/x-ads-api/creatives/reference#get-accounts-account-id-media-library#post-accounts-account-id-media-library) endpoint.
```
twurl -X POST -H ads-api.x.com "/9/accounts/18ce54d4x5t/media_library?file_name=latte.jpeg&media_category=TWEET_IMAGE&media_key=966947208837742592&name=Latte"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request":{
"params":{
"name":"Latte",
"file_name":"latte.jpeg",
"media_category":"TWEET_IMAGE",
"account_id":"18ce54d4x5t",
"media_key":966947208837742592
}
},
"data":{
"tweeted":false,
"name":"Latte",
"file_name":"latte.jpeg",
"media_url":"https://pbs.twimg.com/media/DWtJXQNUQAAdPZj.jpg",
"media_category":"TWEET_IMAGE",
"media_key":"3_966947208837742592",
"created_at":"2018-02-23T08:05:54Z",
"media_status":"TRANSCODE_COMPLETED",
"media_key":"966947208837742592",
"media_type":"IMAGE",
"updated_at":"2018-02-23T08:06:17Z",
"deleted":false
}
}
```
**Note:** Tweeting images, GIFs, or videos directly after the upload also adds media to the library.
#### Request Parameters
All Media Library POST requests require a media identifier. This value is returned during the upload step. When using the media\_id, as in the example above, a media\_category must also be specified. There are four possible category values: AMPLIFY\_VIDEO, TWEET\_GIF, TWEET\_IMAGE, and TWEET\_VIDEO.
Optionally, name and file\_name values can be set for objects in the Media Library. These attributes help users distinguish between media variants in the library.
For videos, it’s also possible to set a title and a description. They values are intended to be passed as the video\_title and video\_description request parameters with the [POST accounts/:account\_id/tweet](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/tweets#post-accounts-account-id-tweet) endpoint. In the Tweet, this text appears under the video.
#### Attributes
The Media Library, formally introduces the concept of the media\_key. This is the unique identifier for objects in the library. Media keys are string values in the following format: 13\_875943225764098048. These are fully supported in all of our card endpoints.
In addition, the Media Library response includes the media\_id, represented as a string. This is included for resources that do not currently accept a media key: [Tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/tweets#post-accounts-account-id-tweet)\*, [Tweet preview](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/tweets#get-accounts-account-id-tweet-preview)\*, and [Scheduled Tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/scheduled-tweets#post-accounts-account-id-scheduled-tweets). We are working toward supporting media keys everywhere.
The aspect\_ratio attribute is returned for GIFs and videos. This can be used to filter media for use in cards that only accept particular aspect ratios.
\*These endpoints support the video\_id parameter, which is a media key.
#### Usage
In this section, the following image will be used in a Tweet and to create a website card.
```
twurl -H ads-api.x.com "/9/accounts/18ce54d4x5t/media_library/3_966947208837742592"
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request":{
"params":{
"account_id":"18ce54d4x5t",
"media_key":"3_966947208837742592"
}
},
"data":{
"tweeted":false,
"name":"Latte",
"file_name":"latte.jpeg",
"media_url":"https://pbs.twimg.com/media/DWtJXQNUQAAdPZj.jpg",
"media_category":"TWEET_IMAGE",
"media_key":"3_966947208837742592",
"created_at":"2018-02-23T08:05:54Z",
"media_status":"TRANSCODE_COMPLETED",
"media_key":"966947208837742592",
"media_type":"IMAGE",
"updated_at":"2018-02-23T08:06:17Z",
"deleted":false
}
}
```
**Tweet**
We can create the Tweet by referencing the images using media\_keys.
```
twurl -X POST -H ads-api.x.com "/9/accounts/18ce54d4x5t/tweet?text=coffee&media_keys=966947208837742592&as_user_id=756201191646691328&trim_user=true"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data":{
"created_at":"Fri Feb 23 08:20:05 +0000 2018",
"id":966950781302665218,
"id_str":"966950781302665218",
"text":"coffee https://t.co/T772Hx5GNT",
"truncated":false,
"entities":{
"hashtags":[
],
"symbols":[
],
"user_mentions":[
],
"urls":[
],
"media":[
{
"id":966947208837742592,
"id_str":"966947208837742592",
"indices":[
7,
30
],
"media_url":"http://pbs.twimg.com/media/DWtJXQNUQAAdPZj.jpg",
"media_url_https":"https://pbs.twimg.com/media/DWtJXQNUQAAdPZj.jpg",
"url":"https://t.co/T772Hx5GNT",
"display_url":"pic.x.com/T772Hx5GNT",
"expanded_url":"https://x.com/apimctestface/status/966950781302665218/photo/1",
"type":"photo",
"sizes":{
"thumb":{
"w":150,
"h":150,
"resize":"crop"
},
"large":{
"w":800,
"h":418,
"resize":"fit"
},
"medium":{
"w":800,
"h":418,
"resize":"fit"
},
"small":{
"w":680,
"h":355,
"resize":"fit"
}
}
}
]
},
"source":"Ads API Internal Test App",
"in_reply_to_status_id":null,
"in_reply_to_status_id_str":null,
"in_reply_to_user_id":null,
"in_reply_to_user_id_str":null,
"in_reply_to_screen_name":null,
"user":{
"id":756201191646691328,
"id_str":"756201191646691328"
},
"geo":null,
"coordinates":null,
"place":null,
"contributors":[
2417045708
],
"retweet_count":0,
"favorite_count":0,
"favorited":false,
"retweeted":false,
"possibly_sensitive":false,
"scopes":{
"followers":false
},
"lang":"en"
},
"request":{
"params":{
"as_user_id":756201191646691328,
"text":"coffee",
"account_id":"18ce54d4x5t",
"media_keys":[
966947208837742592
],
"trim_user":true
}
}
}
```
**Website Card**
All of our cards endpoints support media keys. We will create the [website card](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/website#post-accounts-account-id-cards-website) by referencing the image’s media\_key.
```
twurl -X POST -H ads-api.x.com "/11/accounts/18ce54d4x5t/cards"
```
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "components create cards",
"components": [
{
"type": "MEDIA",
"media_key": "3_1323490622599176192"
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "INSTALL"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android"
}
}
]
}
```
We then associate this card with a Tweet using its card\_uri.
### Identifying Cards
#### Introduction
Cards are customizable ad formats that use media and that can be associated with a website, an app, or with calls to action to drive certain user engagements, such as starting a Direct Message. They can be appended to Tweets, Scheduled Tweets, or Draft Tweets.
Cards may be referenced in Tweet objects in one of two ways: by the card's card\_uri or by its preview\_url. Example values for each are presented below.
| card\_uri | preview\_url |
| :------------------------- | :----------------------------------------------------------------------------------------- |
| card://1043282691834048513 | [https://cards.x.com/cards/18ce54d4x5t/68w3s](https://cards.x.com/cards/18ce54d4x5t/68w3s) |
**Note**: As of Ads API version 3, only the card\_uri is generated and returned in the cards response for newly created cards.
**Note**: As of Ads API version 5, the preview\_url in the cards response is no longer returned.
The type of reference in the Tweet object response will depend on the way the Tweet was created. In other words, if the Tweet was created using the card\_uri request parameter, the card URI value will appear in the response. If the preview\_url was included as part of the Tweet text, on the other hand, the preview URL will appear in the response.
#### Identifying Tweets with card\_uri
For Tweets created using the card's URI value, find the reference to the card in the card\_uri response attribute. The example response below uses the [GET accounts/:account\_id/tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/tweets#get-accounts-account-id-tweets) endpoint.
```bash title="Example request" expandable lines wrap icon="terminal" theme={null}
$ twurl -H ads-api.x.com "/9/accounts/18ce54d4x5t/tweets?trim_user=true&tweet_type=PUBLISHED&tweet_ids=1043551275923591168"
{
"request": {
"params": {
"tweet_ids": [
"1043551275923591168"
],
"tweet_type": "PUBLISHED",
"trim_user": true,
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"coordinates": null,
"retweeted": false,
"source": "Ads API Internal Test App",
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": []
},
"display_text_range": [
0,
15
],
"favorite_count": 0,
"in_reply_to_status_id_str": null,
"geo": null,
"id_str": "1043551275923591168",
"scopes": {
"followers": false
},
"in_reply_to_user_id": null,
"truncated": false,
"retweet_count": 0,
"scheduled_status": null,
"id": 1043551275923591168,
"in_reply_to_status_id": null,
"nullcast": true,
"created_at": "Sat Sep 22 17:23:07 +0000 2018",
"place": null,
"scheduled_at": null,
"tweet_type": "PUBLISHED",
"favorited": false,
"card_uri": "card://1043282691834048513",
"full_text": "Tracking a card",
"lang": "en",
"contributors": [
2417045708
],
"in_reply_to_screen_name": null,
"in_reply_to_user_id_str": null,
"user": {
"id": 756201191646691328,
"id_str": "756201191646691328"
},
"tweet_id": "1043551275923591168"
}
]
}
```
If using the Standard API, use include\_card\_uri=true in the request.
Regardless of which endpoint is used, the card\_uri response attribute will only be rendered if the Tweet was created using a card URI.
For scheduled and draft Tweet objects, the response will always include the card\_uri response attribute.
#### Identifying Tweets with preview\_url
For Tweets created by including the preview URL as part of the Tweet's text, the URL can be found in entities\["urls"]\[i]\["expanded\_url"] (the text field includes a shortened t.co URL), where i is an array index (a Tweet can contain multiple URLs).
For scheduled and draft Tweet objects, the preview URL will always appear in the text field.
#### Fetching cards
To retrieve additional information about a specific card, we provide two endpoints: [GET accounts/:account\_id/cards/all](https://developer.x.com/en/docs/ads/creatives/api-reference/cards-fetch.html#get-accounts-account-id-cards-all) and [GET accounts/:account\_id/cards/all/:card\_id](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/cards-fetch#get-accounts-account-id-cards-all-card-id). The former allows a card to be fetched by card\_uri and the latter by the card's ID. The card's ID is found at the end of the preview\_url. In the example above, the ID is 68w3s.
### Identifying Media
#### Introduction
Media—images, GIFs, and videos—can be added to Tweets and cards. In addition, videos can be used as pre-roll assets and images can be promoted on the [X Audience Platform](https://developer.x.com/en/docs/ads/measurement/overview/twitter-audience-platform). This section describes how to find media references across these entities.
There are two types of media identifiers: IDs and keys. Example values for each are presented below.
| **Media ID** | **Media key** |
| :------------------ | :---------------------- |
| 1029825579531807971 | 13\_1029825579531807971 |
The media key is the ID plus a numeric prefix and an underscore.
#### Images
The following table shows the identifier types currently available in each image-related resource's response as well as the corresponding attribute name(s).
| **Resource** | **Identifier** | **Attribute(s)** |
| :-------------- | :------------- | :-------------------------------------------------------------- |
| Image cards | None | |
| Tweet | Both | `entities["media"]["id_str"]` `entities["media"]["media_key"]` |
| Scheduled Tweet | Both | `media_ids` and `media_keys` |
| Draft Tweet | Both | `media_ids` and `media_keys` |
| Account Media | None | |
| Media Library | Both | `media_id` and `media_key` |
Image cards and Account Media images do not include a reference any media identifier. Tweets only include media IDs. Scheduled and Draft Tweets include both the media ID and media key. The Media Library returns both, too.
For Tweets, the id and id\_str fields in the object within the entities\["media"] array correspond to the media ID. In cases where a Tweet includes multiple images, the references to each media entity can only found in extended\_entities\["media"].
In addition to references to identifiers, it's often important to have access to the image's URL.
| **Resource** | **Attribute(s)** | **Format** |
| :-------------- | :---------------------------------------------------------------------------------- | :--------- |
| Image cards | `image` | .jpg |
| Tweet\* | `entities["media"][0]["media_url"]` or `extended_entities["media"][i]["media_url"]` | .jpg |
| Scheduled Tweet | None | |
| Draft Tweet | None | |
| Account Media | `media_url` | .jpg |
| Media Library | `media_url` | .jpg |
\* This URL locations depend on whether the Tweet contains a single image or multiple images.
All image cards include an image response attribute that contains the X image URL. (For image app download cards, the name is wide\_app\_image.)
For Tweets, the media URL location depends on both the type of media and the endpoint being used. For Tweets with a single image, the URL can be found in entities\["media"]\[0]\["media\_url"]. This is true for both the Ads API and the Standard API. When Tweets contain multiple images, however, the URLs can only be found extended\_entities\["media"]\[i]\["media\_url"]. This is only available in the Standard API.
#### Videos
The following table shows the identifier types currently available in each video-related resource's response as well as the corresponding attribute name(s).
| **Resource** | **Identifier** | **Attribute(s)** |
| :--------------- | :------------- | :-------------------------------------------------------------- |
| Video cards | May be either | `video_content_id` |
| Video poll cards | None | |
| Tweet | Both | `entities["media"]["id_str"]` `entities["media"]["media_key"]` |
| Scheduled Tweet | Both | `media_ids` and `media_keys` |
| Draft Tweet | Both | `media_ids` and `media_keys` |
| Account Media | Media key | `video_id` |
| Media Library | Both | `media_id` and `media_key` |
While video cards (with the exception of poll cards with video) include a video\_content\_id response attribute, there is inconsistency in the type of value returned. In some cases, it's a media ID; in others, it's a media key.
Information about how to access the video's URL is shown below.
| **Resource** | **Attribute(s)** | **Format** |
| :--------------- | :------------------------------------------------------------------ | :----------- |
| Video cards | `video_url` and `video_hls_url` | .vmap .m3u8 |
| Tweet with video | `extended_entities["media"][i]["video_info"]["variants"][j]["url"]` | .mp4 |
| Scheduled Tweet | None | |
| Draft Tweet | None | |
| Account Media | None | |
| Media Library | `media_url` | .mp4 |
Video cards include video\_url and video\_hls\_url response attributes with .vmap and .m3u8 URLs, respectively.
#### Media Library
It's sometimes necessary to retrieve additional information about a media asset. One use case, for video cards, is retrieving the mp4 URL instead of the vmap one. This is available in the Media Library. For details on the available information, see our [Media Library Guide](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/guides/media-library). Most assets belonging to the ads account's FULL promotable user can be found in the library. There are some exceptions, though.
**Fetching media**
As stated above, image cards do not contain references to either media IDs or media keys. As a result, it's not possible to fetch their assets through the Media Library. This is also true for [Account Media](https://developer.x.com/content/developer-twitter/en/docs/ads/creatives/api-reference/account-media#account-media) images.
Video cards require that the video asset be part of the Media Library (or the Videos resource before it) prior to creating it. As a result, these assets will always be retrievable in the Media Library. This is also true for Account Media PREROLL assets.
Finally, media in Tweets are always guaranteed to be in the Media Library.
The following table summarizes which assets are retrievable in the Media Library, taking into account whether the resource response includes an identifier to use in the lookup.
| **Resource** | **In the Media Library** |
| :------------------------------- | :----------------------- |
| Image cards | No |
| Video cards | Yes\* |
| Tweets (any media)\*\* | Yes |
| Scheduled Tweets | Yes |
| Draft Tweets | Yes |
| Account media images | No |
| Account media videos (`PREROLL`) | Yes |
\* For cards where the `video_content_id` is a media key. When the value is a media ID, the asset still exists in the Media Library, but retrieving it involves appending a numeric prefix and underscore to it.
\*\* Tweets only return media IDs. While the asset is guaranteed to exist in the Media Library, fetching it involves appending a numeric prefix and underscore to it.
**Interactions with Account Media**
There are two cases where media assets added to the library are automatically added to the Account Media resource.
* When an AMPLIFY\_VIDEO asset is added to the Media Library, it is automatically added as an Account Media asset as a PREROLL creative type.
* When images that have specific dimensions (see "Creative Types" in our [enumerations page](https://developer.x.com/content/developer-twitter/en/docs/ads/general/overview/enums)) are added to the Media Library, they are automatically added as Account Media assets. The creative type (e.g., INTERSTITIAL) depends on the image dimensions.
### Tweets
#### Introduction
The X Ads API supports three types of Tweets: published, scheduled, and draft.
#### Nullcasted Tweets
Tweets may either be nullcasted (a.k.a. "Promoted-only") or organic. Nullcasted Tweets, once published, do not appear in the user's public timeline, though they are public. Organic Tweets, on the other hand, are served to the user's followers and do appear in the user's public timeline.
**Creating Tweets**
Each of the three Tweet create endpoints supports a Boolean nullcast parameter that gives the API user the option to create nullcasted or organic Tweets. Nullcasted Tweets can be created by the user or by anyone who has permission to create Tweets on the user's behalf. Organic Tweets can only be created by the [full promotable user](https://developer.x.com/content/developer-twitter/en/docs/tutorials/ads-api-hierarchy-terminology#promotable-users).
**Updating Tweets**
It is possible to update the nullcast property for scheduled and draft Tweets. For scheduled Tweets, edits can be made until the Tweet's scheduled\_at time. Draft Tweets can be edited indefinitely. Once published, though, it's not possible to change a Tweet from nullcasted to organic or vice versa.
#### Promoting Tweets
Only published and scheduled Tweets may be promoted. These can either be nullcasted or organic; there's no restriction. An advertiser may promote their own Tweets or another user's Tweets as long as they've obtained permission to do so. (See: [Promoting another user's Tweets](https://developer.x.com/content/developer-twitter/en/docs/tutorials/promoting-another-users-content) for more information.)
Multiple Tweets can be promoted in a single campaign. Similarly, a single Tweet may be promoted in one or more campaigns.
To promote published Tweets, use the [POST accounts/:account\_id/promoted\_tweets endpoint](https://developer.x.com/content/developer-twitter/en/docs/ads/campaign-management/api-reference/promoted-tweets#post-accounts-account-id-promoted-tweets). This associates published Tweets with a line item. To promote scheduled Tweets, use the [POST accounts/:account\_id/scheduled\_promoted\_tweets](https://developer.x.com/content/developer-twitter/en/docs/ads/campaign-management/api-reference/scheduled-promoted-tweets#post-accounts-account-id-scheduled-promoted-tweets) endpoint.
#### Tweet IDs
Published, scheduled, and draft Tweet IDs are [numeric](https://developer.x.com/content/developer-twitter/en/docs/basics/twitter-ids)—they are 64-bit unsigned integers. For example, the following published Tweet's ID is 1166476031668015104.
When published or scheduled Tweets are promoted, a corresponding promoted Tweet entity is created. These entities have their own IDs, which are alpha-numeric and are represented as base-36-encoded values. For example, promoting the published Tweet above—that is, associating it a line item 6c62d—returns the following API response.
```bash title="Example request" expandable lines wrap icon="terminal" theme={null}
$ twurl -X POST -H ads-api.x.com "/9/accounts/18ce54d4x5t/promoted_tweets?line_item_id=6c62d&tweet_ids=1166476031668015104"
{
"request": {
"params": {
"tweet_ids": [
1166476031668015104
],
"line_item_id": "6c62d",
"account_id": "18ce54d4x5t"
}
},
"data": [
{
"line_item_id": "6c62d",
"id": "3qwlq6",
"entity_status": "ACTIVE",
"created_at": "2019-09-12T21:39:10Z",
"updated_at": "2019-09-12T21:39:10Z",
"approval_status": "ACCEPTED",
"tweet_id": "1166476031668015104",
"deleted": false
}
],
"total_count": 1
}
```
In addition to the Tweet ID and the line item ID, which were passed into the create request, the response includes an id field with a value of 3qw1q6, which is the promoted Tweet ID.
### Carousels
#### Introduction
The X Ads API supports creating and retrieving video carousels and image carousels. The carousel is a card type that can contain between 2 and 6 media assets. The carousel card can direct a user to a website or encourage them to install a mobile app. For more information about carousels, their benefits, best practices, and FAQs, see our [Carousel Ads on X](https://business.x.com/en/advertising/carousels.html) page.
A carousel, like any other card type, can be used in Tweets and those Tweets can then be promoted. The workflow is the same as what you're already used to:
1. Upload media
2. Create the card
3. Create the Tweet
4. Promote the Tweet
The only difference is with how the card is created. While other card create requests accept query parameters, carousel card create requests only accept JSON POST bodies.
#### Endpoints
The Ads API supports creating and retrieving carousels.
To create a carousel—any kind—use the [POST accounts/:account\_id/cards](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/cards#post-accounts-account-id-cards) endpoint. To retrieve carousels, use the [GET accounts/:account\_id/cards](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/cards#get-accounts-account-id-cards) endpoint.
#### JSON POST Body
Carousels are created using two components. The first specifies the media assets that will be used. The second specifies information about either the website or the app.
Specifically, a carousel card is created by using the following components, in order:
* One `SWIPEABLE_MEDIA`component, which accepts an array of media keys
* *One* of the following:
* A `DETAILS` component to specify website information
* A `BUTTON` component to specify app information
The `SWIPEABLE_MEDIA` component must include a `media_keys` array where you can specify between 2 and 6 images or videos. The order in which the media keys are passed in determine the order in which they will be rendered.
```json theme={null}
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"13_1089771253848666112",
"13_1191948012077092867"
]
}
```
As a reminder, you can obtain media keys by making a request to the [GET accounts/:account\_id/media\_library](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/media-library#get-accounts-account-id-media-library) endpoint.
The composition of the second component object depends on whether you wish to direct a user to a website or encourage them to install an app. The table below summarizes the two options. (**Note**: all of the listed keys are required.)
| | **Website** | **App** |
| :------------------------- | :----------------------------------------------------------------- | :------------------------------------------------ |
| Specify the component type | `"type": "DETAILS"` | `"type": "BUTTON"` |
| Title/Label | `"title": "X"` | `"label": { "type": "ENUM", "value": "INSTALL" }` |
| Destination | `"destination": { "type": "WEBSITE", "url": "https://www.x.com" }` | `"destination": { "type": "APP", ... }` |
Putting this together, an example website carousel JSON POST body is shown below.
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "website carousel",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"13_1089771253848666112",
"13_1191948012077092867"
]
},
{
"type": "DETAILS",
"title": "X",
"destination": {
"type": "WEBSITE",
"url": "https://www.x.com"
}
}
]
}
```
App destination objects within `BUTTON` components require a country code and at least one app identifier. They optionally accept deep links. For a description of these fields, see the [reference documentation](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/cards#app-destination).
Putting this together, an example app carousel JSON POST body is shown below.
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "app carousel",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"13_1089771253848666112",
"13_1191948012077092867"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "INSTALL"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"iphone_app_id": "333903271"
}
}
]
}
```
#### Example
This section demonstrates how to create a video website carousel card and how to use it in a Tweet. As mentioned above, the workflow is the same as what you're already used to: upload media, create the card, create the Tweet. The only difference is how the card is created.
**Media**
To start, either upload new media assets or use existing ones. For details on how to upload new media assets and add them to the Media Library, see our [Media Library Guide](https://developer.x.com/en/docs/twitter-ads-api/creatives/guides/media-library).
Once your media assets are in the Media Library, fetch them using the [GET accounts/:account\_id/media\_library](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/media-library#get-accounts-account-id-media-library) endpoint. Use the `media_type` request parameter to scope the results to a particular media type.
```bash theme={null}
$ twurl -H ads-api.x.com "/10/accounts/18ce54d4x5t/media_library?media_type=VIDEO"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_type": "VIDEO"
}
},
"next_cursor": null,
"data": [
{
"tweeted": true,
"duration": 5283,
"name": "Sunrise",
"file_name": "sunrise.mp4",
"description": null,
"media_url": "https://video.twimg.com/amplify_video/1089771253848666112/vid/1280x720/tyL-pUBP7GgkS9bl.mp4?tag=9",
"poster_media_key": "3_1089771253848666112",
"media_key": "13_1089771253848666112",
"created_at": "2019-01-28T06:24:48Z",
"media_status": "TRANSCODE_COMPLETED",
"poster_media_url": "https://pbs.twimg.com/amplify_video_thumb/1089771253848666112/img/WOYvToSRZFXUSDzd.jpg",
"title": null,
"media_type": "VIDEO",
"aspect_ratio": "16:9",
"updated_at": "2019-08-23T19:05:33Z",
"deleted": false
},
{
"tweeted": true,
"duration": 15248,
"name": "snow",
"file_name": "snow.mp4",
"description": "Two, three, and to the four",
"media_url": "https://video.twimg.com/amplify_video/1191948012077092867/vid/1280x720/2cOvadcctqqea6Hx.mp4?tag=13",
"poster_media_key": "3_1191948012077092867",
"media_key": "13_1191948012077092867",
"created_at": "2019-11-06T05:18:46Z",
"media_status": "TRANSCODE_COMPLETED",
"poster_media_url": "https://pbs.twimg.com/amplify_video_thumb/1191948012077092867/img/IUbhTRd62SEeIVTf.jpg",
"title": "One",
"media_type": "VIDEO",
"aspect_ratio": "16:9",
"updated_at": "2020-03-27T22:23:18Z",
"deleted": false
}
]
}
```
**Carousel Creation**
Use the [POST accounts/:account\_id/cards](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/cards#post-accounts-account-id-cards) endpoint to create your carousel. Use the media keys from the previous request. Remember, the order in which the media keys are passed in determine the order in which they are rendered.
```bash theme={null}
$ twurl -A "Content-Type: application/json" -X POST -H ads-api.x.com "/10/accounts/18ce54d4x5t/cards" -d '{"name":"website carousel","components":[{"type": "SWIPEABLE_MEDIA","media_keys":["13_1089771253848666112","13_1191948012077092867"]},{"type": "DETAILS","title": "X","destination":{"type":"WEBSITE", "url":"https://www.x.com"}}]}'
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "website carousel",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"13_1089771253848666112",
"13_1191948012077092867"
]
},
{
"type": "DETAILS",
"title": "X",
"destination": {
"type": "WEBSITE",
"url": "https://www.x.com/",
"tco_url": "https://t.co/dyTMHWKWZb"
}
}
],
"id": "ars7m",
"created_at": "2020-11-11T07:51:47Z",
"card_uri": "card://1326432421105995776",
"updated_at": "2020-11-11T07:51:47Z",
"deleted": false,
"card_type": "UNIFIED"
}
}
```
Notice that like with other cards, the carousel card response includes a `card_uri`, which will be used when creating a Tweet.
**Tweet**
Use the [POST accounts/:account\_id/tweet](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/tweets#post-accounts-account-id-tweet) endpoint to create your Tweet. Use the `card_uri` from the previous request. (Response truncated for readability.)
```bash theme={null}
$ twurl -H ads-api.x.com "/9/accounts/18ce54d4x5t/tweet_previews?tweet_type=PUBLISHED&tweet_ids=1326434098324385792"
```
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"created_at": "Wed Nov 11 07:58:27 +0000 2020",
"id": 1326434098324385792,
"id_str": "1326434098324385792",
"text": "Swipe",
"truncated": false,
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": []
},
"source": "Ads API Internal Test App",
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 756201191646691300,
"id_str": "756201191646691328",
...
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": [
2417045708
],
"retweet_count": 0,
"favorite_count": 0,
"favorited": false,
"retweeted": false,
"possibly_sensitive": false,
"scopes": {
"followers": false
},
"lang": "en"
},
"request": {
"params": {
"text": "Swipe",
"as_user_id": 756201191646691300,
"card_uri": "card://1326432421105995776",
"account_id": "18ce54d4x5t"
}
}
}
```
**Tweet Previews**
Use the [GET accounts/:account\_id/tweet\_previews](https://developer.x.com/en/docs/twitter-ads-api/creatives/api-reference/tweet-previews#get-accounts-account-id-tweet-previews) endpoint to see your Tweet.
### creative-metadata-tagging
#### Introduction
This guide is for creative partners, agencies and creative developers to tag assets used within X campaigns to better understand individual asset value and performance.
**Note:** Media assets must only be tagged by the partner or developer creating the media asset. If the user of the media asset did not create the media asset, do not implement metadata tagging.
Creative Metadata Tagging provides attribution of images and videos created by Creative Partners wherever the asset is uploaded to X, or whomever the entity that is uploading the asset. To create the connection between the creative asset and the creative partner, the [XMP](https://exiftool.org/TagNames/XMP.html) standard is used.
#### Tagging Creative Assets
The following table shows the identifier types currently available in each image-related resource's response as well as the corresponding attribute name(s). A tagging tool is needed to tag creative assets. [ExifTool](https://exiftool.org/), a platform-independent Perl library plus a [command-line application](https://exiftool.org/exiftool_pod.html) for reading, writing, and editing meta information, is recommended. See all supported [file types](https://exiftool.org/#supported).
Follow the provided [instructions to install ExifTool](https://exiftool.org/install.html). There are also software packages offered by [Homebrew](https://formulae.brew.sh/) to further simplify the installation by providing the [exiftool install command](https://formulae.brew.sh/formula/exiftool) for macOS and Linux. Confirm your tool is properly installed by entering exiftool -ver in the command line to return the tool’s version number. Learn more about ExifTool command parameters in [ExifTool documentation](https://exiftool.org/).
Creative partners can assign metadata tags on new or existing creative assets with their X app\_id to the contributor XMP tag, and date tag. The creative assets will follow the existing size restrictions when [Uploading Media](/x-api/media/upload-media).
**Note:** X's use of the contributor XMP tag ensures metadata captures values for campaigns on X exclusively.
`exiftool -contributor="" -creative_file.jpg`
`exiftool -date="" -creative_file.jpg`
The app\_id can be found in the [Developer Console](https://developer.x.com/en/portal/dashboard) under Projects & Apps. Example: 16489123
The following example adds app\_id as the contributor tag and date as the date tag for an image:
```
app_id:858382169
```
```
date:2022-03-13
```
```
creative_file: eiffel_tower.jpg
```
```
exiftool -contributor=858382169 eiffel_tower.jpg
```
```
1 image files updated
```
```
exiftool -date=2022-03-13 eiffel_tower.jpg
```
```
1 image files updated
```
Verify that your image has been properly tagged:
`exiftool -xmp:all -G1 `
Example:
`exiftool -xmp:all -G1 eiffel_tower.jpg`
```json theme={null}
[XMP] XMP Toolkit : Image::ExifTool 12.30
```
```json theme={null}
[XMP] Contributor : 858382169
```
```json theme={null}
[XMP] Date : 2022:03:13
```
#### Questions?
If you would like to confirm that your tagging and attribution is successful, please provide sample assets that have been tagged to [adsapi-program@x.com](mailto:adsapi-program@x.com) for a X representative to review.
***
## Full API Reference
For the complete technical reference (all endpoints, parameters, and examples for Cards, Tweets, Media Library, Draft Tweets, Polls, Preroll, Conversation Cards, etc.), see the **[Creatives API Reference](/x-ads-api/creatives/reference)** page.
# Creatives API Reference
Source: https://docs.x.com/x-ads-api/creatives/reference
Endpoint reference for the X Ads Creatives API covering account media, cards, scheduled Tweets, media library, and promoted video creative operations.
## API Reference
### Account Media
#### GET accounts/:account\_id/account\_media
Retrieve details for some or all account media associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/account_media`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired account media by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Scope the response to just the account media that match the specified creative types. More than one creative type may be specified by comma-separating enum values.
Possible values: `BANNER`, `BANNER_TABLET`, `INTERSTITIAL`, `INTERSTITIAL_LANDSCAPE`, `INTERSTITIAL_LANDSCAPE_TABLET`, `INTERSTITIAL_TABLET`, `MEDIUM_RECTANGLE`, `PREROLL`, `VAST_PREROLL`
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/account_media?account_media_ids=3wpx`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_media_ids": [
"3wpx"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"video_id": "13_771791717175468032",
"media_url": null,
"creative_type": "PREROLL",
"id": "3wpx",
"created_at": "2016-09-02T19:27:52Z",
"updated_at": "2016-09-02T19:27:52Z",
"deleted": false
}
]
}
```
Retrieve a specific account media object associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/account_media/:account_media_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the account media you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/account_media/2pnfd`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_media_id": "2pnfd",
"account_id": "18ce54d4x5t"
}
},
"data": {
"video_id": null,
"media_url": "https://pbs.twimg.com/ad_img/890749735862026242/Up07zMym?format=jpg&name=orig",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "2pnfd",
"created_at": "2017-07-28T01:44:41Z",
"updated_at": "2017-07-28T01:44:41Z",
"deleted": false
}
}
```
Delete the specified account media object belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/account_media/:account_media_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the account media you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/account_media/2pnfd`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"video_id": null,
"media_url": "https://pbs.twimg.com/ad_img/890749735862026242/Up07zMym?format=jpg&name=orig",
"creative_type": "INTERSTITIAL_LANDSCAPE_TABLET",
"id": "2pnfd",
"created_at": "2017-07-28T01:44:41Z",
"updated_at": "2017-08-25T17:16:26Z",
"deleted": true
},
"request": {
"params": {
"account_id": "18ce54d4x5t",
"account_media_id": "2pnfd"
}
}
}
```
### Cards
**Note**: To associate a card with a Tweet, use the `card_uri` parameter with either the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet), [POST statuses/update](/x-api/posts/create-post), [POST accounts/:account\_id/scheduled\_tweets](/x-ads-api/creatives/reference#post-accounts-account-id-scheduled-tweets), or the [POST accounts/:account\_id/draft\_tweets](/x-ads-api/creatives/reference#post-accounts-account-id-draft-tweets) endpoints.
Retrieve details for some or all cards associated with the current account.
**Note**: This only returns cards that were created using the POST accounts/:account\_id/cards endpoint. Cards created using other endpoints are not returned.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired card types by specifying a comma-separated list of enum values.
Possible values: `IMAGE_APP`, `IMAGE_CAROUSEL_APP`, `IMAGE_CAROUSEL_WEBSITE`, `IMAGE_MULTI_DEST_CAROUSEL_WEBSITE`, `IMAGE_WEBSITE`, `MIXED_MEDIA_MULTI_DEST_CAROUSEL_WEBSITE`, `MIXED_MEDIA_SINGLE_DEST_CAROUSEL_APP`, `MIXED_MEDIA_SINGLE_DEST_CAROUSEL_WEBSITE`, `VIDEO_APP`, `VIDEO_CAROUSEL_APP`, `VIDEO_CAROUSEL_WEBSITE`, `VIDEO_MULTI_DEST_CAROUSEL_WEBSITE`, `VIDEO_WEBSITE`
Scope the response to just the desired cards by specifying a comma-separated list of identifiers. Up to 200 card IDs may be provided.
Scope the response to just the desired cards by specifying a comma-separated list of identifiers. Up to 200 card URI values may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 200
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Include legacy website and app cards in the response. Legacy cards are those whose resource URL has the following format: accounts/:account\_id/cards/:card\_type.
An optional query to scope cards by `name`. Omit this parameter to retrieve all. Maximum length: 80 characters.
**Note**: This performs case-insensitive prefix matching.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards?count=1`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"count": 1,
"account_id": "18ce54d4x5t"
}
},
"next_cursor": "8wzvldqtc",
"data": [
{
"name": "deep link",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"3_1073727809120419840",
"3_1075096386931052545"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "OPEN"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"googleplay_deep_link": "twitter://user?screen_name=apimctestface"
}
}
],
"created_at": "2020-10-28T20:47:52Z",
"card_uri": "card://1321554298900107264",
"id": "1321554298900107264",
"updated_at": "2020-10-28T20:47:52Z",
"deleted": false,
"card_type": "IMAGE_CAROUSEL_APP"
}
]
}
```
Retrieve details for a single card associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The id of the cards.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/1321554298900107264`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"card_id": "1321554298900107264"
}
},
"data": [
{
"name": "deep link",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"3_1073727809120419840",
"3_1075096386931052545"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "OPEN"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"googleplay_deep_link": "twitter://user?screen_name=apimctestface"
}
}
],
"created_at": "2020-10-28T20:47:52Z",
"card_uri": "card://1321554298900107264",
"id": "1321554298900107264",
"updated_at": "2020-10-28T20:47:52Z",
"deleted": false,
"card_type": "IMAGE_CAROUSEL_APP"
}
]
}
```
#### POST accounts/:account\_id/cards
Create a new card associated to the specified account.
Card create requests only accept JSON POST bodies. The `Content-Type` must be set to `application/json`.
See our [Carousels Guide](/x-ads-api/creatives/reference#carousels) for a detailed usage example.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards`
**Parameters[](#parameters "Permalink to this headline")**
The JSON POST body must include a card `name` and an array of `components`. Components are represented as objects and describe the advertiser-facing attributes of the card.
The following example shows the general structure of the payload (but includes non-working information).
```json theme={null}
{
"name": "some name",
"components": [
{
"type": "TYPE_ENUM",
"key": "value"
}
]
}
```
Additional information on components below.
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The name for the card. Maximum length: 80 characters.
Describes the components to use to create the card. Additional information below. Cannot be specified along with `slides`.
**Note**: The order of the components is important.
Use this array of array to create Multi-Destination Carousels. Describes each card as a grouping of components. Each slide should be a complete representation of a card. Cannot be specified along with `components`.
**Note**: The order of each slide is important.
#### Components
Every component must include a `type` field which determines the object's schema. The Ads API supports the following component types, grouped into media- and description-based components.
* Media:
* `MEDIA`: single video or image
* `SWIPEABLE_MEDIA`: between 2-6 videos or images
* Description:
* `DETAILS`
* `BUTTON`
Each component has a set of required fields (in addition to the `type` key). These are listed in the following table.
| Component `type` | Field | Value type |
| :---------------- | :---------------------- | :--------------- |
| `MEDIA` | `media_key` | string |
| `SWIPEABLE_MEDIA` | `media_keys` | array of strings |
| `DETAILS` | `title` `destination` | string object |
| `BUTTON` | `label` `destination` | object object |
The following is an example of a `BUTTON` component in the context of the `components` array (intentionally omitting the `name` key). (The ellipses indicate places where more information would need to be specified.)
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"components": [
{
"type": "BUTTON",
"label": {
...
},
"destination": {
...
}
}
]
}
```
The order in which the component objects are specified defines the top-to-bottom order in which they will be rendered. Cards must be created using one media-based component and either a `DETAILS` or `BUTTON` component. Description-based components are rendered under media and have associated destinations, either URLs or mobile apps.
**Label**
Labels define the text shown on buttons and, therefore, only apply to the `BUTTON` component. Label objects have two required keys: `type` and `value`. The `type` must be set to `ENUM` and the `value` can be one of: `BOOK`, `CONNECT`, `INSTALL`, `OPEN`, `ORDER`, `PLAY`, or `SHOP`.
Building on the previous example, the following shows the `label` object within the `BUTTON` component.
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"components": [
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "INSTALL"
},
"destination": {
...
}
}
]
}
```
**Destination**
Destinations are where advertisers intend to take users. They are always required within `DETAILS` or `BUTTON` components. There are two destination types: `WEBSITE` or `APP`.
**Note**: Website destinations can only be used with `DETAILS` components and app destinations can only be used with `BUTTON` components.
**Website Destination**
The destination type, which determines its schema.
Possible values: `WEBSITE`
\| url *required* | The URL of the website to redirect a user to. Type: string Example: `https://devcommunity.x.com/c/advertiser-api` |
**App Destination**
| Name | Description |
| :----------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type *required* | The destination type, which determines its schema. Type: enum Possible values: `APP` |
| country\_code *required* | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) two-letter code for the country where the app is sold. Type: string Example: `US` |
| googleplay\_app\_id *sometimes required* | The Google Play application package name. **Note**: At least one of following is required: `ios_app_store_identifier` or `googleplay_app_id`. Type: string Example: `com.twitter.android` |
The iOS app store identifier.
**Note**: At least one of following is required: `ios_app_store_identifier` or `googleplay_app_id`.
A deep link into the Android app you're promoting.
**Note**: Can only be used if an `googleplay_app_id` has been provided.
A deep link into the iOS app you're promoting.
**Note**: Can only be used if an `ios_app_store_identifier` has been provided.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/cards`
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "components create cards",
"components": [
{
"type": "MEDIA",
"media_key": "3_1323490622599176192"
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "INSTALL"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android"
}
}
]
}
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "components create cards",
"components": [
{
"type": "MEDIA",
"media_key": "3_1323490622599176192"
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "INSTALL"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android"
}
}
],
"created_at": "2020-11-11T05:42:25Z",
"card_uri": "card://1326399865065238531",
"id": "1321554298900107264",
"updated_at": "2020-11-11T05:42:25Z",
"deleted": false,
"card_type": "IMAGE_APP"
}
}
```
Update the specified associated with the current account.
Card edit requests only accept JSON POST bodies. The `Content-Type` must be set to `application/json`.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/1321554298900107264`
**Parameters[](#parameters "Permalink to this headline")**
The JSON POST body must include the parameters that will be updated. The request will **replace** each field with the parameters specified within the payload. Components are represented as objects and describe the advertiser-facing attributes of the card.
The following example shows the general structure of the payload (but includes non-working information).
```json theme={null}
{
"name": "some name",
"components": [
{
"type": "TYPE_ENUM",
"key": "value"
}
]
}
```
Additional information on components and slides in **POST accounts/:account\_id/cards**.
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The name for the card. Maximum length: 80 characters.
Describes the components to use to update the card. Additional information below. Cannot be specified along with `slides`.
**Note**: The order of the components is important.
Use this array of array to update Multi-Destination Carousels. Describes each card as a grouping of components. Each slide should be a complete representation of a card. Cannot be specified along with `components`.
**Note**: The order of each slide is important.
**Example Request[](#example-request "Permalink to this headline")**
This example updates both the name and removes one of the media\_keys from the components field from the example above.
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/1321554298900107264`
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"name": "changed name",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"3_1075096386931052545"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "OPEN"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"googleplay_deep_link": "twitter://user?screen_name=apimctestface"
}
}
]
}
```
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"card_id": "1321554298900107264"
}
},
"data": [
{
"name": "changed name",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"3_1075096386931052545"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "OPEN"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"googleplay_deep_link": "twitter://user?screen_name=apimctestface"
}
}
],
"created_at": "2020-10-28T20:47:52Z",
"card_uri": "card://1321554298900107264",
"id": "1321554298900107264",
"updated_at": "2020-10-29T20:47:52Z",
"deleted": false,
"card_type": "IMAGE_CAROUSEL_APP"
}
]
}
```
Delete the specified card belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The id of the card to be deleted.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/1321554298900107264`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"card_id": "1321554298900107264"
}
},
"data": [
{
"name": "deep link",
"components": [
{
"type": "SWIPEABLE_MEDIA",
"media_keys": [
"3_1073727809120419840",
"3_1075096386931052545"
]
},
{
"type": "BUTTON",
"label": {
"type": "ENUM",
"value": "OPEN"
},
"destination": {
"type": "APP",
"country_code": "US",
"googleplay_app_id": "com.twitter.android",
"googleplay_deep_link": "twitter://user?screen_name=apimctestface"
}
}
],
"created_at": "2020-10-28T20:47:52Z",
"card_uri": "card://1321554298900107264",
"id": "1321554298900107264",
"updated_at": "2020-10-29T20:47:52Z",
"deleted": true,
"card_type": "IMAGE_CAROUSEL_APP"
}
]
}
```
### Cards Fetch
Retrieve multiple cards, by `card_uri`, associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/all`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired cards by specifying a comma-separated list of identifiers. Up to 200 card URI values may be provided.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/all?card_uris=card://1044294149527166979,card://1044301099031658496`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_uris": [
"card://1044294149527166979",
"card://1044301099031658496"
],
"account_id": "18ce54d4x5t"
}
},
"data": [
{
"name": "X App",
"googleplay_app_id": "com.twitter.android",
"image_display_height": "836",
"country_code": "US",
"id": "692xn",
"wide_app_image": "https://pbs.twimg.com/media/Dc263l9VwAAAeEH.jpg",
"created_at": "2018-09-24T18:35:01Z",
"image_display_width": "1600",
"card_uri": "card://1044294149527166979",
"updated_at": "2018-09-24T18:35:01Z",
"app_cta": "INSTALL",
"deleted": false,
"card_type": "IMAGE_APP_DOWNLOAD"
},
{
"video_poster_height": "9",
"name": "Developer Platform",
"website_shortened_url": "https://t.co/zadeUSVD18",
"video_height": "9",
"video_url": "https://video.twimg.com/amplify_video/vmap/991374284135137280.vmap",
"content_duration_seconds": "24",
"video_owner_id": "756201191646691328",
"video_content_id": "13_991374284135137280",
"website_display_url": "developer.x.com",
"id": "6933h",
"video_width": "16",
"video_hls_url": "https://video.twimg.com/amplify_video/991374284135137280/pl/sQrBsE9mFvNep9Cx.m3u8?tag=2",
"website_dest_url": "https://developer.x.com",
"created_at": "2018-09-24T19:02:38Z",
"card_uri": "card://1044301099031658496",
"title": "Developer Platform",
"website_url": "https://developer.x.com",
"updated_at": "2018-09-24T19:02:38Z",
"video_poster_url": "https://pbs.twimg.com/amplify_video_thumb/991374284135137280/img/YbbGQHvWRjoFgrLz.jpg",
"video_poster_width": "16",
"deleted": false,
"card_type": "VIDEO_WEBSITE"
}
]
}
```
Retrieve a specific card, by `card_id`, associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/all/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the card you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/all/508pf`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_id": "508pf",
"account_id": "18ce54d4x5t"
}
},
"data": {
"video_poster_height": "9",
"name": "video website card",
"video_height": "9",
"video_url": "https://video.twimg.com/amplify_video/vmap/867520357225418752.vmap",
"content_duration_seconds": "21",
"video_owner_id": "756201191646691328",
"video_content_id": "13_867520357225418752",
"website_display_url": "developer.x.com",
"id": "508pf",
"video_width": "16",
"video_hls_url": "https://video.twimg.com/amplify_video/867520357225418752/pl/TPHeH5ZlHFCa2TeJ.m3u8",
"website_dest_url": "/x-ads-api/creatives/reference#post-accounts-account-id-cards-video-website",
"created_at": "2017-11-10T09:00:35Z",
"card_uri": "card://928910245920829440",
"title": "VWC",
"website_url": "https://t.co/F81hp59pUF",
"updated_at": "2018-01-05T05:43:31Z",
"video_poster_url": "https://pbs.twimg.com/amplify_video_thumb/867520357225418752/img/E3pnXM0sCKnRsFih.jpg",
"video_poster_width": "16",
"deleted": false,
"card_type": "VIDEO_WEBSITE"
}
}
```
### Draft Tweets
#### GET accounts/:account\_id/draft\_tweets
Retrieve details for some or all Draft Tweets associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 200
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Specify the user to retrieve Draft Tweets for. Defaults to the `FULL` promotable user on the account when not set.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets?count=1`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"count": 1
}
},
"data": [
{
"name" null,
"text": "hello, world",
"user_id": "756201191646691328",
"id": "994791681219231744",
"nullcast": true,
"created_at": "2018-05-11T04:09:53Z",
"card_uri": null,
"updated_at": "2018-05-11T04:09:53Z",
"media_keys": []
}
],
"next_cursor": "c-jh1g0ryb"
}
```
Retrieve a specific Draft Tweet associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets/:draft_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Draft Tweet you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets/994788364334325760`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"draft_tweet_id": "994788364334325760"
}
},
"data": {
"name": null,
"text": "#TwitterDev",
"user_id": "756201191646691328",
"id": "994788364334325760",
"nullcast": true,
"created_at": "2018-05-11T03:56:42Z",
"card_uri": "card://958225772740714496",
"updated_at": "2018-05-11T03:56:42Z",
"media_keys": []
}
}
```
#### POST accounts/:account\_id/draft\_tweets
Create a Draft Tweet for the account's full promotable user (default) or the user specified in the `as_user_id` parameter.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The user ID of the advertiser on behalf of whom you are posting the Tweet. The advertiser must grant your handle (or handles) access to their ads account via [ads.x.com](https://ads.x.com/). This permission allows you to call the API using the OAuth tokens of your own handle rather than the advertiser's.
The text of your status update. Required if no `media_keys` are specified.
Associate a card with the Tweet using the `card_uri` value from any cards response, if available.
Associate media with the Tweet by specifying a comma-separated list of identifiers. Include up to 4 images, 1 animated GIF, or 1 video.
**Note**: The media asset must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
Whether to create a nullcasted (or "Promoted-only") Tweet.
The name for the Draft Tweet. Maximum length: 80 characters.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets?as_user_id=756201191646691328&text=Just setting up my X.`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"text": "Just setting up my X.",
"as_user_id": "756201191646691328"
}
},
"data": {
"name": null,
"text": "Just setting up my X.",
"user_id": "756201191646691328",
"id": "994747471329873920",
"nullcast": true,
"created_at": "2018-05-11T01:14:13Z",
"card_uri": null,
"updated_at": "2018-05-11T01:14:13Z",
"media_keys": []
}
}
```
Update the specified Draft Tweet belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets/:draft_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Draft Tweet you are operating with in the request.
Associate a card with the Tweet using the `card_uri` value from any cards response, if available.
**Note**: Unset (remove) by specifying the parameter without a value.
Associate media with the Tweet by specifying a comma-separated list of identifiers. Include up to 4 images, 1 animated GIF, or 1 video.
**Note**: The media asset must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
**Note**: Unset (remove) by specifying the parameter without a value.
Whether to create a nullcasted (or "Promoted-only") Tweet.
The text of your status update.
The name for the Draft Tweet. Maximum length: 80 characters.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets/994747471329873920?text=just setting up my twttr`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"draft_tweet_id": 994747471329873920,
"text": "just setting up my twttr"
}
},
"data": {
"name": null,
"text": "just setting up my twttr",
"user_id": "756201191646691328",
"id": "994747471329873920",
"nullcast": true,
"created_at": "2018-05-11T01:14:13Z",
"card_uri": null,
"updated_at": "2018-05-11T01:16:59Z",
"media_keys": []
}
}
```
Permanently delete the specified Draft Tweet belonging to the current account.
**Note**: We **strongly** recommend deleting drafts once a Tweet or Scheduled Tweet has been created using its metadata.
**Note**: This is a hard delete. As a result, it is not possible to retrieve deleted Draft Tweets.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets/:draft_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Draft Tweet you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets/994787835663155200`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"draft_tweet_id": "994787835663155200"
}
},
"data": {
"name": null,
"text": "hello, world",
"user_id": "756201191646691328",
"id": "994787835663155200",
"nullcast": true,
"status": "DELETED",
"created_at": "2018-05-11T03:54:36Z",
"card_uri": null,
"updated_at": "2018-05-11T04:07:31Z",
"media_keys": []
}
}
```
#### POST accounts/:account\_id/draft\_tweets/preview/:draft\_tweet\_id
Preview a Draft Tweet on a mobile device.
A successful request sends a notification to every device the authenticated user is logged in to. Clicking on the notification opens a timeline that allows the user to see and interact with the Draft Tweet, enabling them to test auto-play, volume, fullscreen, video website card docking, and other behaviors.
**Note**: On-device previews are only visible to the user who receives the notification.
**Note**: Notifications only get sent to X official apps.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/draft_tweets/preview/:draft_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Draft Tweet you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/draft_tweets/preview/996132315829948416`
**Example Response[](#example-response "Permalink to this headline")**
```json theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"draft_tweet_id": "996132315829948416"
}
},
"message": "See @apimctestface's notifications in the X app to preview your Tweet."
}
```
### Image Conversation Cards
**Note**: To associate a card with a Tweet, use the `card_uri` parameter with either the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet), [POST statuses/update](/x-api/posts/create-post), or [POST accounts/:account\_id/scheduled\_tweets](/x-ads-api/creatives/reference#post-accounts-account-id-scheduled-tweets) endpoints.
#### GET accounts/:account\_id/cards/image\_conversation
Retrieve details for some or all image conversation cards associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/image_conversation`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired image conversation cards by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope cards by `name`. Omit this parameter to retrieve all. Maximum length: 80 characters.
**Note**: This performs case-insensitive prefix matching.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/image_conversation?card_ids=59woh`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_type": "image_conversation",
"card_ids": [
"59woh"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"name": "image conversation card",
"first_cta": "#moon",
"image_display_height": "670",
"media_url": "https://pbs.twimg.com/media/DUhZuzxUQAAWZqr.jpg",
"thank_you_text": "thanks",
"id": "59woh",
"first_cta_tweet": "stars",
"media_key": "3_957113581522141184",
"created_at": "2018-01-27T04:58:42Z",
"image_display_width": "1280",
"card_uri": "card://923498485702009837",
"title": "Full moon",
"updated_at": "2018-01-27T04:58:42Z",
"deleted": false,
"card_type": "IMAGE_CONVERSATION"
}
]
}
```
Retrieve a specific image conversation card associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/image_conversation/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the image conversation card you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/image_conversation/59woh`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_type": "image_conversation",
"card_id": "59woh",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "image conversation card",
"first_cta": "#moon",
"image_display_height": "670",
"media_url": "https://pbs.twimg.com/media/DUhZuzxUQAAWZqr.jpg",
"thank_you_text": "thanks",
"id": "59woh",
"first_cta_tweet": "stars",
"media_key": "3_957113581522141184",
"created_at": "2018-01-27T04:58:42Z",
"image_display_width": "1280",
"card_uri": "card://923498485702009837",
"title": "Full moon",
"updated_at": "2018-01-27T04:58:42Z",
"deleted": false,
"card_type": "IMAGE_CONVERSATION"
}
}
```
#### POST accounts/:account\_id/cards/image\_conversation
Create a new image conversation card associated with the specified account.
See [Uploading Media](/x-api/media/quickstart/media-upload-chunked) for useful information on uploading images to our endpoints.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/image_conversation`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The Call-To-Action (CTA) hashtag for the first option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the first CTA is clicked.
The media key for an image to be used in this card.
**Note**: The image must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
**Note**: A minimum image width of 800px and a width:height aspect ratio of 1.91:1 is required.
The name for the card.
The text to be displayed after the CTA is clicked. Maximum length: 23 characters.
The Call-To-Action (CTA) hashtag for the second option. Maximum length: 20 characters (not counting the #).
**Note**: Required if `title` is `not` set.
The Tweet text to be used when the second CTA is clicked.
**Note**: Required if `second_cta` is set.
The title for the card, which appears below the image and above the CTAs. Maximum length: 23 characters.
**Note**: Required if `second_cta` is `not` set.
The Call-To-Action (CTA) hashtag for the third option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the third CTA is clicked.
**Note**: Required if `third_cta` is set.
The Call-To-Action (CTA) hashtag for the fourth option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the fourth CTA is clicked.
**Note**: Required if `fourth_cta` is set.
A `media_key` of an image which will be used in the instant unlock scenario. This is a write-only field. In the response, the API will provide a X URL for this image.
**Note**: The image must be in the account's media library.
**Note**: A minimum image width of 800px and a width:height aspect ratio of 5:2 is required.
The URL to be displayed with the thank you text.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/image_conversation?media_key=3_957113581522141184&name=image conversation card&first_cta=#moon&first_cta_tweet=stars&thank_you_text=thanks&title=Full moon`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"name": "image conversation card",
"first_cta": "#moon",
"image_display_height": "670",
"media_url": "https://pbs.twimg.com/media/DUhZuzxUQAAWZqr.jpg",
"thank_you_text": "thanks",
"id": "59woh",
"first_cta_tweet": "stars",
"media_key": "3_957113581522141184",
"created_at": "2018-01-27T04:58:42Z",
"image_display_width": "1280",
"card_uri": "card://923498485702009837",
"title": "Full moon",
"updated_at": "2018-01-27T04:58:42Z",
"deleted": false,
"card_type": "IMAGE_CONVERSATION"
},
"request": {
"params": {
"name": "image conversation card",
"first_cta": "#moon",
"image_display_height": "670",
"media_url": "https://pbs.twimg.com/media/DUhZuzxUQAAWZqr.jpg",
"thank_you_text": "thanks",
"media_key": "3_957113581522141184",
"account_id": "18ce54d4x5t",
"first_cta_tweet": "stars",
"image_display_width": "1280",
"title": "Full moon",
"card_type": "IMAGE_CONVERSATION"
}
}
}
```
Update the specified image conversation card belonging to the current account.
See [Uploading Media](/x-api/media/quickstart/media-upload-chunked) for useful information on uploading images to our endpoints.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/image_conversation/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the image conversation card you are operating with in the request.
The Call-To-Action (CTA) hashtag for the first option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the first CTA is clicked.
The Call-To-Action (CTA) hashtag for the second option. Maximum length: 20 characters (not counting the #).
**Note**: Required if `title` is `not` set.
The Tweet text to be used when the second CTA is clicked.
**Note**: Required if `second_cta` is set.
The Call-To-Action (CTA) hashtag for the third option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the third CTA is clicked.
**Note**: Required if `third_cta` is set.
The Call-To-Action (CTA) hashtag for the fourth option. Maximum length: 20 characters (not counting the #).
The Tweet text to be used when the fourth CTA is clicked.
**Note**: Required if `fourth_cta` is set.
The media key for an image to be used in this card.
**Note**: The image must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
**Note**: A minimum image width of 800px and a width:height aspect ratio of 1.91:1 is required.
The name for the card.
The text to be displayed after the CTA is clicked. Maximum length: 23 characters.
The URL to be displayed with the thank you text.
The title for the card, which appears below the image and above the CTAs. Maximum length: 23 characters.
**Note**: Required if `second_cta` is `not` set.
A `media_key` of an image which will be used in the instant unlock scenario. This is a write-only field. In the response, the API will provide a X URL for this image.
**Note**: The image must be in the account's media library.
**Note**: A minimum image width of 800px and a width:height aspect ratio of 5:2 is required.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/image_conversation/59woh?name=moon card`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"name": "moon card",
"id": "59woh",
"created_at": "2018-01-27T04:58:42Z",
"card_uri": "card://923498485702009837",
"updated_at": "2018-01-29T21:04:39Z",
"deleted": false,
"card_type": "IMAGE_CONVERSATION"
},
"request": {
"params": {
"account_id": "18ce54d4x5t",
"card_type": "IMAGE_CONVERSATION",
"card_id": "59woh",
"name": "moon card"
}
}
}
```
Permanently delete the specified image conversation card belonging to the current account.
**Note**: This is a hard delete. As a result, it is not possible to retrieve deleted cards.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/image_conversation/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the image conversation card you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/image_conversation/4i0qe`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"name": "image conversation card",
"id": "4i0qe",
"created_at": "2017-07-07T00:03:01Z",
"updated_at": "2017-08-23T13:26:23Z",
"deleted": true,
"card_type": "IMAGE_CONVERSATION"
},
"request": {
"params": {
"card_id": "4i0qe",
"card_type": "image_conversation",
"account_id": "18ce54d4x5t"
}
}
}
```
### Media Library
#### GET accounts/:account\_id/media\_library
Retrieve details for some or all media library objects associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_library`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 50
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired media type.
Possible values: `GIF`, `IMAGE`, `VIDEO`
An optional query to scope resource by `name`, `title`, `file_name`, and `description` fields.
**Note**: This performs case-insensitive *term* matching.
Min, Max length: `1`, `255`
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/media_library?count=1`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"count": 1
}
},
"data": [
{
"tweeted": true,
"name": null,
"file_name": "coffee https://t.co/4tcPU9XUon",
"media_url": "https://pbs.twimg.com/media/DJvnJf_UEAAXnzC.jpg",
"media_category": "TWEET_IMAGE",
"media_key": "3_908573900237180928",
"created_at": "2017-09-15T06:11:12Z",
"media_status": "TRANSCODE_COMPLETED",
"media_type": "IMAGE",
"updated_at": "2017-11-16T06:00:01Z",
"deleted": false
}
],
"next_cursor": "c-1"
}
```
Retrieve a specific media library object associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_library/:media_key`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the media library object you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/media_library/13_909110614026444802`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_key": "13_909110614026444802"
}
},
"data": {
"tweeted": true,
"duration": 39973,
"name": null,
"file_name": "buildings https://t.co/xFdzrHM5QG",
"description": null,
"media_url": "https://video.twimg.com/amplify_video/909110614026444802/vid/1280x720/mfahmfkKVjjk1nGm.mp4",
"media_category": "AMPLIFY_VIDEO",
"poster_media_url": "https://pbs.twimg.com/amplify_video_thumb/909110614026444802/img/QZUNoaiCia0UFNrw.jpg",
"poster_media_key": "3_909110614026444802",
"media_key": "13_909110614026444802",
"created_at": "2017-09-16T17:43:55Z",
"media_status": "TRANSCODE_COMPLETED",
"title": "buildings",
"media_type": "VIDEO",
"aspect_ratio": "16:9",
"updated_at": "2017-09-27T13:04:00Z",
"deleted": false
}
}
```
Associate a media object with the current account. For additional details, please see our [Media Library guide](/x-ads-api/creatives/reference#media-library).
**Note**: When adding a video with the `AMPLIFY_VIDEO` media category to the Media Library, it is automatically available as a `PREROLL` [account\_media](/x-ads-api/creatives/reference#get-accounts-account-id-account-media) asset.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_library`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The `media_key` for the uploaded content. A `media_key` is returned in the POST media/upload response when a `media_category` is specified.
The description that appears under the video when Tweeted. Maximum length: 200 characters.
This is not rendered in the Tweet by default. To display the video's `description`, use the `video_description` parameter with the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet) endpoint.
**Note**: Can only be used with videos.
The file name for the media library object. Maximum length: 255.
The file name can be seen in the media detail of every media asset in the Media Library UI on ads.x.com. This will be empty when the `file_name` is not set.
The name for the media library object. Maximum length: 100.
This is the label under every media asset in the Media Library UI on ads.x.com. The label will be "Untitled" when the `name` is not set.
Specify a poster image for the video using the `media_key` of an uploaded image. If not specified, the first frame will be used.
**Note**: Can only be used with videos.
The title (headline) that appears under the video when Tweeted. Maximum length: 70 characters.
This is not rendered in the Tweet by default. To display the video's `title`, use the `video_title` parameter with the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet) endpoint.
**Note**: Can only be used with videos.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/media_library?media_key=3_931236738554519552`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_key": "3_931236738554519552"
}
},
"data": {
"tweeted": false,
"name": null,
"file_name": null,
"media_url": "https://pbs.twimg.com/media/DOxq4TtV4AAlvh_.jpg",
"media_category": "TWEET_IMAGE",
"media_key": "3_931236738554519552",
"created_at": "2017-11-16T19:05:14Z",
"media_status": "TRANSCODE_COMPLETED",
"media_type": "IMAGE",
"updated_at": "2017-11-16T19:05:23Z",
"deleted": false
}
}
```
Update the specified media library object belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_library/:media_key`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the media library object you are operating with in the request.
The description that appears under the video when Tweeted. Maximum length: 200 characters.
This is not rendered in the Tweet by default. To display the video's `description`, use the `video_description` parameter with the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet) endpoint.
**Note**: Can only be used with videos.
The file name for the media library object. Maximum length: 255.
The file name can be seen in the media detail of every media asset in the Media Library UI on ads.x.com. This will be empty when the `file_name` is not set.
The name for the media library object. Maximum length: 100.
This is the label under every media asset in the Media Library UI on ads.x.com. The label will be "Untitled" when the `name` is not set.
Specify a poster image for the video using the `media_key` of an uploaded image.
**Note**: Can only be used with videos.
The title (headline) that appears under the video when Tweeted. Maximum length: 70 characters.
This is not rendered in the Tweet by default. To display the video's `title`, use the `video_title` parameter with the [POST accounts/:account\_id/tweet](/x-ads-api/creatives/reference#post-accounts-account-id-tweet) endpoint.
**Note**: Can only be used with videos.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/media_library/16_844800354743074820?title=cat GIF&description=in space`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_key": "16_844800354743074820",
"title": "cat GIF",
"description": "in space"
}
},
"data": {
"tweeted": true,
"duration": null,
"name": null,
"file_name": null,
"description": "in space",
"media_url": "https://video.twimg.com/tweet_video/C7lVclqVwAQqTCZ.mp4",
"media_category": "TWEET_GIF",
"poster_media_url": "https://pbs.twimg.com/tweet_video_thumb/C7lVclqVwAQqTCZ.jpg",
"poster_media_key": "3_844800354743074820",
"media_key": "16_844800354743074820",
"created_at": "2017-10-20T09:51:54Z",
"media_status": "TRANSCODE_COMPLETED",
"title": "cat GIF",
"media_type": "GIF",
"aspect_ratio": "125:79",
"updated_at": "2017-10-23T06:37:56Z",
"deleted": false
}
}
```
Delete the specified media library object belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/media_library/:media_key`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the media library object you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/media_library/7_860318603387600896`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"media_key": "7_860318603387600896"
}
},
"data": {
"tweeted": true,
"duration": 14330,
"name": "mountains-on-ads.x.com",
"file_name": "mountains.mp4",
"description": "",
"media_url": "https://video.twimg.com/ext_tw_video/860318603387600896/pu/vid/1280x720/xI3DbvWKxdvICsFW.mp4",
"media_category": "TWEET_VIDEO",
"poster_media_url": "https://pbs.twimg.com/media/C_B3bTRVYAAFBFt.jpg",
"poster_media_key": "3_860318839740915712",
"media_key": "7_860318603387600896",
"created_at": "2017-05-05T02:21:53Z",
"media_status": "TRANSCODE_COMPLETED",
"title": "uploaded on ads.x.com",
"media_type": "VIDEO",
"aspect_ratio": "16:9",
"updated_at": "2017-05-05T02:26:58Z",
"deleted": true
}
}
```
### Poll Cards
#### GET accounts/:account\_id/cards/poll
Retrieve details for some or all poll cards associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/poll`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the desired poll cards by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
An optional query to scope cards by `name`. Omit this parameter to retrieve all. Maximum length: 80 characters.
**Note**: This performs case-insensitive prefix matching.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/poll?card_ids=57i77`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_type": "poll",
"card_ids": [
"57i77"
],
"account_id": "18ce54d4x5t"
}
},
"next_cursor": null,
"data": [
{
"video_poster_height": "9",
"name": "best coast poll",
"start_time": "2018-01-09T04:51:34Z",
"first_choice": "East",
"video_height": "9",
"video_url": "https://video.twimg.com/amplify_video/vmap/950589518557540353.vmap",
"content_duration_seconds": "8",
"second_choice": "West",
"end_time": "2018-01-16T04:51:34Z",
"id": "57i77",
"video_width": "16",
"video_hls_url": "https://video.twimg.com/amplify_video/950589518557540353/vid/1280x720/BRkAhPxFoBREIaFA.mp4",
"created_at": "2018-01-09T04:51:34Z",
"duration_in_minutes": "10080",
"card_uri": "card://950590850777497601",
"updated_at": "2018-01-09T04:51:34Z",
"video_poster_url": "https://pbs.twimg.com/amplify_video_thumb/950589518557540353/img/nZ1vX_MXYqmvbsXP.jpg",
"video_poster_width": "16",
"deleted": false,
"card_type": "VIDEO_POLLS"
}
]
}
```
Retrieve a specific poll card associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/poll/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the poll card you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/poll/57i8t`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"card_type": "poll",
"card_id": "57i8t",
"account_id": "18ce54d4x5t"
}
},
"data": {
"name": "text only poll",
"start_time": "2018-01-09T05:03:05Z",
"first_choice": "Morning",
"second_choice": "Evening",
"end_time": "2018-01-11T05:03:05Z",
"id": "57i8t",
"created_at": "2018-01-09T05:03:05Z",
"duration_in_minutes": "2880",
"card_uri": "card://950593749658189824",
"updated_at": "2018-01-09T05:03:05Z",
"deleted": false,
"card_type": "TEXT_POLLS"
}
}
```
#### POST accounts/:account\_id/cards/poll
Create a new poll card associated with the specified account. This endpoint supports creating poll cards with either an image, a video, or no media. Polls with media are referred to as Media Forward Polls.
**Note**: The Media Forward Polls product is in beta and requires the `PROMOTED_MEDIA_POLLS` account feature.
**Note**: It is not possible to update (PUT) poll cards.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/poll`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The amount of time (in minutes) the poll will remain open. After the specified `duration_in_minutes`, the poll will close and votes will no longer be accepted. This corresponds to `end_time` in the response.
**Note**: This starts as soon as the card is created and not when it is added to a Tweet.
Min: 5, Max: 10080
The first poll choice. Maximum length: 25 characters.
The name for the card.
The second poll choice. Maximum length: 25 characters.
The fourth poll choice. Maximum length: 25 characters.
**Note**: The first, second, and third choices must be set when using this parameter.
The `media_key` of a media library image or video which will be used in this card. This is a write-only field. In the response, the API will provide a X URL for this media.
**Note**: The image or video must be in the account's media library.
**Note**: A minimum image width of 800px and a width:height aspect ratio of 1.91:1 is required.
The third poll choice. Maximum length: 25 characters.
**Note**: The first and second choices must be set when using this parameter.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/poll?duration_in_minutes=10080&first_choice=East&second_choice=West&media_key=13_950589518557540353&name=best coast poll`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"first_choice": "East",
"name": "best coast poll",
"second_choice": "West",
"media_key": "13_950589518557540353",
"duration_in_minutes": 10080
}
},
"data": {
"video_poster_height": "9",
"name": "best coast poll",
"start_time": "2018-01-09T04:51:34Z",
"first_choice": "East",
"video_height": "9",
"video_url": "https://video.twimg.com/amplify_video/vmap/950589518557540353.vmap",
"content_duration_seconds": "8",
"second_choice": "West",
"end_time": "2018-01-16T04:51:34Z",
"id": "57i77",
"video_width": "16",
"video_hls_url": "https://video.twimg.com/amplify_video/950589518557540353/vid/1280x720/BRkAhPxFoBREIaFA.mp4",
"created_at": "2018-01-09T04:51:34Z",
"duration_in_minutes": "10080",
"card_uri": "card://950590850777497601",
"updated_at": "2018-01-09T04:51:34Z",
"video_poster_url": "https://pbs.twimg.com/amplify_video_thumb/950589518557540353/img/nZ1vX_MXYqmvbsXP.jpg",
"video_poster_width": "16",
"deleted": false,
"card_type": "VIDEO_POLLS"
}
}
```
Permanently delete the specified poll card belonging to the current account.
Note: This is a hard delete. As a result, it is not possible to retrieve deleted cards.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/cards/poll/:card_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the poll card you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/cards/poll/57i9t`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"name": "poll with image",
"start_time": "2018-01-09T05:10:51Z",
"id": "57i9t",
"created_at": "2018-01-09T05:10:51Z",
"updated_at": "2018-01-09T05:11:04Z",
"deleted": true,
"card_type": "IMAGE_POLLS"
},
"request": {
"params": {
"card_id": "57i9t",
"card_type": "poll",
"account_id": "18ce54d4x5t"
}
}
}
```
### Preroll Call To Actions
#### GET accounts/:account\_id/preroll\_call\_to\_actions
Retrieve details for some or all preroll Call-To-Actions (CTAs) associated with line items under the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/preroll_call_to_actions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Scope the response to just the preroll CTAs associated with the specified line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 1000
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Scope the response to just the desired preroll CTAs by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided.
Sorts by supported attribute in ascending or descending order. See [Sorting](/x-ads-api/fundamentals/sorting) for more information.
Include deleted results in your request.
Include the `total_count` response attribute.
**Note**: This parameter and `cursor` are exclusive. Requests which include `total_count` will have lower rate limits (currently 200 per 15 minutes).
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/preroll_call_to_actions?line_item_ids=8v53k`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"account_id": "18ce54d4x5t",
"line_item_ids": [
"8v53k"
]
}
},
"next_cursor": null,
"data": [
{
"line_item_id": "8v53k",
"call_to_action_url": "https://www.x.com",
"call_to_action": "VISIT_SITE",
"id": "8f0",
"created_at": "2017-07-07T19:28:40Z",
"updated_at": "2017-07-07T19:28:40Z",
"deleted": false
}
]
}
```
Retrieve a specific Call-to-Action (CTAs) associated with this account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/preroll_call_to_actions/:preroll_call_to_action_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the preroll call to action you are operating with in the request.
Include deleted results in your request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/preroll_call_to_actions/8f0`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"preroll_call_to_action_id": "8f0",
"account_id": "18ce54d4x5t"
}
},
"data": {
"line_item_id": "8v53k",
"call_to_action_url": "https://www.x.com",
"call_to_action": "VISIT_SITE",
"id": "8f0",
"created_at": "2017-07-07T19:28:40Z",
"updated_at": "2017-07-07T19:28:40Z",
"deleted": false
}
}
```
#### POST accounts/:account\_id/preroll\_call\_to\_actions
Set the optional Call-to-Action (CTA) for a `PREROLL_VIEWS` line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/preroll_call_to_actions`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The CTA text for the displayed button within the ad.
Possible values: `GO_TO`, `SEE_MORE`, `SHOP`, `VISIT_SITE`, `WATCH_NOW`
The URL to redirect the user to when the CTA button is clicked.
A reference to the line item you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/preroll_call_to_actions?line_item_id=8v53k&call_to_action=VISIT_SITE&call_to_action_url=https://www.x.com`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8v53k",
"call_to_action_url": "https://www.x.com",
"call_to_action": "VISIT_SITE",
"id": "8f0",
"created_at": "2017-07-07T19:28:40Z",
"updated_at": "2017-07-07T19:28:40Z",
"deleted": false
},
"request": {
"params": {
"line_item_id": "8v53k",
"call_to_action": "VISIT_SITE",
"call_to_action_url": "https://www.x.com",
"account_id": "18ce54d4x5t"
}
}
}
```
Update the optional Call-to-Action (CTA) for a `PREROLL_VIEWS` line item.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/preroll_call_to_actions/:preroll_call_to_action_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the preroll CTA you are operating with in the request.
The CTA text for the displayed button within the ad.
Possible values: `GO_TO`, `SEE_MORE`, `SHOP`, `VISIT_SITE`, `WATCH_NOW`
The URL to redirect the user to when the CTA button is clicked.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/preroll_call_to_actions/8f0?call_to_action=WATCH_NOW`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8v53k",
"call_to_action_url": "https://www.x.com",
"call_to_action": "WATCH_NOW",
"id": "8f0",
"created_at": "2017-07-07T19:28:40Z",
"updated_at": "2017-09-09T05:51:26Z",
"deleted": false
},
"request": {
"params": {
"preroll_call_to_action_id": "8f0",
"call_to_action": "WATCH_NOW",
"account_id": "18ce54d4x5t"
}
}
}
```
Delete the specified preroll Call-to-Action (CTA) belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/preroll_call_to_actions/:preroll_call_to_action_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the preroll CTA you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/preroll_call_to_actions/8f0`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"data": {
"line_item_id": "8v53k",
"call_to_action_url": "https://www.x.com",
"call_to_action": "VISIT_SITE",
"id": "8f0",
"created_at": "2017-07-07T19:28:40Z",
"updated_at": "2017-08-30T06:08:21Z",
"deleted": true
},
"request": {
"params": {
"preroll_call_to_action_id": "8f0",
"account_id": "18ce54d4x5t"
}
}
}
```
### Scheduled Tweets
#### GET accounts/:account\_id/scheduled\_tweets
Retrieve details for some or all Scheduled Tweets associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
Specifies the number of records to try and retrieve per distinct request.
Min: 1, Max: 200
Specifies a cursor to get the next page of results. See [Pagination](/x-ads-api/fundamentals/pagination) for more information.
Specify the user to retrieve Scheduled Tweets for. Defaults to the `FULL` promotable user on the account when not set.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_tweets?count=1`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"count": 1
}
},
"data": [
{
"name": "test name",
"completed_at": "2017-06-18T22:00:05Z",
"text": "where you want to be",
"user_id": "756201191646691328",
"scheduled_status": "SUCCESS",
"id": "875828692081037312",
"nullcast": true,
"created_at": "2017-06-16T21:33:27Z",
"scheduled_at": "2017-06-18T22:00:00Z",
"card_uri": null,
"updated_at": "2017-06-19T18:02:20Z",
"tweet_id": "876560168963645440",
"media_keys": []
}
],
"next_cursor": "c-j41uw400"
}
```
Retrieve a specific Scheduled Tweet associated with the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_tweets/:scheduled_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Scheduled Tweet you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_tweets/917438609065623552`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"scheduled_tweet_id": "917438609065623552"
}
},
"data": {
"name": null,
"completed_at": null,
"text": "",
"user_id": "756201191646691328",
"scheduled_status": "SCHEDULED",
"id": "917438609065623552",
"nullcast": true,
"created_at": "2017-10-09T17:16:24Z",
"scheduled_at": "2018-01-01T00:00:00Z",
"card_uri": null,
"updated_at": "2017-10-09T17:16:24Z",
"tweet_id": null,
"media_keys": [
"3_917438348871983104"
]
}
}
```
#### POST accounts/:account\_id/scheduled\_tweets
Create a Scheduled Tweet for the account's full promotable user (default) or the user specified in the `as_user_id` parameter.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_tweets`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the Tweet should be published (or go live).
**Note**: Tweets can only be scheduled up to one year in the future.
**Note**: Tweets should only be scheduled at minute-granularity; seconds will be ignored.
The user ID of the advertiser on behalf of whom you are posting the Tweet. The advertiser must grant your handle (or handles) access to their ads account via [ads.x.com](https://ads.x.com/). This permission allows you to call the API using the OAuth tokens of your own handle rather than the advertiser's.
The text of your status update. Required if no `media_keys` are specified.
Associate a card with the Tweet using the `card_uri` value from any cards response, if available.
Associate media with the Tweet by specifying a comma-separated list of identifiers. Include up to 4 images, 1 animated GIF, or 1 video.
**Note**: The media asset must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
Whether to create a nullcasted (or "Promoted-only") Tweet.
The name for the Scheduled Tweet. Maximum length: 80 characters.
**Example Request[](#example-request "Permalink to this headline")**
`POST https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_tweets?as_user_id=756201191646691328&media_keys=3_917438348871983104&scheduled_at=2018-01-01`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" expandable lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"media_keys": [
"3_917438348871983104"
],
"scheduled_at": "2018-01-01T00:00:00Z",
"as_user_id": 756201191646691328
}
},
"data": {
"name": null,
"completed_at": null,
"text": "",
"user_id": "756201191646691328",
"scheduled_status": "SCHEDULED",
"id": "917438609065623552",
"nullcast": true,
"created_at": "2017-10-09T17:16:24Z",
"scheduled_at": "2018-01-01T00:00:00Z",
"card_uri": null,
"updated_at": "2017-10-09T17:16:24Z",
"tweet_id": null,
"media_keys": [
"3_917438348871983104"
]
}
}
```
Update the specified Scheduled Tweet belonging to the current account.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_tweets/:scheduled_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Scheduled Tweet you are operating with in the request.
Associate a card with the Tweet using the `card_uri` value from any cards response, if available.
**Note**: Unset (remove) by specifying the parameter without a value.
Associate media with the Tweet by specifying a comma-separated list of identifiers. Include up to 4 images, 1 animated GIF, or 1 video.
**Note**: The media asset must be in the account's [Media Library](/x-ads-api/creatives/reference#media-library).
**Note**: Unset (remove) by specifying the parameter without a value.
Whether to create a nullcasted (or "Promoted-only") Tweet.
The time, expressed in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), that the Tweet should be published (or go live).
The text of your status update.
The name for the Scheduled Tweet. Maximum length: 80 characters.
**Example Request[](#example-request "Permalink to this headline")**
`PUT https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_tweets/875057751231037440?text=winter solstice`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"scheduled_tweet_id": "875057751231037440",
"text": "winter solstice"
}
},
"data": {
"name": null,
"completed_at": null,
"scheduled_status": "SCHEDULED",
"text": "winter solstice",
"user_id": "756201191646691328",
"id": "875057751231037440",
"nullcast": true,
"created_at": "2017-06-14T18:30:00Z",
"scheduled_at": "2017-12-21T00:00:00Z",
"card_uri": null,
"updated_at": "2017-06-14T18:30:00Z",
"tweet_id": null,
"media_keys": []
}
}
```
Permanently delete the specified Scheduled Tweet belonging to the current account.
**Note**: This is a hard delete. As a result, it is not possible to retrieve deleted Scheduled Tweets.
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/scheduled_tweets/:scheduled_tweet_id`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A reference to the Scheduled Tweet you are operating with in the request.
**Example Request[](#example-request "Permalink to this headline")**
`DELETE https://ads-api.x.com/12/accounts/18ce54d4x5t/scheduled_tweets/875064008595787776`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"scheduled_tweet_id": 875064008595787776
}
},
"data": {
"name": null,
"completed_at": null,
"scheduled_status": "DELETED",
"text": "hello, world",
"user_id": "756201191646691328",
"id": "875064008595787776",
"nullcast": true,
"created_at": "2017-06-14T18:54:52Z",
"scheduled_at": "2017-06-15T00:00:00Z",
"card_uri": null,
"updated_at": "2017-06-14T19:01:16Z",
"tweet_id": null,
"media_keys": []
}
}
```
### Tweet Previews
#### GET accounts/:account\_id/tweet\_previews
Preview published, scheduled, or draft Tweets.
* Supports previewing *multiple* Tweets—up to 200—in a single API request
* Accurate, up-to-date rendering of Tweet layout and style
* Supports all the latest formats and card types
* Returns an iframe
**Resource URL[](#resource-url "Permalink to this headline")**
`https://ads-api.x.com/12/accounts/:account_id/tweet_previews`
The identifier for the leveraged account. Appears within the resource's path and is generally a required parameter for all Advertiser API requests. The specified account must be associated with the authenticated user.
A comma-separated list of identifiers. Up to 200 IDs may be provided.
**Note**: The IDs should correspond to the specified `tweet_type`. For example, if a Scheduled Tweet ID is passed in and `tweet_type=PUBLISHED` is specified, a preview for that ID will not be returned.
The Tweet type for the specified `tweet_ids`.
Possible values: `DRAFT`, `PUBLISHED`, `SCHEDULED`
**Example Request[](#example-request "Permalink to this headline")**
`GET https://ads-api.x.com/12/accounts/18ce54d4x5t/tweet_previews?tweet_ids=1122911801354510336,1102836745790316550&tweet_type=PUBLISHED`
**Example Response[](#example-response "Permalink to this headline")**
```json title="Example response" lines wrap icon="https://mintcdn.com/x-preview/Vn2KEkZaPF9LiPi3/icons/xds/icon-brackets.svg?fit=max&auto=format&n=Vn2KEkZaPF9LiPi3&q=85&s=ed2428e77bab43e57800e1a590e982fa" theme={null}
{
"request": {
"params": {
"tweet_ids": [
"1122911801354510336",
"1102836745790316550"
],
"tweet_type": "PUBLISHED",
"account_id": "18ce54d4x5t"
}
},
"data": [
{
"tweet_id": "1122911801354510336",
"preview": "