> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Twitter media scraper & profile export API guide

> Scrape tweets with photos, videos, and GIFs from a Twitter or X profile. Export media posts with authors, metrics, cursors, and timestamps. 1 credit per tweet.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-x-user-media-200">
      ```json theme={null}
      {
        "tweets": [],
        "has_next_page": false,
        "next_cursor": ""
      }
      ```
    </Tab>

    <Tab title="400" id="response-x-user-media-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-x-user-media-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required."
      }
      ```
    </Tab>

    <Tab title="402" id="response-x-user-media-402">
      ```json theme={null}
      {
        "error": "insufficient_credits",
        "message": "Insufficient credits. Top up or subscribe to continue."
      }
      ```
    </Tab>

    <Tab title="403" id="response-x-user-media-403">
      ```json theme={null}
      {
        "error": "x_account_protected",
        "message": "Account is protected. Choose a public account."
      }
      ```
    </Tab>

    <Tab title="404" id="response-x-user-media-404">
      ```json theme={null}
      {
        "error": "user_not_found",
        "message": "X user not found. Check the username."
      }
      ```
    </Tab>

    <Tab title="424" id="response-x-user-media-424">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="429" id="response-x-user-media-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>

    <Tab title="502" id="response-x-user-media-502">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "X data source temporarily unavailable. Try again later."
      }
      ```
    </Tab>

    <Tab title="503" id="response-x-user-media-503">
      ```json theme={null}
      {
        "error": "x_api_unavailable",
        "message": "Xquik is busy right now. Retry shortly."
      }
      ```
    </Tab>
  </Tabs>
</Panel>

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Note>
  Requested result counts are upper bounds for paid authenticated calls. When remaining credits cannot cover the full page or ID list, Xquik returns fewer results. If zero paid results are affordable, it returns `402 insufficient_credits`.
</Note>

