X Ads Repository

X Ads Repository API (beta)

Promoted posts from X's EU Ads Repository by handle, with the post's text and media. In beta: X's repository search often fails on X's side right now.

Coverage
Ads delivered in the EU, Iceland, Liechtenstein and Norway, from 26 August 2023. Without a country, the search goes through the countries one page at a time.
Price
1 credit per ad. 1 credit per delivered ad. A live search page costs at most 5 credits. Ads last shown more than 12 months ago cost double. Failed calls, such as X's over-capacity errors, are free, as are empty and cached results.
Status
X publishes no status and no run dates. status is unknown; use our last_seen_by_us.

Find ads by

  • Handle or exact name (advertiser=nike)
  • User id (advertiser=x:…)
  • Domain (domain=nike.com), turned into a handle guess
  • Ad id (GET /v1/ads/x:{post id}): the post's creative only
  • Our archive (source=history)

Filters

  • country: EU countries, IS, LI and NO
  • from / to: default the last 30 days, not before 26 August 2023

What you get for each ad

The same fields as every other platform, in one schema. What X publishes is filled in; what it does not stays null.

Ad and advertiser

id
x:<post id>
advertiser.id, advertiser.name
The X account
advertiser.verified
true for blue-verified accounts, else null
extra.tweet_created_at
When the post was created

Creative

creatives[]
The post's text, card title as headline, first link as landing_url, images and videos
formats
text, image, video or carousel (several media)
library_url
The post on x.com

Delivery

countries
Countries the ad was delivered in
impressions_range
Impressions summed over the repository's records

Only for ads shown in the EU

Published under the Digital Services Act; see EU reach.

  • eu_data.reach_by_country and eu_data.reach_total: reach summed per country
  • eu_data.targeting: ages, genders, locations and other targeting types
  • Not confirmed yet: reach, impressions and targeting follow the record format of X's own repository page, because X's search has not returned a full answer we could check

What X does not publish

  • Run dates: first_shown and last_shown are null
  • Payer and beneficiary
  • Spend and placements
  • An active flag: status is always unknown
  • The account's website, so a domain is never proven on X
  • Keyword and format search

Try it

Nike's promoted posts in Germany. While X's search is over capacity this call fails and costs nothing.

Media: Images and videos of the promoted post. Images are copied to media.adlibapi.com under stable URLs, and videos are archived for advertisers on a watchlist.

curl "https://api.adlibapi.com/v1/search?platform=x&advertiser=nike&country=DE" \
  -H "X-API-Key: $ADLIB_API_KEY"

What to do with it

  • Add X to a competitor watchlist so its posts are recorded once X answers.
  • Pull the text and media of a brand's promoted posts by id.

Limits

  • Beta: X's repository search often answers 503 over capacity for advertisers that have ads.
  • Cross-platform search skips X; ask for it with platform=x.
  • GET /v1/ads/{id} returns the creative only, without reach or targeting.
  • Domain search guesses a handle from the domain; it is not checked against the account's website.

Questions

Does X (Twitter) have an ad library?
Yes, the Ads Repository, for ads delivered in the EU, Iceland, Liechtenstein and Norway. Its search often fails on X's side at the moment, so AdLib marks X as beta.
Can I search X ads by keyword?
No. X's repository searches by account only. Search by handle, user id or domain.
Why does my X search return an error?
X's repository answers 503 over capacity for many advertisers with ads. AdLib passes the error on and does not bill it. Try again later or put the account on a watchlist.

Read more

Other platforms

Questions about X data? [email protected]