Skip to main content
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 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

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

Required fields

Tweet objects require id, text, and documented engagement counts. Profile objects require id, username, and name.

Optional fields

The API omits optional fields when X does not supply them. Absence is not an empty string, false value, or 0 count.

String IDs

Keep tweet, user, media, conversation, and reply IDs as strings. Large IDs can lose precision in spreadsheet or JavaScript number types.

Count snapshots

Likes, replies, reposts, quotes, views, bookmarks, followers, and following counts can change after collection. Store collected_at downstream.
A 0 tweet metric can mean X did not report that count. Do not treat every 0 as a measured absence.

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
Tweets also include available entities, disclosures, nested tweets, and media.

Tweet metadata example

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.

Direct reply

Join inReplyToId to the parent tweet. Keep conversationId for the full thread.

Quote

Join quoted_tweet.id to the quoted tweet. Attribute quote text to the outer tweet.

Repost

Join retweeted_tweet.id to the original tweet. Do not merge their metric snapshots.

Note tweet

Keep noteTweet.inlineMedia positions with long-form text and formatting.

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 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. Xquik removes account-specific actions, permissions, and relationships from public reads. Use dedicated write routes or X for account state.

Twitter profile API example

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.

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

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

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

Interface mapping

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. 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.
Xquik omits unavailable optional fields. It never invents missing X values.

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

Precision lost. Store tweet, user, conversation, reply, and media IDs as strings before spreadsheet or JavaScript processing.
Meaning changed. Keep field absence. Add a separate downstream default only when the consumer requires one.
Relationship lost. Keep inReplyToId for the parent. Keep conversationId for the root.
Counts misattributed. Keep outer and nested tweet IDs in separate rows.
History split. Use the stable X user ID. Store the observed username as an attribute.
Mapping failed. Map REST createdAt and MCP created explicitly.

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.