# How can Claude or another AI agent read a tweet from an x.com link?

> X blocks most bots, so Claude's web fetch fails on x.com links. Give the agent a tool that fetches an X post's text, media and engagement by its link. Cost and code.

Canonical page: https://okdata.online/answers/ai-agent-read-tweet-from-link/

**Short answer: **Give the agent a tool that fetches the post by its link instead of loading x.com: okdata's X post detail takes an x.com or twitter.com status link and returns the text, media, views, likes, reposts and reply count for $0.001. The author's profile costs another $0.001, and no X account or developer app is involved.

You are in Claude Code, you paste three links from a launch thread and ask what people are saying and who these accounts are. The web fetch tool comes back with a login wall, a JavaScript shell or a refusal, because x.com shows almost nothing to visitors without a session. People work around it with shell scripts that route through third-party mirrors, and those break whenever the mirror does. A sturdier fix is a tool that takes the link and returns the post as data.

## The two calls

- [X post detail](/apis/x/posts/get/) takes `url` (x.com or twitter.com status links) or `id` and returns the text, media, views, likes, reposts, replies count, language, time and the author.
- [X account profile](/apis/x/users/get/) takes the handle and returns followers, following, post count, bio and verification, which is usually what "who is this" means.

With the [MCP server](/mcp/) connected, add one line to your project's CLAUDE.md so the agent stops trying the browser first:

```text
For x.com or twitter.com links, do not use WebFetch. Use the okdata call tool with endpoint x.posts.get and params {"url": "<link>"}; for the author, x.users.get with {"username": "<handle>"}.
```

Outside an MCP client, it is one HTTP call per link:

```python
import os
import requests

API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}

def read_post(link):
    body = requests.get(API + "/v1/x/posts/get", headers=H, params={"url": link}, timeout=60).json()
    if body["code"] != "ok":
        return {"link": link, "error": body["code"], "message": body["message"]}
    post = body["data"]["item"]
    return {"text": post["text"], "author": post["author"]["username"],
            "likes": post["metrics"]["likes"], "views": post["metrics"]["views"],
            "published_at": post["published_at"]}

print(read_post("https://x.com/user/status/1850000000000000000"))
```

## What it costs

| Task | Calls | Cost |
|---|---|---|
| One post | 1 | $0.001 |
| One post and its author | 2 | $0.002 |
| 3 posts and 3 authors | 6 | $0.006 |
| 1,000 links from a spreadsheet | 1,000 | $1.00 |

## Gotchas

- A thread is several posts and each link is one of them. Fetch each link, or search `from:handle` with [X post search](/apis/x/posts/search/) to get the author's recent posts in one page.
- You get the reply count, not the replies.
- Deleted posts and posts from protected accounts return `not_found` and are not charged.
- Views can be null on older posts; the response lists null fields and why in `meta.unavailable`.
- Public posts only.

## Other routes

The official X API is the right choice when you also need to post or reply, or when your company requires terms-backed access; it needs a developer account and is billed by X. Mirror-based scripts are free and fine for a personal setup, as long as you accept that they can stop working without notice. For one post, copying the text into the chat still works.

## Endpoints used

- [X post detail](https://okdata.online/apis/x/posts/get/) `x.posts.get`: $0.001 per call
- [X account profile](https://okdata.online/apis/x/users/get/) `x.users.get`: $0.001 per call

Updated 2026-11-12
