# Tweet Lookup API – Tweets by ID or URL (`sfoln/x-posts-lookup`)

Look up X (Twitter) posts by ID or URL in bulk: full text, author, date, likes, reposts, replies, quotes, views, media, hashtags and reply or quote links, one record per post. Deleted or protected posts are flagged as not_found. $0.70 per 1,000 posts.

- Family: Social media data
- Categories: Social media, News, Lead generation
- Availability: on request (private on Apify). Email contact@sfoln.com with subject "Access request: Tweet Lookup API – Tweets by ID or URL (sfoln/x-posts-lookup)" before calling; calls fail until it is public.
- JSON: https://www.sfoln.com/actors/x-posts-lookup.json
- MCP: https://mcp.apify.com?tools=sfoln/x-posts-lookup
- REST (sync): POST https://api.apify.com/v2/actors/sfoln~x-posts-lookup/run-sync-get-dataset-items
- REST (async): POST https://api.apify.com/v2/actors/sfoln~x-posts-lookup/runs

Tweet Lookup API – Tweets by ID or URL fetches X (Twitter) posts by ID or URL in bulk and returns one normalized record per requested post: full text, author, timestamp, likes, reposts, replies, quotes, views, bookmarks, media (incl. best MP4), hashtags, mentions, links, and reply / quote / repost relations. Ideal for refreshing engagement on a list of posts, enriching links collected elsewhere, verifying whether posts still exist, and feeding LLM pipelines.

## Price per delivered record

| Event | Price | Per 1,000 | Charged for |
| --- | --- | --- | --- |
| X post (`x-post-looked-up`) | $0.0007 | $0.70 / 1,000 | Charged once per requested post id or URL for which the post was returned, or for which the upstream confirmed it does not exist (deleted, protected or never existed). |

Pay-per-event, USD, billed by Apify; no platform usage charge. Only records with status `ok` are charged. Cap a run with `maxTotalChargeUsd`. Apify free plan: up to 10 per run.

## Run

```bash
curl -X POST "https://api.apify.com/v2/actors/sfoln~x-posts-lookup/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"posts":["https://x.com/jack/status/20"]}'
```

MCP client configuration:

```json
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/x-posts-lookup"
    }
  }
}
```

Example prompt: Fetch the post https://x.com/jack/status/20 and report its text, author, likes, reposts and views.

## Input

Paste post (tweet) ids or x.com / twitter.com status URLs. Each requested post produces exactly one dataset record.

| Field | Type | Default | Meaning |
| --- | --- | --- | --- |
| `posts` (required) | array | — | Post ids or URLs: Numeric post ids or status URLs such as https://x.com/jack/status/20, one per line. Duplicates are removed. Accounts on the Apify free plan can process up to 10 posts per run. |
| `maxItems` | integer | `10000` | Max posts: Safety cap on the number of posts looked up in this run. |
| `includeRaw` | boolean | `false` | Include raw upstream response: Attach the unmodified TwitterAPI.io payload to each record under `raw` (larger output). |

Example input:

```json
{
  "posts": [
    "https://x.com/jack/status/20"
  ]
}
```

## Output

One record per input item with `status` (`ok` is charged; `not_found`, `error`, `skipped_*` are free) and `charged`. The run stores an `OUTPUT` summary record.

