> ## 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.

# Tweet metadata, profile & media API field guide

> Map Twitter API fields for tweets, profiles, media, replies, engagement metrics, IDs, cursors, exports, REST, SDK, MCP, and Actor responses with JSON examples.

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

Use this guide to get tweet metadata from Xquik responses.
It maps Twitter API fields for tweets, user profiles, media files, and replies.
In short, treat IDs as strings.
Keep reply, quote, and repost relationships separate.

This Twitter metadata guide focuses on public fields X supplies.
Xquik keeps every documented public field supplied for supported reads.
Core fields remain stable. Optional fields appear only when X supplies them.

The [API reference](/api-reference/overview) defines exact REST and SDK types.
Each API response must follow those documented types.
The Twitter API response fields below match that public contract.
The MCP contract normalizes names for agent use.
Most fields use `snake_case`. REST `createdAt` becomes MCP `created`.
It does not become `created_at`.

## Choose the object before mapping fields

| Need | Primary object | Stable join key |
| - | - | - |
| Tweet text and engagement | Tweet | `id` |
| Reply or thread relationship | Tweet | `conversationId` and `inReplyToId` |
| Quote context | `quoted_tweet` | Nested tweet `id` |
| Repost context | `retweeted_tweet` | Nested tweet `id` |
| Author profile | `author` | Author `id` |
| Image, video, or GIF | `media[]` | `mediaKey` or media `id` |
| Pagination | Page envelope | Returned cursor |

Do not flatten every object into one unversioned row. Nested tweets and authors
have their own IDs. Store those IDs before building joins.

## Field presence rules

<CardGroup cols={2}>
  <Card title="Required fields" icon="badge-check">
    Tweet objects require `id`, `text`, and documented engagement counts.
    Profile objects require `id`, `username`, and `name`.
  </Card>

  <Card title="Optional fields" icon="circle-dashed">
    The API omits optional fields when X does not supply them. Absence is not an
    empty string, false value, or 0 count.
  </Card>

  <Card title="String IDs" icon="fingerprint">
    Keep tweet, user, media, conversation, and reply IDs as strings. Large IDs
    can lose precision in spreadsheet or JavaScript number types.
  </Card>

  <Card title="Count snapshots" icon="chart-no-axes-column">
    Likes, replies, reposts, quotes, views, bookmarks, followers, and following
    counts can change after collection. Store `collected_at` downstream.
  </Card>
</CardGroup>

<Warning>
  A 0 tweet metric can mean X did not report that count. Do not treat every
  0 as a measured absence.
</Warning>

## Tweet fields

Every tweet includes its ID, text, metrics, and available author profile.
These optional fields hold additional X metadata.

Core tweet fields group into these roles:

* Identity and publishing: `id`, `type`, `url`, `createdAt`, `lang`, and `source`
* Text: `text`, `displayTextRange`, `textHighlights`, `entities`, and `contentDisclosure`
* Replies: `isReply`, `isLimitedReply`, `conversationId`, `conversationControl`, `limitedActions`, `unmentionedUserIds`, `inReplyToId`, `inReplyToUserId`, and `inReplyToUsername`
* Quote and repost context: `isQuoteStatus`, `quoted_tweet`, `quotedTweetId`, `retweeted_tweet`, and `isNoteTweet`
* Retweets: `isRetweet` is `true`, `text` carries the original post in full, and `retweeted_tweet` holds the original
* Pinning: `isPinned` marks the post the author pinned to their profile
* Related data: `author`, `media`, `reactionContext`, `retweetCount`, `replyCount`, `likeCount`, `quoteCount`, `viewCount`, and `bookmarkCount`

| Field | Description |
| - | - |
| `article` | X Article metadata |
| `card` | Link card metadata |
| `communityId` | Community ID |
| `communityNote` | Community Note text, links, icons, and style |
| `coordinates` | Author-published point, with longitude before latitude |
| `edit` | Edit history and remaining state |
| `authorUnavailable` | Why the author is missing: X reason code and notice text |
| `exclusiveContent` | Subscriber-only post creator and subscribe link |
| `grokShareAttachment` | Public Grok share content and links |
| `grokTranslatedPost` | Grok's translation of the post, as X shows it |
| `hasCommunityNotes` | Whether X holds Community Notes on the post, shown or not |
| `geo` | Author-published point, with latitude before longitude |
| `isTranslatable` | Translation availability |
| `jetfuelAttachment` | Interactive attachment metadata |
| `noteTweet` | Long-form content and inline media |
| `place` | Tagged place metadata |
| `postCta` | Public post action metadata |
| `possiblySensitive` | X sensitivity state |
| `previousCounts` | Pre-edit engagement counts |
| `quotedTweetPermalink` | The quoted post's link, kept when X withholds that post |
| `reactionContext` | Referenced public post and user |
| `sportsContext` | Game, team, score, and schedule details attached to a post |
| `scopes` | Sanitized public scope metadata |
| `tombstone` | Unavailable tweet metadata |
| `unavailableAuthorId` | The author's ID when X withholds the author's profile |
| `viewState` | X view-state metadata |

