Skip to main content

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.

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 or an official SDK.

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 with tools like openapi-typescript to auto-generate types:
    npx openapi-typescript https://docs.xquik.com/openapi.yaml -o xquik-api.d.ts
    
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.
Response objects returned by API endpoints.
// ─── 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
}

REST API vs MCP Field Naming

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.

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 for implementation details.
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.

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 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. 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 one of 7 sources. The metadata field shape depends on the source: GitHub includes starsToday and language, Hacker News includes points, numberComments, and author, Reddit includes subreddit and author, Google Trends includes approxTraffic, Wikipedia includes views, and TrustMRR includes mrr, growthPercent, last30Days, customers, activeSubscriptions, onSale, category, and xHandle. 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.
Last modified on May 25, 2026