Copy-pasteable TypeScript types for every Xquik API object. Use these in your client code for full type safety. These types match the response shapes from the API Reference.
Usage
3 ways to use these types in your project:
- Copy all types — copy the entire “Response types”, “Request types”, and “Shared types” tabs into a single
xquik-types.ts file
- Copy individual interfaces — grab only the types you need (e.g.
Tweet, EventList)
- Generate 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 large projects, option 1 or 3 is recommended. For quick prototypes, copy only the interfaces you need.
Response types
Request types
Shared types
Response objects returned by API endpoints.// ─── Account ─────────────────────────────────────────────
interface Account {
plan: "active" | "inactive";
pricingVersion: number;
monitorsAllowed: number;
monitorsUsed: number;
currentPeriod?: {
start: string;
end: string;
usagePercent: number;
};
}
// ─── 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;
}
// ─── Events ──────────────────────────────────────────────
interface Event {
id: string;
type: EventType;
monitorId: string;
username: string;
occurredAt: string;
data: EventData;
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;
username: string;
data: EventData;
}
// ─── 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" | "unknown";
estimatedResults: number;
usagePercent: number;
projectedPercent: number;
error?: 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[];
count: 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;
}
// ─── Integrations ─────────────────────────────────────────
interface Integration {
id: string;
type: string;
name: string;
config: Record<string, unknown>;
eventTypes: string[];
filters: EventFilters | null;
messageTemplate: string | null;
scopeAllMonitors: boolean;
silentPush: boolean;
isActive: boolean;
createdAt: string;
updatedAt: string;
}
// ─── Compose ──────────────────────────────────────────────
// step="compose" response
interface ComposeTweetResult {
contentRules: { rule: string }[];
engagementMultipliers: { action: string; multiplier: string }[];
engagementVelocity: string;
followUpQuestions: string[];
intentUrl: string;
nextStep: string;
scorerWeights: { signal: string; weight: number; context: string }[];
source: 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
}
Request body types for POST/PATCH endpoints.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;
}
Enums and shared types used across request and response objects.type EventType =
| "follower.gained"
| "follower.lost"
| "tweet.new"
| "tweet.quote"
| "tweet.reply"
| "tweet.retweet";
// 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 };
};
}
interface FollowerEventData {
followerId: string;
followerUsername: string;
followerName: string;
followerFollowersCount: number;
followerVerified: boolean;
}
type EventData = TweetEventData | FollowerEventData;
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 =
| "github"
| "google_trends"
| "hacker_news"
| "polymarket"
| "reddit"
| "trustmrr"
| "wikipedia";
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;
}
REST API vs MCP Field Naming
The MCP server’s xquik tool calls REST API endpoints directly via xquik.request() and returns the same response shapes documented here. No field name mapping is needed.
Type reference
Account
Returned by GET /api/v1/account. The currentPeriod field is omitted when there is no active subscription. usagePercent is an integer (0-100) representing how much of the monthly quota has been consumed.
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
Returned by all monitor endpoints. The xUserId is the X (Twitter) user ID resolved from the username at creation time. eventTypes controls which event types this monitor tracks.
Events
Event represents a single tracked action from a monitored account. The data field shape depends on the event type: tweet events contain tweetId, text, and metrics, while follower events contain followerId, followerUsername, followerName, followerFollowersCount, and followerVerified. Tweet subtypes include additional fields (quotedTweetId for quotes, inReplyToTweetId for replies, retweetedTweetId for retweets). 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/get) 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. It contains only 3 fields: the event type, the monitored username, and the event data. Verify its authenticity using the X-Xquik-Signature header and your webhook secret. See Webhook Verification for implementation details.
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.
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.
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. count 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/:username) 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. 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.
Integrations
Integration represents a configured notification channel (e.g., Discord, Telegram, Slack). eventTypes controls which event types trigger notifications. filters optionally narrows events by keywords, engagement thresholds, or verification status. scopeAllMonitors sends events from all monitors when true; when false, the integration must be linked to specific monitors. silentPush suppresses notification sounds when supported by the platform.
Compose
ComposeRequest drives the 3-step tweet composition flow: compose generates a draft from a topic and goal, refine improves an existing draft, and score evaluates a draft’s quality. style accepts a username whose writing style to emulate. ComposeResponse returns the generated tweet text and an intentUrl that opens the X compose dialog pre-filled with the tweet.
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.