Developer Docs

X (Twitter) Scraper: Profiles & Posts

Scraping is asynchronous: submit a run → poll → fetch data. See Quick Start for the end-to-end flow; see Auth & Error Handling for the unified response envelope, run state machine, billing, and error handling. This page only lists the target fields and output fields for the two X endpoints.


At a Glance

  • Base URL: https://api.antsdata.com/v1
  • Method & path: submit a run with POST /v1/scraper/x/<resource>; poll and fetch via the shared GET /v1/scraper/runs/{id} endpoints (see Quick Start).
  • Auth: header Authorization: Bearer ants_xxx (static API Key).
  • Content-Type: application/json
  • Request body: always { "deliveryMode": "async", "recordLimit": <per-target record cap>, "targets": [ ... ] }; the fields of each targets[] element are listed per endpoint below.

💡 You can also use deliveryMode: "sync" (small jobs block until terminal, auto fallback to polling on timeout) — see quick-start · Sync mode.

  • Billing: charged by the number of records successfully produced; failed targets are released and not billed. See Auth & Error Handling.

Endpoints

Endpoint Description Key target fields
POST /v1/scraper/x/profile Account profile username
POST /v1/scraper/x/posts Account posts username, maxResults

Profile

Collect the public profile of an X account.

Target fields (each targets[] element):

Field Type Required Description
username string X username (without @)

Output fields (each record in records):

Field Type Description
username string Username (unique identifier).
displayName string Display name.
bio string Bio.
location string Location.
websiteUrl string External website URL.
followersCount number Follower count.
followingCount number Following count.
postsCount number Total number of posts.
likesCount number Total like count received (when available).
isVerified boolean Whether the account has a verified badge.
isPrivate boolean Whether the account is private.
createdAt string Account creation time.
profileImageUrl string Avatar URL.
bannerImageUrl string Banner image URL.
profileUrl string Profile URL.

Submit example:

curl -X POST "https://api.antsdata.com/v1/scraper/x/profile" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "deliveryMode": "async",
    "recordLimit": 1000,
    "targets": [
      { "username": "jack" },
      { "username": "elonmusk" }
    ]
  }'

The submit returns HTTP 201 with data containing the run id and status: "queued"; then poll GET /v1/scraper/runs/{id} until succeeded and fetch records, following Quick Start.


Posts

Collect the list of posts published by a given account.

Target fields (each targets[] element):

Field Type Required Description
username string X username (without @)
maxResults number Max posts returned for this account (whichever is smaller with the run-level recordLimit)

Output fields (each record in records):

Field Type Description
id string Post ID.
url string Post URL.
text string Post text content.
createdAt string Published time.
author object Author of the post.
author.username string Author username.
author.displayName string Author display name.
author.profileUrl string Author profile URL.
metrics object Engagement metrics of the post.
metrics.likeCount number Like count.
metrics.retweetCount number Repost count.
metrics.replyCount number Comment count.
metrics.quoteCount number Quote count.
metrics.impressionCount number View count.
entities object Entities extracted from the post text.
entities.hashtags array List of hashtags.
entities.mentions array List of mentioned usernames.
entities.urls array List of links contained in the post.
entities.urls.expandedUrl string Full expanded URL.
entities.urls.displayUrl string Shortened URL as displayed on the page.
media array List of media attached to the post.
media.type string Media type: photo / video / gif.
media.url string Direct media URL.
media.previewUrl string Thumbnail URL.
media.altText string Alternative text of the image.
isReply boolean Whether the post is a reply.
isRetweet boolean Whether the post is a repost.
isQuoteTweet boolean Whether the post is a quote post.
quotedTweet object The quoted post, when present.
quotedTweet.id string ID of the quoted post.
quotedTweet.text string Text of the quoted post.
quotedTweet.authorUsername string Username of the quoted post author.
lang string Language code.

Submit example:

curl -X POST "https://api.antsdata.com/v1/scraper/x/posts" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "deliveryMode": "async",
    "recordLimit": 200,
    "targets": [
      { "username": "elonmusk", "maxResults": 100 }
    ]
  }'

The submit returns HTTP 201 with data.id as the run id and status: "queued"; poll and fetch as in Quick Start.


Fetching Data

Once the run reaches succeeded, fetch records or download by run id (each record has the "Output fields" shape above):

  • Paginated records: GET /v1/scraper/runs/{id}/records?page=1&pageSize=20
  • Download: GET /v1/scraper/runs/{id}/download?format=json|csv|excel

See Quick Start for the full poll-and-fetch example.


Next Steps


FAQ

Q: Why isn't the profile / post data returned right after I submit?

Scraping is asynchronous: the submit returns a run id, the work runs in the background, and you fetch records by id once it reaches succeeded. See Quick Start.

Q: Can I scrape multiple accounts at once?

Yes. targets is an array, so one run can contain multiple accounts that execute in parallel; per-account status is reported in the run object's tasks[].

Q: Should the username include @?

No. Pass the bare handle (e.g. elonmusk).

Q: What happens with private or non-existent accounts?

That target is reported in tasks[] with status: "failed" and an errorMessage, while other targets can still succeed (partial success still produces data); failed targets are released and not billed.