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

# Type definitions

> Common TypeScript definitions for Xquik API request and response objects

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

Copy-pasteable TypeScript helpers for common Xquik API objects. Use these for prototypes, docs examples, and lightweight clients. For complete generated coverage, use the [OpenAPI spec](https://docs.xquik.com/openapi.yaml) or an [official SDK](/sdks).

## Usage

3 ways to use these types in your project:

1. **Copy curated types** - copy the "Response types", "Request types", and "Shared types" tabs into a single `xquik-types.ts` file
2. **Copy individual interfaces** - grab only the types you need (e.g. `Tweet`, `EventList`)
3. **Generate full coverage from OpenAPI** - use the [OpenAPI spec](https://docs.xquik.com/openapi.yaml) with tools like `openapi-typescript` to auto-generate types:
   ```bash theme={null}
   npx openapi-typescript https://docs.xquik.com/openapi.yaml -o xquik-api.d.ts
   ```

<Tip>
  For production projects, option 3 or an official SDK is the safest source for complete coverage. For quick prototypes, copy only the interfaces you need.
</Tip>

<Tabs>
  <Tab title="Response types">
    Response objects returned by API endpoints.

    ```typescript theme={null}
    // ─── Account ─────────────────────────────────────────────

    interface Account {
      plan: "active" | "inactive";
      monitorsAllowed: number;
      monitorsUsed: number;
      creditInfo?: {
        balance: number;
        lifetimePurchased: number;
        lifetimeUsed: number;
        autoTopupEnabled: boolean;
      };
      xUsername?: string;
    }

    // ─── API Keys ────────────────────────────────────────────

    // Returned when creating a new key (includes full key)
    interface ApiKeyCreated {
      id: string;
      fullKey: string;
      prefix: string;
      name: string;
      createdAt: string;
    }

    // Returned when listing keys (full key is never exposed)
    interface ApiKey {
      id: string;
      name: string;
      prefix: string;
      isActive: boolean;
      createdAt: string;
      lastUsedAt?: string;
    }

    // ─── Monitors ────────────────────────────────────────────

    interface Monitor {
      id: string;
      username: string;
      xUserId: string;
      eventTypes: EventType[];
      isActive: boolean;
      createdAt: string;
      nextBillingAt: string;
    }

    interface KeywordMonitor {
      id: string;
      query: string;
      eventTypes: EventType[];
      isActive: boolean;
      createdAt: string;
      nextBillingAt: string;
    }

    // ─── Events ──────────────────────────────────────────────

    interface Event {
      id: string;
      type: EventType;
      monitorId: string;
      monitorType: "account" | "keyword";
      occurredAt: string;
      data: EventData;
      username?: string;
      query?: string;
      keywordMonitorId?: string;
      xEventId?: string;
    }

    interface EventList {
      events: Event[];
      hasMore: boolean;
      nextCursor?: string;
    }

    // ─── Webhooks ────────────────────────────────────────────

    // Returned when creating a webhook (includes signing secret)
    interface WebhookCreated {
      id: string;
      url: string;
      eventTypes: EventType[];
      secret: string;
      createdAt: string;
    }

    // Returned when listing webhooks (secret is never exposed)
    interface Webhook {
      id: string;
      url: string;
      eventTypes: EventType[];
      isActive: boolean;
      createdAt: string;
    }

    // ─── Deliveries ──────────────────────────────────────────

    interface Delivery {
      id: string;
      streamEventId: string;
      status: "pending" | "delivered" | "failed" | "exhausted";
      attempts: number;
      lastStatusCode?: number;
      lastError?: string;
      createdAt: string;
      deliveredAt?: string;
    }

    // ─── Webhook Payload ─────────────────────────────────────

    interface WebhookPayload {
      eventType: EventType;
      schemaVersion: 1;
      deliveryId: string;
      streamEventId: string;
      occurredAt: string;
      data: EventData;
      username?: string;
      query?: string;
    }

    interface WebhookTestPayload {
      eventType: "webhook.test";
      data: { message: string };
      timestamp: string;
    }

    // ─── Draws ──────────────────────────────────────────────

    interface Draw {
      id: string;
      tweetId: string;
      tweetUrl: string;
      tweetText: string;
      tweetAuthorUsername: string;
      tweetLikeCount: number;
      tweetRetweetCount: number;
      tweetReplyCount: number;
      tweetQuoteCount: number;
      status: "pending" | "running" | "completed" | "failed";
      totalEntries: number;
      validEntries: number;
      createdAt: string;
      drawnAt?: string;
    }

    interface DrawListItem {
      id: string;
      tweetUrl: string;
      status: "pending" | "running" | "completed" | "failed";
      totalEntries: number;
      validEntries: number;
      createdAt: string;
      drawnAt?: string;
    }

    interface DrawWinner {
      position: number;
      authorUsername: string;
      tweetId: string;
      isBackup: boolean;
    }

    interface DrawList {
      draws: DrawListItem[];
      hasMore: boolean;
      nextCursor?: string;
    }

    // ─── Extractions ────────────────────────────────────────

    interface ExtractionJob {
      id: string;
      toolType: ExtractionToolType;
      status: "pending" | "running" | "completed" | "failed";
      totalResults: number;
      targetTweetId?: string;
      targetUsername?: string;
      targetUserId?: string;
      targetCommunityId?: string;
      searchQuery?: string;
      errorMessage?: string;
      createdAt: string;
      completedAt?: string;
    }

    interface ExtractionResult {
      id: string;
      xUserId: string;
      xUsername?: string;
      xDisplayName?: string;
      xFollowersCount?: number;
      xVerified?: boolean;
      xProfileImageUrl?: string;
      tweetId?: string;
      tweetText?: string;
      tweetCreatedAt?: string;
      createdAt: string;
      enrichmentData?: Record<string, unknown>;
    }

    interface ExtractionList {
      extractions: ExtractionJob[];
      hasMore: boolean;
      nextCursor?: string;
    }

    interface ExtractionEstimate {
      allowed: boolean;
      source: "replyCount" | "retweetCount" | "quoteCount" | "followers" | "resultsLimit" | "unknown";
      estimatedResults: number;
      creditsRequired: string;
      creditsAvailable: string;
      resolvedXUserId?: string;
    }

    // ─── X API ──────────────────────────────────────────────

    interface Tweet {
      id: string;
      text: string;
      type?: string;
      createdAt?: string;
      retweetCount?: number;
      replyCount?: number;
      likeCount?: number;
      quoteCount?: number;
      viewCount?: number;
      bookmarkCount?: number;
      media?: TweetMediaItem[];
      url?: string;
      lang?: string;
      isReply?: boolean;
      inReplyToId?: string;
      inReplyToUserId?: string;
      inReplyToUsername?: string;
      conversationId?: string;
      source?: string;
      displayTextRange?: number[];
      isNoteTweet?: boolean;
      isQuoteStatus?: boolean;
      isLimitedReply?: boolean;
      entities?: Record<string, unknown>;
      author?: UserProfile;
      quoted_tweet?: Tweet;
      retweeted_tweet?: Tweet;
    }

    interface TweetAuthor {
      id: string;
      username: string;
      followers: number;
      verified: boolean;
      profilePicture?: string;
    }

    interface TweetSearchResult {
      id: string;
      text: string;
      createdAt: string;
      likeCount: number;
      retweetCount: number;
      replyCount: number;
      author: {
        id: string;
        username: string;
        name: string;
        verified: boolean;
      };
      media?: TweetMediaItem[];
    }

    interface UserProfile {
      id: string;
      username: string;
      name: string;
      description?: string;
      followers?: number;
      following?: number;
      verified?: boolean;
      profilePicture?: string;
      coverPicture?: string;
      location?: string;
      createdAt?: string;
      statusesCount?: number;
      mediaCount?: number;
      canDm?: boolean;
      url?: string;
      favouritesCount?: number;
      hasCustomTimelines?: boolean;
      isTranslator?: boolean;
      withheldInCountries?: string[];
      possiblySensitive?: boolean;
      pinnedTweetIds?: string[];
      isAutomated?: boolean;
      automatedBy?: string;
      unavailable?: boolean;
      unavailableReason?: string;
      verifiedType?: string;
      profile_bio?: Record<string, unknown>;
    }

    interface FollowerCheck {
      sourceUsername: string;
      targetUsername: string;
      isFollowing: boolean;
      isFollowedBy: boolean;
    }

    // ─── Trends ─────────────────────────────────────────────

    interface Trend {
      name: string;
      description?: string;
      rank?: number;
      query?: string;
    }

    interface TrendList {
      trends: Trend[];
      total: number;
      woeid: number;
    }

    // ─── Radar ──────────────────────────────────────────────

    interface RadarItem {
      id: string;
      title: string;
      description?: string;
      url?: string;
      imageUrl?: string;
      source: RadarSource;
      sourceId: string;
      category: RadarCategory;
      region: string;
      language: string;
      score: number;
      metadata: Record<string, unknown>;
      publishedAt: string;
      createdAt: string;
    }

    interface RadarList {
      items: RadarItem[];
      hasMore: boolean;
      nextCursor?: string;
    }

    // ─── Styles ─────────────────────────────────────────────

    interface StyleProfile {
      xUsername: string;
      isOwnAccount: boolean;
      tweetCount: number;
      fetchedAt: string;
      tweets: StyleTweet[];
    }

    interface StyleListItem {
      xUsername: string;
      isOwnAccount: boolean;
      tweetCount: number;
      fetchedAt: string;
    }

    interface StyleList {
      styles: StyleListItem[];
    }

    interface StyleComparison {
      style1: StyleProfile;
      style2: StyleProfile;
    }

    interface PerformanceAnalysis {
      xUsername: string;
      tweetCount: number;
      tweets: PerformanceTweet[];
    }

    // ─── Drafts ─────────────────────────────────────────────

    interface Draft {
      id: string;
      text: string;
      topic?: string;
      goal?: "engagement" | "followers" | "authority" | "conversation";
      createdAt: string;
      updatedAt: string;
    }

    interface DraftList {
      drafts: Draft[];
      hasMore: boolean;
      nextCursor?: string;
    }

    // ─── X Accounts ───────────────────────────────────────────

    interface XAccount {
      id: string;
      username: string;
      displayName: string;
      isActive: boolean;
      createdAt: string;
    }

    // ─── Compose ──────────────────────────────────────────────

    // step="compose" response
    interface ComposeTweetResult {
      contentRules: { rule: string }[];
      engagementMultipliers: { action: string; multiplier: string }[];
      engagementVelocity: string;
      followUpQuestions: string[];
      intentUrl: string;
      nextStep: string;
      savedStyles?: { tweetCount: number; username: string }[];
      scorerWeights: { signal: string; weight: number; context: string }[];
      source: string;
      styleNote?: string;
      styleTweets?: string[];
      topPenalties: string[];
    }

    // step="refine" response
    interface RefineTweetResult {
      compositionGuidance: string[];
      examplePatterns: { description: string; pattern: string }[];
      intentUrl: string;
      nextStep: string;
    }

    // step="score" response
    interface ScoreTweetResult {
      passed: boolean;
      passedCount: number;
      totalChecks: number;
      topSuggestion: string;
      nextStep: string;
      checklist: { factor: string; passed: boolean; suggestion?: string }[];
      intentUrl?: string;
    }

    // ─── X Write ──────────────────────────────────────────────

    interface XWriteResponse {
      success: boolean;
      data?: Record<string, unknown>;
    }

    // ─── Support Tickets ──────────────────────────────────────

    interface SupportTicket {
      publicId: string;
      subject: string;
      status: "open" | "in_progress" | "resolved" | "closed";
      messageCount: number;
      createdAt: string;
      updatedAt: string;
    }

    interface SupportTicketDetail {
      publicId: string;
      subject: string;
      status: "open" | "in_progress" | "resolved" | "closed";
      createdAt: string;
      updatedAt: string;
      messages: SupportMessage[];
    }

    interface SupportMessage {
      body: string;
      sender: "user" | "support";
      createdAt: string;
    }

    // ─── Error Response ──────────────────────────────────────

    interface ApiError {
      error: string;
      limit?: number; // only present for monitor_limit_reached
    }
    ```
  </Tab>

  <Tab title="Request types">
    Request body types for POST/PATCH endpoints.

    ```typescript theme={null}
    interface CreateMonitorRequest {
      username: string;
      eventTypes: EventType[];
    }

    interface UpdateMonitorRequest {
      eventTypes?: EventType[];
      isActive?: boolean;
    }

    interface CreateWebhookRequest {
      url: string;
      eventTypes: EventType[];
    }

    interface UpdateWebhookRequest {
      url?: string;
      eventTypes?: EventType[];
      isActive?: boolean;
    }

    interface CreateApiKeyRequest {
      name?: string;
    }

    interface CreateDrawRequest {
      tweetUrl: string;
      winnerCount?: number;
      backupCount?: number;
      uniqueAuthorsOnly?: boolean;
      mustRetweet?: boolean;
      mustFollowUsername?: string;
      filterMinFollowers?: number;
      filterAccountAgeDays?: number;
      filterLanguage?: string;
      requiredKeywords?: string[];
      requiredHashtags?: string[];
      requiredMentions?: string[];
    }

    interface CreateExtractionRequest {
      toolType: ExtractionToolType;
      targetTweetId?: string;
      targetUsername?: string;
      targetCommunityId?: string;
      targetListId?: string;
      targetSpaceId?: string;
      searchQuery?: string;
      resultsLimit?: number;
    }

    interface CreateDraftRequest {
      text: string;
      topic?: string;
      goal?: "engagement" | "followers" | "authority" | "conversation";
    }

    interface ComposeRequest {
      step: "compose" | "refine" | "score";
      topic?: string;
      goal?: ComposeTweetGoal;
      styleUsername?: string;
      tone?: string;
      additionalContext?: string;
      callToAction?: string;
      hasLink?: boolean;
      hasMedia?: boolean;
      mediaType?: MediaType;
      draft?: string;
    }
    ```
  </Tab>

  <Tab title="Shared types">
    Enums and shared types used across request and response objects.

    ```typescript theme={null}
    type EventType =
      | "tweet.new"
      | "tweet.quote"
      | "tweet.reply"
      | "tweet.retweet"
      | "tweet.media"
      | "tweet.link"
      | "tweet.poll"
      | "tweet.mention"
      | "tweet.hashtag"
      | "tweet.longform"
      | "profile.avatar.changed"
      | "profile.banner.changed"
      | "profile.name.changed"
      | "profile.username.changed"
      | "profile.bio.changed"
      | "profile.location.changed"
      | "profile.url.changed"
      | "profile.verified.changed"
      | "profile.protected.changed"
      | "profile.pinned_tweet.changed"
      | "profile.unavailable.changed";

    // The data field contains the raw tweet object from the X real-time stream.
    interface TweetEventData {
      id: string;
      text: string;
      author: {
        id: string;
        userName: string;
        name: string;
      };
      isRetweet: boolean;
      isReply: boolean;
      isQuote: boolean;
      createdAt: string;
      inReplyToId?: string;
      quoted_tweet?: {
        id: string;
        text: string;
        author: { userName: string };
      };
    }

    type EventData = TweetEventData;

    interface EventFilters {
      keywords?: { include?: string[]; exclude?: string[] };
      minLikes?: number;
      minRetweets?: number;
      verifiedOnly?: boolean;
    }

    type ExtractionToolType =
      | "article_extractor"
      | "community_extractor"
      | "community_moderator_explorer"
      | "community_post_extractor"
      | "community_search"
      | "favoriters"
      | "follower_explorer"
      | "following_explorer"
      | "list_follower_explorer"
      | "list_member_extractor"
      | "list_post_extractor"
      | "mention_extractor"
      | "people_search"
      | "post_extractor"
      | "quote_extractor"
      | "reply_extractor"
      | "repost_extractor"
      | "space_explorer"
      | "thread_extractor"
      | "tweet_search_extractor"
      | "user_likes"
      | "user_media"
      | "verified_follower_explorer";

    type ComposeTweetGoal = "authority" | "conversation" | "engagement" | "followers";
    type MediaType = "none" | "photo" | "video";

    type RadarSource = string;

    type RadarCategory =
      | "business"
      | "culture"
      | "dev"
      | "entertainment"
      | "general"
      | "politics"
      | "science"
      | "tech";

    interface TweetMediaItem {
      mediaUrl: string;
      type: string;
      url: string;
    }

    interface StyleTweet {
      id: string;
      authorUsername: string;
      text: string;
      createdAt: string;
      media?: TweetMediaItem[];
    }

    interface PerformanceTweet {
      id: string;
      text: string;
      likeCount: number;
      retweetCount: number;
      replyCount: number;
      quoteCount: number;
      viewCount: number;
      bookmarkCount: number;
    }
    ```
  </Tab>
</Tabs>

## REST API vs MCP Field Naming

<Info>
  REST examples show the default v1 response contract unless they explicitly send `xquik-api-contract: 2026-04-29`. The MCP server's `xquik.request()` tool sends that normalized contract automatically, so paginated MCP responses use `has_more` and `next_cursor`. Pass `next_cursor` as `cursor` on most X data pages, or as `after` for draws, extractions, events, and radar.
</Info>

## Type reference

### Account

Returned by `GET /api/v1/account`. The `creditInfo` field is omitted when no credit balance record exists yet. `creditInfo.balance` shows the current credit count available for metered API calls.

### API Keys

Two shapes exist: `ApiKeyCreated` is returned only from `POST /api/v1/api-keys` and includes the `fullKey` field. This is the only time the full key is exposed. `ApiKey` is returned by `GET /api/v1/api-keys` and shows only the `prefix` (first 8 characters) for identification.

### Monitors

Account monitor endpoints return `Monitor`. The `xUserId` is the X (Twitter) user ID resolved from the `username` at creation time. Keyword monitor endpoints return `KeywordMonitor` with the normalized X search `query`. Both monitor types include `eventTypes`, `isActive`, `createdAt`, and `nextBillingAt` for active monitor billing.

### Events

`Event` represents a single tracked action from an account or keyword monitor. `monitorType` is `account` or `keyword`; `monitorId` points to the source monitor. Account events include `username`; keyword events include `query` and `keywordMonitorId`. The `data` field contains tweet event data with `id`, `text`, `author`, `isRetweet`, `isReply`, `isQuote`, and `createdAt`. Replies include `inReplyToId`, quotes include a nested `quoted_tweet` object. Retweets are identified by `isRetweet: true`. See the `TweetEventData` interface in the Shared types tab for the full shape. `EventList` wraps paginated responses. Use `nextCursor` with the `after` query parameter to fetch subsequent pages.

### Webhooks

Similar to API keys, webhooks have two shapes. `WebhookCreated` includes the `secret` field used for HMAC signature verification. `Webhook` (from list) never exposes the secret. If you lose the secret, delete and recreate the webhook.

### Deliveries

Each `Delivery` represents one attempt to send an event to a webhook endpoint. Status progresses from `pending` to `delivered` (success) or through `failed` to `exhausted` (all retries failed). `lastStatusCode` and `lastError` help diagnose delivery failures.

### Webhook payload

The `WebhookPayload` type describes the JSON body your endpoint receives on each delivery. Normal monitor events include `schemaVersion`, `deliveryId`, `streamEventId`, `occurredAt`, `eventType`, and `data`. Account monitor events include `username`; keyword monitor events include `query`. Verify authenticity with the `X-Xquik-Signature` header and your webhook secret. See [Webhook Verification](/webhooks/verification) for implementation details.

<Note>
  `webhook.test` payloads include `timestamp` and omit monitor-only fields because they are not tied to a stored event. In normal event payloads, `timestamp` is omitted.
</Note>

### Draws

`Draw` is the full draw object returned by `GET /api/v1/draws/{id}` with tweet metadata and engagement counts. `DrawListItem` is the compact shape returned in list responses. `DrawWinner` contains the position, username, tweet ID, and backup flag for each winner. Filter fields on `CreateDrawRequest` control which entries qualify for the draw.

### Extractions

`ExtractionJob` represents a completed or failed extraction job. The target fields (`targetTweetId`, `targetUsername`, etc.) vary by `toolType`. `ExtractionResult` contains the core user and tweet data returned by the API. Results are paginated in the get endpoint with up to 1,000 results per page. Exports (CSV, XLSX, Markdown) include additional enrichment columns not present in the API response. See [Export Extraction](/api-reference/extractions/export) for the full column list. `ExtractionEstimate` previews the cost before running a job.

### X API

Direct X data lookup types. `Tweet` and `TweetAuthor` are returned by the tweet lookup endpoint. `TweetSearchResult` is returned in search results with an inline `author` object. `UserProfile` contains the full user profile. `FollowerCheck` returns the bidirectional follow relationship between two users. Both `Tweet` and `TweetSearchResult` include an optional `media` array of `TweetMediaItem` objects, present only when the tweet has attached media. Media types are `photo`, `video`, or `animated_gif`.

### Trends

`Trend` represents a single trending topic on X. The `description`, `rank`, and `query` fields are omitted when unavailable. `TrendList` wraps the `GET /api/v1/trends` response. `total` is the number of trends returned, `woeid` is the region ID.

### Radar

`RadarItem` represents a single trending topic or news item from Xquik's own infrastructure. The `source` field identifies the Radar stream, and the `metadata` object contains stream-specific fields such as author, category, language, score, volume, views, or community signals when available. `RadarList` wraps paginated responses from `GET /api/v1/radar`. Use `nextCursor` with the `after` query parameter to fetch subsequent pages.

### Styles

`StyleProfile` is returned by the analyze style (`POST /api/v1/styles`) and get style (`GET /api/v1/styles/{id}`) endpoints. It includes the cached tweets array with text, media, and timestamps. `StyleListItem` is the compact shape returned by `GET /api/v1/styles` (no tweets). `StyleComparison` wraps two full profiles for side-by-side comparison. `PerformanceAnalysis` adds engagement metrics (likes, retweets, replies, quotes, views, bookmarks) to each cached tweet. `isOwnAccount` is `true` when the analyzed username matches the authenticated user's linked X identity.

### Drafts

`Draft` represents a saved tweet draft. List, create, and get responses include `id`, `text`, `createdAt`, and `updatedAt`. Optional `topic` and `goal` fields are omitted (not null) when not set. `DraftList` wraps paginated responses. Use `nextCursor` with the `afterCursor` query parameter to fetch subsequent pages. Maximum 50 drafts per page.

### X Accounts

`XAccount` represents a linked X account. `displayName` is the user's display name on X. `isActive` indicates whether the account is currently connected and usable for API operations.

### Compose

`ComposeRequest` drives the 3-step tweet composition flow: `compose` returns algorithm rules, follow-up questions, and an `intentUrl` built from the topic; `refine` returns composition guidance and example patterns; `score` evaluates a draft's quality. `styleUsername` accepts a cached style username for voice matching. Compose responses can include `savedStyles`, `styleTweets`, or `styleNote` depending on the cached style state.

### X Write

`XWriteResponse` is returned by write operations (post, retweet, like, reply). `success` indicates whether the operation completed. The optional `data` field contains platform-specific response data when available.

### Support tickets

`SupportTicket` is the compact shape returned in list responses. `SupportTicketDetail` includes the full `messages` array. Each `SupportMessage` has a `sender` field indicating whether the message is from the user or support team. Status progresses from `open` through `in_progress` to `resolved` or `closed`.

### Request bodies

All request body types use optional fields for update operations (PATCH) and required fields for creation (POST). The API validates request bodies and returns `400 invalid_input` for missing or malformed fields.
