> For the complete documentation index, see [llms.txt](https://docs.pullbay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pullbay.com/api-reference/endpoints/twitter-x.md).

# Twitter / X

Twitter: tweets, users, handles, and search. All endpoints are read-only `GET` requests and return public Twitter/X data — no posting or account access is included.

**Base URL:** `https://dashboard.pullbay.com/api`

## Endpoints

| Endpoint                             | Description                              | Pagination        |
| ------------------------------------ | ---------------------------------------- | ----------------- |
| `GET /twitter/search`                | Search tweets by query                   | Cursor / maxItems |
| `GET /twitter/tweet/{id}`            | Get a single tweet by ID                 | —                 |
| `GET /twitter/handle/{handle}`       | Get a user by handle                     | —                 |
| `GET /twitter/handle/{handle}/about` | Get a user's about/bio details by handle | —                 |
| `GET /twitter/user/{id}`             | Get a user by numeric ID                 | —                 |
| `GET /twitter/user/{id}/tweets`      | Get tweets posted by a user              | Cursor / maxItems |

***

### Search Twitter

Search tweets matching a query.

**Request**

```bash
GET /twitter/search
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                    |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------ |
| `query`    | string  | Yes      | Search query, 1–100 characters                                                 |
| `sort`     | string  | No       | `Top` or `Latest` (default `Latest`)                                           |
| `useFirst` | string  | No       | `true` or `false` (default `false`)                                            |
| `cursor`   | string  | No       | Pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`            |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/search" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d query="openai" \
  -d sort=Latest \
  -d maxItems=20
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "tweet",
      "id": "20",
      "url": "https://x.com/jack/status/20",
      "twitterUrl": "https://twitter.com/jack/status/20",
      "text": "just setting up my twttr",
      "fullText": "just setting up my twttr",
      "source": "Twitter Web Client",
      "lang": "en",
      "createdAt": "Tue Mar 21 20:50:14 +0000 2006",
      "conversationId": "20",
      "retweetCount": 126541,
      "replyCount": 17858,
      "likeCount": 309719,
      "quoteCount": 6384,
      "bookmarkCount": 21386,
      "viewCount": null,
      "isReply": false,
      "isPinned": false,
      "isRetweet": false,
      "isQuote": false,
      "author": {
        "type": "user",
        "id": "44196397",
        "userName": "elonmusk",
        "name": "Elon Musk",
        "url": "https://x.com/elonmusk",
        "twitterUrl": "https://twitter.com/elonmusk",
        "description": "https://t.co/dDtDyVssfm",
        "location": "",
        "profilePicture": "https://pbs.twimg.com/profile_images/2035314704307081216/71U1ftM3_normal.jpg",
        "coverPicture": "https://pbs.twimg.com/profile_banners/44196397/1774145451",
        "isVerified": true,
        "isBlueVerified": true,
        "protected": false,
        "canDm": false,
        "canMediaTag": false,
        "followers": 239698341,
        "following": 1319,
        "fastFollowersCount": 0,
        "favouritesCount": 225074,
        "listedCount": 168631,
        "mediaCount": 4467,
        "statusesCount": 101980,
        "createdAt": "Tue Jun 02 20:12:29 +0000 2009",
        "status": ""
      },
      "media": []
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "DAACCgACGY...", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Using `maxItems` to pull more results in one call costs proportionally more than a single page.

***

### Get Tweet

Returns a single tweet by its numeric ID.

**Request**

```bash
GET /twitter/tweet/{id}
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                    |
| --------- | ------ | -------- | ---------------------------------------------- |
| `id`      | string | Yes      | Numeric tweet ID, 1–100 characters (e.g. `20`) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/tweet/20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "tweet",
      "id": "20",
      "url": "https://x.com/jack/status/20",
      "twitterUrl": "https://twitter.com/jack/status/20",
      "text": "just setting up my twttr",
      "fullText": "just setting up my twttr",
      "source": "Twitter Web Client",
      "lang": "en",
      "createdAt": "Tue Mar 21 20:50:14 +0000 2006",
      "conversationId": "20",
      "retweetCount": 126541,
      "replyCount": 17858,
      "likeCount": 309719,
      "quoteCount": 6384,
      "bookmarkCount": 21386,
      "viewCount": null,
      "isReply": false,
      "isPinned": false,
      "isRetweet": false,
      "isQuote": false,
      "author": {
        "type": "user",
        "id": "12",
        "userName": "jack",
        "name": "jack",
        "url": "https://x.com/jack",
        "twitterUrl": "https://twitter.com/jack",
        "description": "",
        "location": "",
        "profilePicture": "https://pbs.twimg.com/profile_images/1115644092329758721/AFjOzXz3_normal.jpg",
        "coverPicture": "",
        "isVerified": false,
        "isBlueVerified": false,
        "protected": false,
        "canDm": false,
        "canMediaTag": false,
        "followers": 6800000,
        "following": 4500,
        "fastFollowersCount": 0,
        "favouritesCount": 25000,
        "listedCount": 22000,
        "mediaCount": 350,
        "statusesCount": 30000,
        "createdAt": "Tue Mar 21 20:50:14 +0000 2006",
        "status": ""
      },
      "media": []
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get User By Handle

Returns a Twitter user by handle (without `@`).

**Request**

```bash
GET /twitter/handle/{handle}
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                                    |
| --------- | ------ | -------- | -------------------------------------------------------------- |
| `handle`  | string | Yes      | Twitter handle without `@`, 1–100 characters (e.g. `elonmusk`) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/handle/elonmusk" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "user",
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk",
      "url": "https://x.com/elonmusk",
      "twitterUrl": "https://twitter.com/elonmusk",
      "description": "https://t.co/dDtDyVssfm",
      "location": "",
      "profilePicture": "https://pbs.twimg.com/profile_images/2035314704307081216/71U1ftM3_normal.jpg",
      "coverPicture": "https://pbs.twimg.com/profile_banners/44196397/1774145451",
      "isVerified": true,
      "isBlueVerified": true,
      "protected": false,
      "canDm": false,
      "canMediaTag": false,
      "followers": 239698341,
      "following": 1319,
      "fastFollowersCount": 0,
      "favouritesCount": 225074,
      "listedCount": 168631,
      "mediaCount": 4467,
      "statusesCount": 101980,
      "createdAt": "Tue Jun 02 20:12:29 +0000 2009",
      "status": ""
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get User About By Handle

Returns extended profile / about details for a Twitter user, by handle.

**Request**

```bash
GET /twitter/handle/{handle}/about
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                                    |
| --------- | ------ | -------- | -------------------------------------------------------------- |
| `handle`  | string | Yes      | Twitter handle without `@`, 1–100 characters (e.g. `elonmusk`) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/handle/elonmusk/about" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "accountBasedIn": "United States",
      "locationAccurate": true,
      "profileImageShape": "Circle",
      "avatarUrl": "https://pbs.twimg.com/profile_images/2035314704307081216/71U1ftM3_normal.jpg",
      "usernameChangeCount": "0",
      "accountCreatedAt": "Tue Jun 02 20:12:29 +0000 2009",
      "accountSource": "United States App Store",
      "verifiedSince": "-156836000000000"
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get User By ID

Returns a Twitter user by their numeric user ID.

**Request**

```bash
GET /twitter/user/{id}
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter | Type   | Required | Description                                                 |
| --------- | ------ | -------- | ----------------------------------------------------------- |
| `id`      | string | Yes      | Numeric Twitter user ID, 1–100 characters (e.g. `44196397`) |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/user/44196397" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "user",
      "id": "44196397",
      "userName": "elonmusk",
      "name": "Elon Musk",
      "url": "https://x.com/elonmusk",
      "twitterUrl": "https://twitter.com/elonmusk",
      "description": "https://t.co/dDtDyVssfm",
      "location": "",
      "profilePicture": "https://pbs.twimg.com/profile_images/2035314704307081216/71U1ftM3_normal.jpg",
      "coverPicture": "https://pbs.twimg.com/profile_banners/44196397/1774145451",
      "isVerified": true,
      "isBlueVerified": true,
      "protected": false,
      "canDm": false,
      "canMediaTag": false,
      "followers": 239698341,
      "following": 1319,
      "fastFollowersCount": 0,
      "favouritesCount": 225074,
      "listedCount": 168631,
      "mediaCount": 4467,
      "statusesCount": 101980,
      "createdAt": "Tue Jun 02 20:12:29 +0000 2009",
      "status": ""
    }
  ],
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`.

***

### Get User's Tweets

Returns tweets posted by a user, by user ID.

**Request**

```bash
GET /twitter/user/{id}/tweets
Authorization: Bearer YOUR_API_KEY
```

**Parameters**

| Parameter  | Type    | Required | Description                                                                    |
| ---------- | ------- | -------- | ------------------------------------------------------------------------------ |
| `id`       | string  | Yes      | Numeric Twitter user ID, 1–100 characters (e.g. `44196397`)                    |
| `cursor`   | string  | No       | Pagination cursor from a previous response. Mutually exclusive with `maxItems` |
| `maxItems` | integer | No       | One-shot bulk pull, 1–200 results. Mutually exclusive with `cursor`            |

**Example**

```bash
curl -G "https://dashboard.pullbay.com/api/twitter/user/44196397/tweets" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d maxItems=20
```

**Response**

```json
{
  "status": 200,
  "message": "OK",
  "success": true,
  "data": [
    {
      "type": "tweet",
      "id": "20",
      "url": "https://x.com/jack/status/20",
      "twitterUrl": "https://twitter.com/jack/status/20",
      "text": "just setting up my twttr",
      "fullText": "just setting up my twttr",
      "source": "Twitter Web Client",
      "lang": "en",
      "createdAt": "Tue Mar 21 20:50:14 +0000 2006",
      "conversationId": "20",
      "retweetCount": 126541,
      "replyCount": 17858,
      "likeCount": 309719,
      "quoteCount": 6384,
      "bookmarkCount": 21386,
      "viewCount": null,
      "isReply": false,
      "isPinned": false,
      "isRetweet": false,
      "isQuote": false,
      "author": {
        "type": "user",
        "id": "44196397",
        "userName": "elonmusk",
        "name": "Elon Musk",
        "url": "https://x.com/elonmusk",
        "twitterUrl": "https://twitter.com/elonmusk",
        "description": "https://t.co/dDtDyVssfm",
        "location": "",
        "profilePicture": "https://pbs.twimg.com/profile_images/2035314704307081216/71U1ftM3_normal.jpg",
        "coverPicture": "https://pbs.twimg.com/profile_banners/44196397/1774145451",
        "isVerified": true,
        "isBlueVerified": true,
        "protected": false,
        "canDm": false,
        "canMediaTag": false,
        "followers": 239698341,
        "following": 1319,
        "fastFollowersCount": 0,
        "favouritesCount": 225074,
        "listedCount": 168631,
        "mediaCount": 4467,
        "statusesCount": 101980,
        "createdAt": "Tue Jun 02 20:12:29 +0000 2009",
        "status": ""
      },
      "media": []
    }
  ],
  "pagination": { "page": null, "hasNextPage": true, "cursor": "DAACCgACGY...", "offset": null },
  "pricing": { "creditsCharged": 1 }
}
```

**Credit cost:** dynamic, returned in `pricing.creditsCharged`. Cost scales with the number of tweets returned, not the number of requests.

***

## Object schemas

### User object

| Field                             | Type    | Description                                           |
| --------------------------------- | ------- | ----------------------------------------------------- |
| `type`                            | string  | Always `user`                                         |
| `id`                              | string  | Numeric Twitter user ID                               |
| `userName`                        | string  | Handle, without `@`                                   |
| `name`                            | string  | Display name                                          |
| `url` / `twitterUrl`              | string  | Profile URL on `x.com` and `twitter.com`              |
| `description`                     | string  | Bio text                                              |
| `location`                        | string  | Free-text profile location                            |
| `profilePicture` / `coverPicture` | string  | Avatar and banner image URLs                          |
| `isVerified` / `isBlueVerified`   | boolean | Legacy verification and Blue subscriber verification  |
| `protected`                       | boolean | Whether the account's tweets are protected            |
| `canDm` / `canMediaTag`           | boolean | Whether the user accepts DMs / can be tagged in media |
| `followers` / `following`         | integer | Follower and following counts                         |
| `fastFollowersCount`              | integer | Recently-gained follower count                        |
| `favouritesCount`                 | integer | Total likes given by the user                         |
| `listedCount`                     | integer | Number of lists the user appears on                   |
| `mediaCount`                      | integer | Number of tweets containing media                     |
| `statusesCount`                   | integer | Total tweet count                                     |
| `createdAt`                       | string  | Account creation timestamp (Twitter date format)      |
| `status`                          | string  | Reserved/internal status field                        |

### Tweet object

| Field                                                                        | Type                        | Description                                  |
| ---------------------------------------------------------------------------- | --------------------------- | -------------------------------------------- |
| `type`                                                                       | string                      | Always `tweet`                               |
| `id`                                                                         | string                      | Numeric tweet ID                             |
| `url` / `twitterUrl`                                                         | string                      | Tweet permalink on `x.com` and `twitter.com` |
| `text` / `fullText`                                                          | string                      | Tweet body (truncated and full)              |
| `source`                                                                     | string                      | Client used to post the tweet                |
| `lang`                                                                       | string                      | Tweet language code                          |
| `createdAt`                                                                  | string                      | Posted timestamp (Twitter date format)       |
| `conversationId`                                                             | string                      | ID of the root tweet in the thread           |
| `retweetCount` / `replyCount` / `likeCount` / `quoteCount` / `bookmarkCount` | integer                     | Engagement counts                            |
| `viewCount`                                                                  | integer, nullable           | View count, when available                   |
| `isReply` / `isPinned` / `isRetweet` / `isQuote`                             | boolean                     | Tweet type flags                             |
| `author`                                                                     | [User object](#user-object) | The tweet's author                           |
| `media`                                                                      | array                       | Attached media objects                       |

### User about object

| Field                 | Type    | Description                                      |
| --------------------- | ------- | ------------------------------------------------ |
| `accountBasedIn`      | string  | Inferred account region                          |
| `locationAccurate`    | boolean | Whether `accountBasedIn` is considered accurate  |
| `profileImageShape`   | string  | Profile picture mask shape (e.g. `Circle`)       |
| `avatarUrl`           | string  | Avatar image URL                                 |
| `usernameChangeCount` | string  | Number of times the handle has been changed      |
| `accountCreatedAt`    | string  | Account creation timestamp (Twitter date format) |
| `accountSource`       | string  | Platform/channel the account was created from    |
| `verifiedSince`       | string  | Verification timestamp, when applicable          |

***

## Errors

All non-2xx responses share the same envelope:

```json
{
  "status": 400,
  "message": "Bad request",
  "success": false,
  "error": { "code": "BAD_REQUEST" }
}
```

| Status | Meaning                                  |
| ------ | ---------------------------------------- |
| `400`  | Bad request — missing/invalid parameters |
| `402`  | Insufficient credits                     |
| `404`  | Tweet or user not found                  |

## Looking Up Users: Handle vs. ID

Twitter users can be resolved two ways, and the right one depends on what you already have:

* **By handle** (`/twitter/handle/{handle}`, `/twitter/handle/{handle}/about`) — use when you have the `@username` (without the `@`). This is the natural entry point when a human gives you a Twitter handle.
* **By numeric ID** (`/twitter/user/{id}`, `/twitter/user/{id}/tweets`) — use when you already have the user's numeric ID, typically because you pulled it from `author.id` on a tweet or from a prior handle lookup's `id` field. Numeric IDs are stable even if a user changes their handle, so prefer caching the ID for repeated lookups.

This mirrors the Instagram service's handle-vs-ID split: resolve once by handle to get the numeric ID, then use the ID for subsequent lookups (like fetching a user's tweets) to avoid re-resolving the handle each time.

Profile detail also comes in two levels:

* **Basic profile** (`/twitter/handle/{handle}`, `/twitter/user/{id}`) — followers, bio, verification status, and engagement counters. Use this for most lookups.
* **About / extended profile** (`/twitter/handle/{handle}/about`) — additional metadata not on the basic profile, such as inferred account region, profile image shape, username change count, and verification timestamp. Only available via handle, not by numeric ID. Call this in addition to the basic profile when you need these extra fields.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pullbay.com/api-reference/endpoints/twitter-x.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