| Field | Type | Meaning |
| --- | --- | --- |
| `input` | string | object | Input: The input item this record corresponds to. |
| `status` | string | Status: ok \| not_found \| error \| skipped_invalid \| skipped_budget \| skipped_free_plan |
| `charged` | boolean | Charged: Whether this record incurred a pay-per-event charge. |
| `chargedEvent` | string | Charged event: Pay-per-event event charged for this record. |
| `source` | string | Source: Upstream data source (twitterapi = TwitterAPI.io). |
| `fetchedAt` | string | Fetched at: ISO timestamp. |
| `error` | object | Error: code / message when status is not ok. |
| `warnings` | array | Warnings: Non-fatal notes (e.g. stopped early). |
| `tweetId` | string | Requested id: Post id extracted from the input. |
| `found` | boolean | Found: true when the post was returned. |
| `id` | string | null | Post id: Numeric post (tweet) id as a string. |
| `url` | string | null | URL: Link to the post on x.com. |
| `text` | string | null | Text: Full post text. |
| `createdAt` | string | null | Created at: ISO 8601 creation time. |
| `lang` | string | null | Language: Language code detected by X. |
| `authorHandle` | string | null | Author handle: Author's @handle without @. |
| `authorId` | string | null | Author id: Author's numeric user id. |
| `authorName` | string | null | Author name: Author display name. |
| `authorFollowers` | integer | null | Author followers: Author follower count at fetch time. |
| `authorIsBlueVerified` | boolean | null | Author blue verified: Author has a blue check. |
| `likes` | integer | null | Likes: Like count. |
| `retweets` | integer | null | Reposts: Repost (retweet) count. |
| `replies` | integer | null | Replies: Reply count. |
| `quotes` | integer | null | Quotes: Quote count. |
| `views` | integer | null | Views: View count (null when X does not report it). |
| `bookmarks` | integer | null | Bookmarks: Bookmark count. |
| `isReply` | boolean | Is reply: Post is a reply. |
| `inReplyToId` | string | null | In reply to post: Parent post id. |
| `inReplyToUserId` | string | null | In reply to user id: Parent author id. |
| `inReplyToHandle` | string | null | In reply to handle: Parent author handle. |
| `conversationId` | string | null | Conversation id: Root post id of the thread. |
| `isRetweet` | boolean | Is repost: Post is a repost (retweet). |
| `retweetedTweetId` | string | null | Reposted post id: Original post id for reposts. |
| `isQuote` | boolean | Is quote: Post quotes another post. |
| `quotedTweetId` | string | null | Quoted post id: Quoted post id. |
| `hashtags` | array | Hashtags: Hashtags without #. |
| `mentions` | array | Mentions: Mentioned handles without @. |
| `urls` | array | Links: Expanded links in the post. |
| `media` | array | Media: Photos / videos: type, url, videoUrl (best MP4), expandedUrl. |
| `mediaCount` | integer | Media count: Number of attached media items. |
| `postedVia` | string | null | Posted via: Client app used to post (e.g. Twitter for iPhone). |

Example record:

```json
{
  "input": "https://x.com/jack/status/20",
  "tweetId": "20",
  "found": true,
  "id": "20",
  "url": "https://x.com/jack/status/20",
  "text": "just setting up my twttr",
  "createdAt": "2006-03-21T20:50:14.000Z",
  "lang": "en",
  "postedVia": "Twitter Web Client",
  "authorHandle": "jack",
  "authorId": "12",
  "authorName": "jack",
  "authorFollowers": 6500000,
  "authorIsBlueVerified": false,
  "likes": 300000,
  "retweets": 120000,
  "replies": 15000,
  "quotes": 9000,
  "views": null,
  "bookmarks": 2000,
  "isReply": false,
  "inReplyToId": null,
  "inReplyToUserId": null,
  "inReplyToHandle": null,
  "conversationId": "20",
  "isRetweet": false,
  "retweetedTweetId": null,
  "isQuote": false,
  "quotedTweetId": null,
  "hashtags": [],
  "mentions": [],
  "urls": [],
  "media": [],
  "mediaCount": 0,
  "status": "ok",
  "charged": true,
  "chargedEvent": "x-post-looked-up",
  "source": "twitterapi",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}
```

## Related

- [Tweet Thread Context API – Replies & Author](https://www.sfoln.com/actors/x-post-context.md) (`sfoln/x-post-context`)
- [Tweet Replies Scraper (X / Twitter)](https://www.sfoln.com/actors/x-post-replies.md) (`sfoln/x-post-replies`)
- [Twitter Mentions Scraper (X)](https://www.sfoln.com/actors/x-user-mentions.md) (`sfoln/x-user-mentions`)
- [Twitter Profile Scraper (X)](https://www.sfoln.com/actors/x-profile-lookup.md) (`sfoln/x-profile-lookup`)

Publisher: SFOLN LLC, contact@sfoln.com. Catalogue: https://www.sfoln.com/catalog.json. Agent guide: https://www.sfoln.com/agents.md.