<Callout icon="coins" color="#5c3327">
  **1 credit per result returned** · [All plans](https://xquik.com/#pricing) from \$0.00012/credit · Supports [guest paid reads](/guides/guest-wallets)
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://xquik.com/api/v1/x/users/44196397/media \
    -H "x-api-key: xq_your_api_key_here" | jq

  # Page 2
  curl -G https://xquik.com/api/v1/x/users/44196397/media \
    --data-urlencode "cursor=abc123" \
    -H "x-api-key: xq_your_api_key_here" | jq
  ```

  ```javascript Node.js theme={null}
  const userId = "44196397";
  let pageCursor = "";

  for (let pageIndex = 0; pageIndex < 3; pageIndex += 1) {
    const params = pageCursor === "" ? "" : `?${new URLSearchParams({ cursor: pageCursor })}`;
    const response = await fetch(`https://xquik.com/api/v1/x/users/${userId}/media${params}`, {
      headers: { "x-api-key": "xq_your_api_key_here" },
    });
    const page = await response.json();
    if (!response.ok) throw new Error(JSON.stringify(page));

    const mediaRows = page.tweets.map((tweet) => ({
      source_user_id: userId,
      media_tweet_id: tweet.id,
      text: tweet.text,
      tweet_url: tweet.url ?? null,
      created_at: tweet.createdAt ?? null,
      author_id: tweet.author?.id ?? null,
      author_username: tweet.author?.username ?? null,
      author_name: tweet.author?.name ?? null,
      author_followers: tweet.author?.followers ?? null,
      author_verified: tweet.author?.verified ?? null,
      author_profile_picture: tweet.author?.profilePicture ?? null,
      like_count: tweet.likeCount ?? null,
      reply_count: tweet.replyCount ?? null,
      retweet_count: tweet.retweetCount ?? null,
      quote_count: tweet.quoteCount ?? null,
      view_count: tweet.viewCount ?? null,
      media_urls: (tweet.media ?? []).map((item) => item.mediaUrl).filter(Boolean),
      media_types: (tweet.media ?? []).map((item) => item.type).filter(Boolean),
      page_index: pageIndex,
      page_cursor: pageCursor,
      next_cursor: page.next_cursor,
      has_next_page: page.has_next_page,
    }));
    for (const row of mediaRows) process.stdout.write(`${JSON.stringify(row)}\n`);

    if (!page.has_next_page || page.next_cursor === "") break;
    pageCursor = page.next_cursor;
  }
  ```

  ```python Python theme={null}
  import json
  import requests

  user_id = "44196397"
  page_cursor = ""

  for page_index in range(3):
      params = {"cursor": page_cursor} if page_cursor else {}
      response = requests.get(
          f"https://xquik.com/api/v1/x/users/{user_id}/media",
          params=params,
          headers={"x-api-key": "xq_your_api_key_here"},
      )
      page = response.json()
      if not response.ok:
          raise RuntimeError(page)

      for tweet in page["tweets"]:
          media_items = tweet.get("media", [])
          media_row = {
              "source_user_id": user_id,
              "media_tweet_id": tweet["id"],
              "text": tweet["text"],
              "tweet_url": tweet.get("url"),
              "created_at": tweet.get("createdAt"),
              "author_id": (tweet.get("author") or {}).get("id"),
              "author_username": (tweet.get("author") or {}).get("username"),
              "author_name": (tweet.get("author") or {}).get("name"),
              "author_followers": (tweet.get("author") or {}).get("followers"),
              "author_verified": (tweet.get("author") or {}).get("verified"),
              "author_profile_picture": (tweet.get("author") or {}).get("profilePicture"),
              "like_count": tweet.get("likeCount"),
              "reply_count": tweet.get("replyCount"),
              "retweet_count": tweet.get("retweetCount"),
              "quote_count": tweet.get("quoteCount"),
              "view_count": tweet.get("viewCount"),
              "media_urls": [
                  item["mediaUrl"] for item in media_items if item.get("mediaUrl")
              ],
              "media_types": [item["type"] for item in media_items if item.get("type")],
              "page_index": page_index,
              "page_cursor": page_cursor,
              "next_cursor": page["next_cursor"],
              "has_next_page": page["has_next_page"],
          }
          print(json.dumps(media_row, separators=(",", ":")))

      if not page["has_next_page"] or not page["next_cursor"]:
          break
      page_cursor = page["next_cursor"]
  ```
</CodeGroup>

## User media handoff

Use `GET /x/users/{id}/media` when a gallery, moderation queue, warehouse, or
agent needs recent media tweets from one account. The examples above write JSON
Lines rows with the source user, media tweet ID, text, tweet URL, author ID,
username, display name, follower count, verified state, profile image URL,
engagement counts, `media_urls`, `media_types`, and cursor fields. A worker
can then resume from the last saved `next_cursor`.

A protected account returns 403 `x_account_protected`. Xquik charges nothing.

## Which media endpoint?

* Use `GET /api/v1/x/users/{id}/media` when every row must be a media tweet
  from one profile. Store `media_urls`, `media_types`, `media_tweet_id`,
  `page_cursor`, `next_cursor`, and `has_next_page`.
* Use `GET /api/v1/x/users/{id}/tweets` when the sync also needs non-media
  posts or replies.
* Use `GET /api/v1/x/tweets/{id}` when you already know one tweet ID and need
  its media plus full tweet detail.
* Use `POST /api/v1/x/media` only to host or validate a local file or HTTPS
  media URL before a write. Pass `mediaUrl` to `POST /api/v1/x/tweets`, or pass
  `mediaId` as the only `media_ids` item for `POST /api/v1/x/dm/{userId}`.

## Build a profile media inventory

Use this route for tweets containing photos, videos, or animated GIFs from one
profile. Keep the source profile ID with every media item.

Use the inventory for asset review, campaign research, or approved archiving.
Respect the original publisher and applicable usage rights.

## Hand media into an asset workflow

Create one child row per media item. Include the parent tweet ID, media type,
source URL, author ID, and collection time.

Choose the best available video variant only after inspecting its metadata.
Keep the original variant list when later processing may need another format.

Do not download every asset during discovery. First filter and approve the
relevant tweets. Then call the download route with the selected tweet IDs.

Keep attribution and source links in any archive. The media URL alone does
not explain who published the asset or where it appeared.

Record download status separately from discovery status. A listed media URL
does not mean you downloaded the asset.

| Media inventory column | Response source | Asset rule |
| - | - | - |
| `source_x_user_id` | Resolved profile ID | Keep every media tweet tied to the intended profile. |
| `tweet_id` | `tweets[].id` | Use as the parent key for one or more media items. |
| `tweet_url` | `tweets[].url` | Keep the original X post for attribution and review. |
| `tweet_text` | `tweets[].text` | Keep the caption or post context beside each asset. |
| `author_id` | `tweets[].author.id` | Keep the original publisher as a stable identity. |
| `created_at` | `tweets[].createdAt` | Store the tweet publication time. |
| `media_index` | Position inside `tweets[].media` | Keep the order of several assets on one tweet. |
| `media_type` | `tweets[].media[].type` | Separate photo, video, and animated GIF processing. |
| `media_url` | `tweets[].media[].mediaUrl` | Deduplicate an asset only within its parent tweet. |
| `video_variants` | `tweets[].media[].videoVariants` | Keep every returned rendition until someone approves a download. |
| `page_cursor` | Request `cursor` | Resume the profile media inventory after stored pages. |
| `collected_at` | Integration timestamp | Audit when you observed the media URL and engagement counts. |

| Asset decision | Required evidence | Next action |
| - | - | - |
| Review only | Tweet URL, media URL, author, and text | Keep the remote asset linked to its source tweet. |
| Approved image download | Image media type and approved usage | Call the download route with the parent tweet ID. |
| Approved video download | Video variants and selected format | Choose a variant after inspecting bitrate and content type. |
| Rejected asset | Reviewer decision and reason | Keep the source record without downloading the file. |
| Failed selected download | Tweet ID, media URL, and failure state | Retry only the selected asset, not the entire profile inventory. |

## Path parameters

<ParamField path="id" type="string" required>
  User ID, username with or without `@`, or URL-encoded profile URL, such as
  `x.com/nasa`. See [path IDs](/api-reference/overview#path-ids).
</ParamField>

## Query parameters

<ParamField query="cursor" type="string">
  Pagination cursor. Pass the `next_cursor` value from the previous response to fetch the next page.
</ParamField>

<ParamField query="pageSize" type="integer">
  Tweets per page. Range: `1-100`. Defaults to `20`.
</ParamField>

### Tweet result filters

These optional filters apply to `tweets[]` returned by this route. They keep the
same media-tweets target. Xquik filters rows after it fetches each page. Selective
filters can return fewer rows than an unfiltered page.

<ParamField query="fromUser" type="string">
  Filter to posts from this username. The `@` prefix is optional.
</ParamField>

<ParamField query="toUser" type="string">
  Filter to replies directed to this username.
</ParamField>

<ParamField query="mentioning" type="string">
  Filter to posts that mention this username.
</ParamField>

<ParamField query="language" type="string">
  Only include posts with this language code.
</ParamField>

<ParamField query="sinceDate" type="string">
  Include posts created on or after this date or timestamp.
</ParamField>

<ParamField query="untilDate" type="string">
  Include posts up to this date or timestamp. A date is a UTC day, inclusive, so its own posts count.
</ParamField>

<ParamField query="mediaType" type="string">
  Use `images`, `videos`, `gifs`, `media`, `links`, or `none`.
</ParamField>

<ParamField query="minLikes" type="integer">
  Require this minimum like count.
</ParamField>

<ParamField query="minRetweets" type="integer">
  Require this minimum repost count.
</ParamField>

<ParamField query="minReplies" type="integer">
  Require this minimum reply count.
</ParamField>

<ParamField query="minQuotes" type="integer">
  Require this minimum quote count.
</ParamField>

<ParamField query="minViews" type="integer">
  Require this minimum view count.
</ParamField>

<ParamField query="minBookmarks" type="integer">
  Require this minimum bookmark count.
</ParamField>

<ParamField query="maxFaves" type="integer">
  Allow this maximum like count. Missing counts pass.
</ParamField>

<ParamField query="maxRetweets" type="integer">
  Allow this maximum repost count. Missing counts pass.
</ParamField>

<ParamField query="maxReplies" type="integer">
  Allow this maximum reply count. Missing counts pass.
</ParamField>

<ParamField query="maxQuotes" type="integer">
  Allow this maximum quote count. Missing counts pass.
</ParamField>

<ParamField query="blueVerifiedOnly" type="boolean">
  When `true`, only return posts from Blue-verified authors.
</ParamField>

<ParamField query="verifiedOnly" type="boolean">
  When `true`, only return posts from verified authors.
</ParamField>

<ParamField query="replies" type="string">
  Use `include`, `exclude`, or `only` for replies.
  This setting overrides `includeReplies` when the endpoint supports both.
</ParamField>

<ParamField query="retweets" type="string">
  Use `include`, `exclude`, or `only` for reposts.
</ParamField>

<ParamField query="exactPhrase" type="string">
  Match this literal phrase, including any hyphens.
</ParamField>

<ParamField query="excludeWords" type="string">
  Exclude comma-separated or whitespace-separated terms.
</ParamField>

<ParamField query="anyWords" type="string">
  Require at least 1 comma-separated or whitespace-separated term.
</ParamField>

<ParamField query="hashtags" type="string">
  Match these hashtags. Separate values with commas or spaces.
</ParamField>

<ParamField query="cashtags" type="string">
  Match these cashtags. Separate values with commas or spaces.
</ParamField>

<ParamField query="quotes" type="string">
  Use `include`, `exclude`, or `only` for quote posts.
</ParamField>

<ParamField query="url" type="string">
  URL substring or domain that must appear in tweet URL entities.
</ParamField>

<ParamField query="conversationId" type="string">
  Filter to tweets in this conversation thread.
</ParamField>

<ParamField query="inReplyToTweetId" type="string">
  Only include replies to this tweet ID.
</ParamField>

<ParamField query="quotesOfTweetId" type="string">
  Filter to quote tweets of this tweet ID.
</ParamField>

<ParamField query="retweetsOfTweetId" type="string">
  Filter to retweets of this tweet ID.
</ParamField>

<ParamField query="sinceId" type="string">
  Return Tweets whose IDs exceed this ID.
</ParamField>

<ParamField query="maxId" type="string">
  Return Tweets at or below this ID.
</ParamField>

<ParamField query="nativeRetweets" type="boolean">
  When `true`, only return native reposts.
</ParamField>

<ParamField query="withinTime" type="string">
  Match Tweets from this recent window, such as `90m` or `7d`. Use a whole number & `s`, `m`, `h` or `d`.
</ParamField>

## Headers

<ParamField header="x-api-key" type="string">
  Full account key. Sessions and OAuth also work.
</ParamField>

<ParamField header="Authorization" type="string">
  `Bearer xq_your_guest_key_here` for `paid_reads`.
</ParamField>

## Response

### 200 OK

<ResponseField name="tweets" type="object[]">
  Array of tweets containing media.
  **Tweet object fields.**

  <ResponseField name="id" type="string">Tweet ID.</ResponseField>
  <ResponseField name="text" type="string">Tweet text content.</ResponseField>
  <ResponseField name="type" type="string">Tweet type. Omitted if unavailable.</ResponseField>
  <ResponseField name="createdAt" type="string">ISO 8601 creation timestamp. Omitted if unavailable.</ResponseField>
  <ResponseField name="isNoteTweet" type="boolean">Whether this is a Note Tweet (long-form post). Omitted if unavailable.</ResponseField>
  <ResponseField name="isPinned" type="boolean">Whether the author pinned this post to their profile. Omitted if unavailable.</ResponseField>
  <ResponseField name="likeCount" type="number">Like count. Omitted if unavailable.</ResponseField>
  <ResponseField name="retweetCount" type="number">Retweet count. Omitted if unavailable.</ResponseField>
  <ResponseField name="replyCount" type="number">Reply count. Omitted if unavailable.</ResponseField>
  <ResponseField name="quoteCount" type="number">Quote tweet count. Omitted if unavailable.</ResponseField>
  <ResponseField name="viewCount" type="number">View count. Omitted if unavailable.</ResponseField>
  <ResponseField name="bookmarkCount" type="number">Bookmark count. Omitted if unavailable.</ResponseField>
  <ResponseField name="url" type="string">Permalink URL on X. Omitted if unavailable.</ResponseField>
  <ResponseField name="lang" type="string">Tweet language code. Omitted if unavailable.</ResponseField>
  <ResponseField name="isReply" type="boolean">Whether the tweet is a reply. Omitted if unavailable.</ResponseField>
  <ResponseField name="inReplyToId" type="string">Tweet ID being replied to. Omitted if not a reply.</ResponseField>
  <ResponseField name="inReplyToUserId" type="string">User ID being replied to. Omitted if not a reply.</ResponseField>
  <ResponseField name="inReplyToUsername" type="string">Username being replied to. Omitted if not a reply.</ResponseField>
  <ResponseField name="conversationId" type="string">Conversation thread ID. Omitted if unavailable.</ResponseField>
  <ResponseField name="source" type="string">Client used to post the tweet. Omitted if unavailable.</ResponseField>
  <ResponseField name="displayTextRange" type="number[]">Start and end offsets for rendered tweet text. Omitted if unavailable.</ResponseField>
  <ResponseField name="isLimitedReply" type="boolean">Whether replies are limited. Omitted if unavailable.</ResponseField>
  <ResponseField name="isQuoteStatus" type="boolean">Whether this tweet quotes another tweet. Omitted if unavailable.</ResponseField>
  <ResponseField name="isRetweet" type="boolean">Whether this row is a retweet. `text` carries the original post in full.</ResponseField>
  <ResponseField name="entities" type="object">Parsed entities. Omitted if unavailable.</ResponseField>
  <ResponseField name="contentDisclosure" type="object">Disclosure metadata for paid partnership and AI-generated media labels. Includes `advertising.isPaidPromotion` and `aiGenerated.hasAiGeneratedMedia` when X returns them. Omitted if unavailable.</ResponseField>

  <ResponseField name="author" type="object">
    Tweet author profile. Omitted if unavailable.
    **Author object fields.**
    <ResponseField name="id" type="string">Author user ID.</ResponseField>
    <ResponseField name="username" type="string">Author handle without `@`.</ResponseField>
    <ResponseField name="name" type="string">Author display name.</ResponseField>
    <ResponseField name="followers" type="number">Follower count. Omitted if unavailable.</ResponseField>
    <ResponseField name="verified" type="boolean">Whether the author is verified. Omitted if unavailable.</ResponseField>
    <ResponseField name="profilePicture" type="string">Author profile image URL. Omitted if unavailable.</ResponseField>
  </ResponseField>

  <ResponseField name="media" type="object[]">
    Media attachments. Omitted if unavailable.
    **Media item fields.**
    <ResponseField name="mediaUrl" type="string">Direct media URL.</ResponseField>
    <ResponseField name="videoVariants" type="object[]">Available video renditions with bitrate, content type, and URL. Omitted for images.</ResponseField>
    <ResponseField name="type" type="string">Media type.</ResponseField>
    <ResponseField name="url" type="string">Shortened URL from the tweet text.</ResponseField>
  </ResponseField>

  <ResponseField name="quoted_tweet" type="object">Embedded quoted tweet. Omitted if not a quote tweet.</ResponseField>
  <ResponseField name="retweeted_tweet" type="object">Original retweeted tweet. Omitted if not a retweet.</ResponseField>
</ResponseField>

<ResponseField name="has_next_page" type="boolean">
  Whether more results are available.
</ResponseField>

<ResponseField name="next_cursor" type="string">
  Opaque cursor for the next page. Empty string when no more results.
</ResponseField>

```json theme={null}
{
  "tweets": [
    {
      "id": "1893456789012345678",
      "text": "Check out this photo",
      "createdAt": "2026-02-24T10:00:00.000Z",
      "likeCount": 200,
      "viewCount": 15000,
      "url": "https://x.com/user/status/1893456789012345678",
      "author": {
        "id": "44196397",
        "username": "username",
        "name": "Xquik",
        "followers": 1200,
        "verified": true,
        "profilePicture": "https://pbs.twimg.com/profile_images/example.jpg"
      },
      "media": [{ "type": "photo", "mediaUrl": "https://pbs.twimg.com/media/example.jpg" }]
    }
  ],
  "has_next_page": true,
  "next_cursor": "DAADDAABCgABF..."
}
```

### 400 Invalid user ID

```json theme={null}
{
  "error": "invalid_user_id",
  "message": "Send a user ID, @username or profile URL, such as x.com/nasa."
}
```

The user ID is empty or invalid.

### 404 User not found

```json theme={null}
{ "error": "user_not_found", "message": "X user not found. Check the username." }
```

### 401 Unauthenticated

Anonymous requests get `WWW-Authenticate: Bearer` and a guest wallet checkout action. This is not a Payment challenge.

```json theme={null}
{ "error": "unauthenticated" }
```

Missing or invalid API key.

### 402 Payment required

Account keys get account options. Guest keys get guest top-up only.
No checkout starts automatically. Confirm any payment action.

### 502 X API unavailable

```json theme={null}
{ "error": "x_api_unavailable" }
```

The read service returned an error. Retry after a short delay.

### 429 Rate limit exceeded

```json theme={null}
{ "error": "rate_limit_exceeded", "retryAfter": 60 }
```

You exceeded your tier rate limit. Wait for the `Retry-After` header before retrying.

### 424 Dependency failed

```json theme={null}
{ "error": "x_api_unavailable" }
```

The normalized v1 response contract can return 424 when the read service is unavailable.

<Note>
  **Related.** [Get user timeline](/api-reference/x/user-tweets) · [User highlights](/api-reference/x/user-highlights) · [User likes](/api-reference/x/user-likes) · [User mentions timeline](/api-reference/x/user-mentions)
</Note>

<div className="related-api-links">
  <Accordion title="Related tweet, reply & media APIs" icon="link">
    * Tweets: [Get tweet](/api-reference/x/get-tweet) · [Batch tweets](/api-reference/x/batch-tweets) · [Tweet thread](/api-reference/x/tweet-thread) · [Hidden replies](/api-reference/x/tweet-hidden-replies) · [Translate tweet](/api-reference/x/tweet-translation) · [Embed tweet](/api-reference/x/tweet-embed) · [Resolve links](/api-reference/x/resolve-links) · [Tweet subtitles](/api-reference/x/tweet-subtitles) · [X Article](/api-reference/x/get-article)
    * Analysis: [Sentiment analysis](/api-reference/x/sentiment-analysis) · [Brand mentions](/api-reference/x/brand-monitoring) · [News classification](/api-reference/x/news-classification) · [Market signals](/api-reference/x/market-signals) · [Viral score](/api-reference/x/viral-score) · [Classify posts](/api-reference/x/classify-tweets)
    * Engagement: [Tweet replies](/api-reference/x/tweet-replies) · [Quote tweets](/api-reference/x/tweet-quotes) · [Likers](/api-reference/x/favoriters) · [Reposters](/api-reference/x/retweeters) · [Check repost](/api-reference/x/tweet-repost-check)
    * Profiles: [User tweets](/api-reference/x/user-tweets) · [Batch user tweets](/api-reference/x/batch-user-tweets) · [User replies](/api-reference/x/user-replies) · [User likes](/api-reference/x/user-likes) · [User media](/api-reference/x/user-media) · [User highlights](/api-reference/x/user-highlights) · [User articles](/api-reference/x/user-articles)
    * Feeds: [List tweets](/api-reference/x/list-tweets) · [Trends](/api-reference/x/trends) · [Trend locations](/api-reference/x/trend-locations) · [Search Spaces](/api-reference/x/search-spaces) · [Get Space](/api-reference/x/get-space) · [Space replay](/api-reference/x/space-replay) · [Get broadcast](/api-reference/x/get-broadcast) · [Hashflags](/api-reference/x/hashflags) · [Search places](/api-reference/x/search-places) · [Download media](/api-reference/x/download-media)
  </Accordion>
</div>

<div className="related-api-links">
  <Accordion title="Related timeline, bookmark & notification APIs" icon="link">
    * Account feeds: [Home timeline](/api-reference/x/timeline) · [Notifications](/api-reference/x/notifications) · [Mentions](/api-reference/x/user-mentions)
    * Saved and private: [Bookmarks](/api-reference/x/bookmarks) · [Bookmark folders](/api-reference/x/bookmark-folders) · [DM history](/api-reference/x/dm-history)
  </Accordion>
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.