Tweets also include available entities, disclosures, nested tweets, and media.

### Tweet metadata example

```json theme={null}
{
  "id": "1893704267862470862",
  "text": "A public tweet with a reply and media.",
  "createdAt": "2026-05-24T20:32:58.000Z",
  "url": "https://x.com/example/status/1893704267862470862",
  "lang": "en",
  "isReply": true,
  "isNoteTweet": false,
  "isQuoteStatus": false,
  "isRetweet": false,
  "conversationId": "1893600000000000000",
  "inReplyToId": "1893690000000000000",
  "inReplyToUserId": "987654321",
  "inReplyToUsername": "parent_author",
  "retweetCount": 8,
  "replyCount": 3,
  "likeCount": 42,
  "quoteCount": 2,
  "viewCount": 1500,
  "bookmarkCount": 4,
  "author": {
    "id": "123456789",
    "username": "example",
    "name": "Example Account"
  },
  "media": [
    {
      "mediaUrl": "https://pbs.twimg.com/media/example.jpg",
      "type": "photo",
      "url": "https://x.com/example/status/1893704267862470862/photo/1",
      "altText": "Product dashboard with a tweet search result"
    }
  ]
}
```

The example illustrates field placement. Read the endpoint response for actual
values. Never copy example IDs into a production join.

### Map replies, quotes, and reposts

Join replies to `inReplyToId`. Keep `conversationId` for the root conversation.
Join quotes and reposts to each nested tweet ID.
Keep original tweets separate from outer repost records.

`reactionContext` identifies the public post and user tied to a reaction.
Xquik removes viewer-specific state from its nested user.

<CardGroup cols={2}>
  <Card title="Direct reply" icon="reply">
    Join `inReplyToId` to the parent tweet. Keep `conversationId` for the full
    thread.
  </Card>

  <Card title="Quote" icon="quote">
    Join `quoted_tweet.id` to the quoted tweet. Attribute quote text to the
    outer tweet.
  </Card>

  <Card title="Repost" icon="repeat-2">
    Join `retweeted_tweet.id` to the original tweet. Do not merge their metric
    snapshots.
  </Card>

  <Card title="Note tweet" icon="notebook-tabs">
    Keep `noteTweet.inlineMedia` positions with long-form text and formatting.
  </Card>
</CardGroup>

### Repost timestamps

Tweet repost records include `retweetedAt` as a UTC ISO 8601 timestamp.
It is `null` when unavailable and omitted for original posts.
`retweeted_tweet.createdAt` remains the original post's creation date.

[Get retweeters](/api-reference/x/retweeters#retweet-timestamps) supports `includeRetweetTimestamp=true`.
It checks each account's newest available profile page for the matching repost.
Profile rows remain present when timestamps are unavailable, with `retweetedAt: null`.
This optional lookup adds latency and does not search complete account histories.
Profile `createdAt` remains the account creation date.

### Interpret tweet engagement fields

`likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `viewCount`, and
`bookmarkCount` are count snapshots. They can change after collection.

Store `tweet_id`, every count, and `collected_at` in one snapshot row. Compare
snapshots with the same tweet ID. Do not overwrite history when measuring
growth.

`previousCounts` can hold pre-edit engagement counts. `edit` can describe
edit history. Keep both objects when analyzing edited tweets.

### Map entities and content labels

Read `entities` for URLs, mentions, hashtags, and other parsed text markers.
Read `displayTextRange` before slicing rendered text. Keep the original
tweet text beside any normalized tokens.

Read `textHighlights` on a search row for the ranges of `text` that match the
search. Each range counts code points of `text`. The list is empty when X marks
nothing.

Read `contentDisclosure` for documented content labels. Read
`possiblySensitive` for the returned sensitivity state. Never infer either
field when it is absent.

## Profile fields

Every profile includes `id`, `username`, and `name`.
Counts, verification, images, bios, and other metadata appear when X supplies them.

Core profile fields group into these roles:

* Identity: `id`, `username`, `name`, and `createdAt`
* Bio: `description`, `profile_bio`, `grokTranslatedBio`, `location`, and `url`
* Audience: `followers` and `following`
* Activity: `statusesCount`, `mediaCount`, and `favouritesCount`
* Verification: `verified`, `isVerified`, `isBlueVerified`, and `verifiedType`
* Images: `profilePicture`, `coverPicture`, and `profileBannerUrl`
* Access: `protected`, `unavailable`, and `unavailableReason`
* Safety: `possiblySensitive`, `withheldInCountries`, and `withheldScope`
* Automation: `isAutomated` and `automatedBy`
* Features: `hasCustomTimelines`, `isTranslator`, and `communityRole`
* Pinned content: `pinnedTweetIds`

Treat `author` as the user object for each returned tweet.
Store the user profile using its stable `id`.
A profile page can change its username, name, bio, and images.
Keep pinned tweet IDs as strings.

| Field | Description |
| - | - |
| `accountBasedIn` | Observed account location metadata |
| `accountBasedInUnavailable` | X withheld the account location |
| `accountBasedInAccurate` | False when X notes the location may be inaccurate |
| `connectedVia` | How the account first connected to X |
| `connectedViaAccurate` | False when X notes that country may be inaccurate |
| `usernameChanges` | Username change count and latest change time |
| `birthdate` | Public parts of the birthday |
| `listedCount` | Public lists that include the profile |
| `fastFollowersCount` | Followers X counts as fast followers |
| `normalFollowersCount` | Followers minus fast followers |
| `subscribersCount` | Accounts subscribed to its paid Subscriptions |
| `defaultProfile` | Whether the profile keeps X's default theme |
| `defaultProfileImage` | Whether the profile keeps X's default avatar |
| `geoEnabled` | Whether the profile may add a location to posts |
| `hasExtendedProfile` | Whether it filled X's extended fields |
| `isTranslationEnabled` | Whether it turned on X's translation of its posts |
| `advertiserAccountType` | X Ads type: `none` or `promotable_user` |
| `advertiserAccountServiceLevels` | X Ads services it uses, such as `analytics` |
| `businessProfileState` | Business profile state: `none` or `enabled` |
| `verificationReason` | X's text on why the profile is verified, with links |
| `affiliatesHighlightedLabel` | Affiliate label metadata |
| `businessAccountAffiliatesCount` | Business affiliate count |
| `creatorSubscriptionsCount` | Creator subscription count |
| `professional` | Professional profile metadata |
| `hasGraduatedAccess` | Graduated access state |
| `hasHiddenSubscriptionsOnProfile` | Hidden subscription state |
| `highlightsInfo` | Profile highlights metadata |
| `identityVerification` | Identity verification metadata |
| `isProfileTranslatable` | Profile translation availability |
| `parodyCommentaryFanLabel` | Parody or fan label |
| `profileDescriptionLanguage` | Detected bio language |
| `profileImageShape` | Profile image shape |
| `profileInterstitialType` | Profile interstitial type |
| `profileSortEnabled` | Profile sorting state |
| `profileTranslatorType` | Profile translator type |
| `superFollowEligible` | Subscription eligibility |
| `superFollowsUserProfileActive` | Active subscription profile state |
| `tipJar` | Public creator support handles |

Xquik removes account-specific actions, permissions, and relationships from
public reads. Use dedicated write routes or X for account state.

### Twitter profile API example

```json theme={null}
{
  "id": "9876543210",
  "username": "example_user",
  "name": "Example User",
  "description": "Developer building tweet monitoring tools.",
  "followers": 12500,
  "following": 420,
  "statusesCount": 8600,
  "mediaCount": 730,
  "verified": true,
  "isBlueVerified": false,
  "isVerified": true,
  "verifiedType": "Business",
  "profilePicture": "https://pbs.twimg.com/profile_images/example.jpg",
  "coverPicture": "https://pbs.twimg.com/profile_banners/example.jpg",
  "location": "London",
  "createdAt": "2018-04-12T10:30:00.000Z",
  "protected": false,
  "pinnedTweetIds": ["1893704267862470862"]
}
```

Use `id` as the profile join key. Usernames can change. Display names are not
unique. Keep the observed username and collection time beside each snapshot.

### Interpret profile counts

Use `followers` for the returned follower count. Use `following` for accounts
the profile follows. Use `statusesCount` for the returned post count. Use
`mediaCount` for posts containing media.

Do not calculate follower growth from one response. Store dated profile
snapshots. Compare the same X user ID across collection times.

### Keep verification fields separate

Keep `verified`, `isVerified`, `isBlueVerified`, and `verifiedType` as
distinct fields. X can return different verification signals. Do not collapse
them into one custom boolean.

`identityVerification` and `affiliatesHighlightedLabel` provide separate
profile metadata. Keep those objects when present.

### Handle protected or unavailable profiles

Use `protected` for the returned privacy state. Use `unavailable` and
`unavailableReason` for unavailable profiles. Do not replace omitted profile
fields with invented values.

Keep `withheldInCountries` and `possiblySensitive` when returned. These fields
describe public response state. They do not grant access to hidden content.

### Handle a withheld account location

`accountBasedIn` holds the country or region X shows for the account.
It is `null` when X shows no label. X sometimes withholds the label from a read.
The profile then has `accountBasedInUnavailable: true` & no `accountBasedIn`.
Treat that as unknown, not as no label. Retry later to get it.

## Media fields

Media rows keep their URL and type. These optional fields add detail.
The Twitter media API field section covers returned photos, videos, and GIFs.
Store media files only when returned URLs and availability allow it.

Every media object includes `mediaUrl`, `type`, and `url`.

| Field | Description |
| - | - |
| `adultContent` | Adult content state |
| `allowDownload` | Download permission |
| `altText` | Accessibility text |
| `aspectRatio` | Video aspect ratio |
| `availabilityStatus` | Media availability state |
| `availabilityReason` | Media availability reason |
| `description` | Media description |
| `displayUrl` | Display URL |
| `durationMillis` | Video duration |
| `embeddable` | Embedding availability |
| `expandedUrl` | Expanded media URL |
| `faceRects` | Detected face rectangles |
| `focusRects` | Crop focus rectangles |
| `grokPostId` | Related Grok post ID |
| `graphicViolence` | Graphic violence state |
| `height` | Media height |
| `id` | Media ID |
| `indices` | Source-text indices |
| `mediaKey` | X media key |
| `monetizable` | Monetization state |
| `otherSensitiveContent` | Other sensitive content state |
| `sizes` | Available image sizes |
| `sourceStatusId` | Source tweet ID |
| `sourceUserId` | Source user ID |
| `sourceUser` | Public profile that first posted copied media |
| `tags` | Tagged users |
| `title` | Media title |
| `videoVariants` | Video encodings and bitrates |
| `visitSiteUrl` | Public destination URL |
| `watchNowUrl` | Public media action URL |
| `width` | Media width |

### Map photos, videos, and GIFs

Read `type` before selecting a media workflow. Supported values are `photo`,
`video`, and `animated_gif`. Keep the original type with every media row.

Use `mediaUrl` as the returned preview URL. Use `url` as the X media link.
Use `expandedUrl` and `displayUrl` only when present.

Keep `altText` for accessibility. Keep `width`, `height`, and
`aspectRatio` for layout. Keep `durationMillis` for video duration.

`videoVariants` can contain multiple encodings and bitrates. Keep the complete
array when another service selects playback quality. Do not invent a missing
variant.

Use `allowDownload` and `availabilityStatus` when returned. Check both before a
media handoff. A media object does not guarantee permanent file availability.

### Store a media join row

```json theme={null}
{
  "tweet_id": "1893704267862470862",
  "media_id": "1912345678901234567",
  "media_key": "3_1912345678901234567",
  "media_type": "video",
  "media_url": "https://pbs.twimg.com/ext_tw_video_thumb/example.jpg",
  "x_media_url": "https://x.com/example/status/1893704267862470862/video/1",
  "duration_millis": 18400,
  "alt_text": "Short product demonstration",
  "collected_at": "2026-05-24T20:33:00.000Z"
}
```

Create one row per media object. Join it back through `tweet_id`. Keep all
variants in a child table or structured column.

## Reply coverage

Reply coverage depends on X. X can hide, rank, or omit counted replies.

Omit `mode` for automatic maximum direct-reply coverage with pagination. Pass
each `next_cursor` back unchanged as `cursor`. This keeps the standard response
shape and billing.

Use `GET /api/v1/x/tweets/<tweet_id>/replies?mode=complete&limit=25000`.
Complete mode adds nested replies and detailed diagnostics.

Direct replies match `inReplyToId` to the requested tweet. Keep
`nested_replies` separate. Trust `diagnostic.complete` instead of row count.
Complete mode requires 80% of X's current reported direct replies, or a
`sinceTime` or `untilTime` window read to its end. HTTP 424
`replies_incomplete` returns the collected rows and coverage diagnostic.
Inspect `coveragePercentage`, strategy results, cursor failures, and fallback.
Disclose that reply coverage depends on X.

### Store reply relationships

Keep these fields for each collected reply:

* `id` for the reply tweet
* `inReplyToId` for the direct parent
* `conversationId` for the thread root
* `author.id` for the reply author
* `createdAt` for ordering
* `nested_replies` for separately returned descendants

Do not infer a direct parent from array position. Use `inReplyToId`. Keep
`nested_replies` separate from direct replies when measuring first-level
coverage.

## Twitter API pagination fields

Tweet, profile, follower, reply, list, and timeline routes can return page
envelopes. Keep each endpoint's documented field names.

REST read pages commonly return `has_next_page` and `next_cursor`. Pass the
returned cursor back as `cursor`. Stop when `has_next_page` is false.

Extraction result pages return `hasMore` and `nextCursor`. Pass `nextCursor`
back as `cursor`. Do not mix REST cursors with extraction cursors.

Commit rows and their next cursor together. A retry must upsert by tweet ID,
user ID, or media ID before advancing.

## Field mapping handoff

```json theme={null}
{
  "schema": "xquik.tweet_profile_fields.v1",
  "source_route": "GET /api/v1/x/tweets/1893704267862470862",
  "tweet_key": "id",
  "profile_key": "author.id",
  "media_key": "media[].mediaKey",
  "reply_parent_key": "inReplyToId",
  "conversation_key": "conversationId",
  "quote_key": "quoted_tweet.id",
  "repost_key": "retweeted_tweet.id",
  "count_fields": [
    "likeCount",
    "replyCount",
    "retweetCount",
    "quoteCount",
    "viewCount",
    "bookmarkCount"
  ],
  "ids_as_strings": true,
  "optional_field_policy": "preserve_absence",
  "collected_at": "2026-05-24T20:33:00.000Z"
}
```

Use this checkpoint when building CSV, warehouse, search-index, or CRM rows.
Keep nested JSON when flattening would erase relationships.

## Interface mapping

| Interface | Field style | Contract |
| - | - | - |
| REST API | Mostly `camelCase` | `quoted_tweet`, `retweeted_tweet`, and `profile_bio` are documented exceptions |
| Generated SDKs | Language-native names | Generated OpenAPI models |
| MCP | Normalized | Most names use `snake_case`. REST `createdAt` becomes MCP `created` |
| Apify Actors | Configurable | Dataset schemas and Actor READMEs |

### Read Actor diagnostics

Interrupted extraction keeps available data and adds a free `partial` diagnostic.
Read the `diagnostics` output and `run-report` before retrying unfinished targets.
Diagnostic records use `resultType: "diagnostic"` and never count as billable results.

| Field | Meaning |
| - | - |
| `status` | Extraction outcome, such as `partial` or `zero-output` |
| `message` | Explanation of the extraction outcome |
| `availableResults` | Accepted data rows the run kept |
| `failedTargets` | Targets that failed during extraction |
| `retryable` | Whether retrying unfinished work is appropriate |
| `nextAction` | Suggested recovery step |

`SUCCEEDED` and HTTP 200 confirm run completion and response delivery.
They do not prove complete extraction. Check the diagnostic and report together.
Keep any other platform status accurate when investigating interrupted runs.

<Info>
  Xquik omits unavailable optional fields. It never invents missing X values.
</Info>

### Keep interface names explicit

Do not assume one casing rule covers every field. REST uses mostly camel case.
The documented nested exceptions keep their public names.

Generated SDKs expose language-native models from OpenAPI. Use the generated
property names for that SDK version. Do not hand-convert them from REST.

MCP tools normalize most response names for agents. REST `createdAt` becomes
MCP `created`. Actor datasets follow each Actor's documented output mode.

## Avoid tweet metadata mapping errors

<AccordionGroup>
  <Accordion title="Large IDs become rounded numbers">
    Precision lost. Store tweet, user, conversation, reply, and media IDs as
    strings before spreadsheet or JavaScript processing.
  </Accordion>

  <Accordion title="Missing optional fields become false or zero">
    Meaning changed. Keep field absence. Add a separate downstream default
    only when the consumer requires one.
  </Accordion>

  <Accordion title="Reply and conversation IDs are merged">
    Relationship lost. Keep `inReplyToId` for the parent. Keep
    `conversationId` for the root.
  </Accordion>

  <Accordion title="Quote and repost metrics are combined">
    Counts misattributed. Keep outer and nested tweet IDs in separate rows.
  </Accordion>

  <Accordion title="Profile growth uses usernames as keys">
    History split. Use the stable X user ID. Store the observed username as an
    attribute.
  </Accordion>

  <Accordion title="REST and MCP timestamps share one field name">
    Mapping failed. Map REST `createdAt` and MCP `created` explicitly.
  </Accordion>
</AccordionGroup>

## Tweet metadata and profile API questions

### How do I get tweet metadata?

Call the route matching your tweet, timeline, profile, or reply task.
Read the returned API response through its documented schema.
Keep IDs, counts, relationships, and cursors without inventing missing fields.

### Which Twitter API fields should I store?

Start with IDs, text, timestamps, authors, engagement counts, media, and
relationships.
Add optional fields only when X supplies them.
Store collection time beside mutable counts.

### Which Twitter API user fields identify a profile?

Use `id` as the stable profile key.
Keep `username`, `name`, bio, images, verification, followers, and following.
Record collection time beside changing profile counts.

### How do I read Twitter API response fields?

Follow each Xquik route's response schema in the API reference.
Use the field names documented for each interface.
Apply only documented mappings between REST, SDK, MCP, and Actor names.

### How do I read Twitter API pagination fields?

Twitter API pagination uses the response envelope documented for each route.
Read `has_next_page` with `next_cursor` for REST pages.
Read `hasMore` with `nextCursor` for extraction result pages.
Never mix cursors between those response envelopes.

### What metadata does a tweet include?

A tweet includes its ID, text, counts, URL, language, and relationship fields.
It can also include author, media, entities, labels, and edit objects. Article,
place, coordinates, geo, quote, repost, and Note Tweet objects can also appear.

### How do I find a tweet ID?

Read the response `id` field. Keep it as a string. Use it for lookups, joins,
deduplication, exports, and engagement snapshots.

### What is a Twitter conversation ID?

`conversationId` identifies the root tweet for the returned conversation.
`inReplyToId` identifies one reply's direct parent. Keep both fields.

### How do I know whether a tweet is a reply?

Check `isReply`. Then read `inReplyToId`, `inReplyToUserId`, and
`inReplyToUsername` when present.

### How do quotes differ from reposts?

Quotes can add new outer tweet text and `quoted_tweet` context. Reposts expose
original context through `retweeted_tweet`. Keep both tweet IDs separate.

### Which fields contain Twitter engagement metrics?

Use `likeCount`, `replyCount`, `retweetCount`, `quoteCount`, `viewCount`, and
`bookmarkCount`. Store collection time because these counts can change.

### Does the Twitter profile API include follower counts?

Yes. Read `followers` and `following` when supplied. Store dated snapshots for
growth tracking. Join snapshots through the profile `id`.

### Why is a tweet or profile field missing?

The field is optional and X did not supply it for that response. Keep the
absence. Never replace it with an invented value.

### How do I get tweet media metadata?

Read the tweet's `media` array. Use `type`, URLs, dimensions, alt text,
duration, availability, and video variants when present.

### Can I export tweet metadata to CSV?

Yes. Flatten selected scalar fields and keep stable IDs. Store nested author,
media, quote, and repost objects separately. Use linked rows or JSON columns.

### Do REST, SDK, MCP, and actor fields match exactly?

They share the documented contract but can expose different field naming.
Follow the OpenAPI model, MCP response shape, or Actor dataset schema directly.

## Sports context

`sportsContext` appears when X attaches game details to a post.
It includes `gameId`, `league`, `title`, `url`, `state`, and `statusText` when available.
`scheduledAtMs` keeps the source's numeric or string Unix timestamp in milliseconds.

Each `competitors` entry can include `teamId`, `name`, `abbreviation`, and `score`.
`color` contains the team display color.
`isActive` and `isWinner` describe the competitor. Both keep `false` values.
`logoUrl` and `darkLogoUrl` provide team images for light and dark backgrounds.
IDs and score display values remain strings. A score of `"0"` remains valid.
Missing fields stay omitted. These values describe the captured response, not live score updates.

<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>


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