UNPKG

x-developer

Version:

X (Twitter) data platform skill for AI coding agents. 100+ REST API endpoints, 2 MCP tools, 23 extraction types, HMAC webhooks.

1,041 lines (892 loc) 31.1 kB
# Xquik TypeScript Type Definitions Copy-pasteable TypeScript types for all Xquik API objects. ## Contents - [Account](#account) - [API Keys](#api-keys) - [Credits](#credits) - [Monitors](#monitors) - [Events](#events) - [Webhooks](#webhooks) - [Draws](#draws) - [Extractions](#extractions) - [X API](#x-api) - [Trends](#trends) - [Support](#support) - [Error](#error) - [Request Bodies](#request-bodies) - [MCP Output Schemas](#mcp-output-schemas) ```typescript // ─── Account ───────────────────────────────────────────── interface Account { plan: "active" | "inactive"; monitorsAllowed: number; monitorsUsed: number; monitorBilling: { activeDailyEstimate: string; activeHourlyBurn: string; creditsPerActiveMonitorDay: string; creditsPerActiveMonitorHour: string; eventsIncluded: boolean; instantCheckIntervalSeconds: number; unlimitedSlots: boolean; }; creditInfo?: { balance: string; lifetimePurchased: string; lifetimeUsed: string; autoTopupEnabled: boolean; autoTopupAmountDollars: number; autoTopupThreshold: string; }; xUsername?: string; } // ─── Credits ──────────────────────────────────────────── interface CreditBalance { balance: string; // Current credit balance, bigint string lifetimePurchased: string; // Total credits purchased, bigint string lifetimeUsed: string; // Total credits consumed, bigint string autoTopupEnabled: boolean; // Whether auto top-up is enabled autoTopupAmountDollars: number; // Dollar amount charged by auto top-up autoTopupThreshold: string; // Trigger threshold, bigint string } interface CreditTopUpResponse { url: string; // Checkout URL } type CreditQuickTopUpResponse = | { outcome: "charged"; credits: string; // Credits added, bigint string balance: string; // New balance, bigint string } | { outcome: "no_payment_method" } | { outcome: "requires_action"; clientSecret: string; // Complete required cardholder action }; // ─── API Keys ──────────────────────────────────────────── interface ApiKeyCreated { id: string; fullKey: string; prefix: string; name: string; createdAt: string; } 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; } type EventType = | "tweet.new" | "tweet.quote" | "tweet.reply" | "tweet.retweet"; // ─── Events ────────────────────────────────────────────── interface Event { id: string; type: EventType; monitorId: string; username: string; occurredAt: string; data: EventData; xEventId?: string; } // Tweet events (tweet.new, tweet.reply, tweet.quote, tweet.retweet) interface TweetEventData { tweetId: string; text: string; metrics: { likes: number; retweets: number; replies: number; }; // tweet.quote only quotedTweetId?: string; quotedUsername?: string; // tweet.reply only inReplyToTweetId?: string; inReplyToUsername?: string; // tweet.retweet only retweetedTweetId?: string; retweetedUsername?: string; } type EventData = TweetEventData; interface EventList { events: Event[]; hasMore: boolean; nextCursor?: string; } // ─── Webhooks ──────────────────────────────────────────── interface WebhookCreated { id: string; url: string; eventTypes: EventType[]; secret: string; createdAt: string; } interface Webhook { id: string; url: string; eventTypes: EventType[]; isActive: boolean; createdAt: string; } interface Delivery { id: string; streamEventId: string; status: "pending" | "delivered" | "failed" | "exhausted"; attempts: number; lastStatusCode?: number; lastError?: string; createdAt: string; deliveredAt?: string; } 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; } 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[]; } // ─── Extractions ───────────────────────────────────────── 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"; interface ExtractionJob { id: string; toolType: ExtractionToolType; status: "pending" | "running" | "completed" | "failed"; totalResults: number; targetTweetId?: string; targetUsername?: string; targetUserId?: string; targetCommunityId?: string; targetListId?: string; targetSpaceId?: string; searchQuery?: string; resultsLimit?: number; // Max results to extract. Stops early instead of fetching all. Omit for all. 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; } interface ExtractionList { extractions: ExtractionJob[]; hasMore: boolean; nextCursor?: string; } interface ExtractionEstimate { allowed: boolean; creditsAvailable: string; creditsRequired: string; source: "replyCount" | "retweetCount" | "quoteCount" | "followers" | "unknown"; estimatedResults: number; resolvedXUserId?: string; error?: string; } interface CreateExtractionRequest { toolType: ExtractionToolType; targetTweetId?: string; targetUsername?: string; targetCommunityId?: string; targetListId?: string; targetSpaceId?: string; searchQuery?: string; resultsLimit?: number; // Max results to extract. Stops early instead of fetching all. Omit for all. // Tweet search filters (tweet_search_extractor only) fromUser?: string; toUser?: string; mentioning?: string; language?: string; sinceDate?: string; // YYYY-MM-DD untilDate?: string; // YYYY-MM-DD mediaType?: 'images' | 'videos' | 'gifs' | 'media'; minFaves?: number; minRetweets?: number; minReplies?: number; verifiedOnly?: boolean; replies?: 'include' | 'exclude' | 'only'; retweets?: 'include' | 'exclude' | 'only'; exactPhrase?: string; excludeWords?: string; advancedQuery?: string; } // ─── X API ─────────────────────────────────────────────── interface TweetMediaItem { mediaUrl: string; type: string; // "photo" | "video" | "animated_gif" url: string; } interface Tweet { id: string; text: string; createdAt?: string; retweetCount: number; replyCount: number; likeCount: number; quoteCount: number; viewCount: number; bookmarkCount: number; media?: TweetMediaItem[]; } interface TweetAuthor { id: string; username: string; followers: number; verified: boolean; profilePicture?: string; } interface TweetSearchResult { id: string; text: string; createdAt: string; likeCount: number; // Omitted if unavailable retweetCount: number; // Omitted if unavailable replyCount: number; // Omitted if unavailable media?: TweetMediaItem[]; author: { id: string; username: string; name: string; verified: boolean; }; } interface UserProfile { id: string; username: string; name: string; description?: string; followers?: number; following?: number; verified?: boolean; profilePicture?: string; location?: string; createdAt?: string; statusesCount?: number; } interface FollowerCheck { sourceUsername: string; targetUsername: string; isFollowing: boolean; isFollowedBy: boolean; } // ─── User Activity ────────────────────────────────────── interface UserTweetsResponse { tweets: Tweet[]; hasMore: boolean; nextCursor?: string; } interface UserLikesResponse { tweets: Tweet[]; hasMore: boolean; nextCursor?: string; } interface UserMediaResponse { tweets: Tweet[]; hasMore: boolean; nextCursor?: string; } interface TweetFavoritersResponse { users: UserProfile[]; hasMore: boolean; nextCursor?: string; } interface FollowersYouKnowResponse { users: UserProfile[]; hasMore: boolean; nextCursor?: string; } // ─── Bookmarks & Timeline ─────────────────────────────── interface BookmarksResponse { tweets: Tweet[]; hasMore: boolean; nextCursor?: string; } interface BookmarkFolder { id: string; name: string; } interface BookmarkFoldersResponse { folders: BookmarkFolder[]; } interface NotificationsResponse { notifications: Notification[]; hasMore: boolean; nextCursor?: string; } interface TimelineResponse { tweets: Tweet[]; hasMore: boolean; nextCursor?: string; } interface DmHistoryResponse { messages: DmMessage[]; hasMore: boolean; nextCursor?: string; } interface DmMessage { id: string; text: string; senderId: string; createdAt: string; media?: TweetMediaItem[]; } // ─── X Articles ───────────────────────────────────────── interface Article { title: string; coverImage?: string; bodyHtml: string; likeCount: number; retweetCount: number; replyCount: number; viewCount: number; bookmarkCount: number; author: { id: string; username: string; name: string; }; } // ─── Radar ─────────────────────────────────────────────── type RadarSource = | "github" | "google_trends" | "hacker_news" | "polymarket" | "reddit" | "trustmrr" | "wikipedia"; type RadarCategory = | "general" | "tech" | "dev" | "science" | "culture" | "politics" | "business" | "entertainment"; 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; } // ─── Download Media ───────────────────────────────────── interface DownloadMediaRequest { tweetInput?: string; // Tweet URL or numeric tweet ID (single mode) tweetIds?: string[]; // Array of tweet URLs or IDs (bulk mode, max 50). Exactly 1 of tweetInput or tweetIds required. } interface DownloadMediaSingleResponse { tweetId: string; // Resolved tweet ID galleryUrl: string; // Shareable gallery page URL cacheHit: boolean; // true if served from cache (no usage consumed) } interface DownloadMediaBulkResponse { galleryUrl: string; // Combined gallery page URL totalTweets: number; // Number of tweets processed totalMedia: number; // Total media items downloaded } // ─── Trends ────────────────────────────────────────────── interface Trend { name: string; description?: string; rank?: number; query?: string; } interface TrendList { trends: Trend[]; total: number; woeid: number; } // ─── Support ──────────────────────────────────────────── interface SupportTicket { id: string; subject: string; status: string; createdAt: string; updatedAt: string; } interface SupportMessage { id: string; body: string; sender: string; createdAt: string; } interface CreateTicketRequest { subject: string; body: string; } // ─── Error ─────────────────────────────────────────────── interface ApiError { error: string; limit?: number; } // ─── Request Bodies ────────────────────────────────────── 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; } // --- Tweet Style Cache --- interface TweetStyleCache { xUsername: string; tweetCount: number; isOwnAccount: boolean; fetchedAt: string; // ISO 8601 tweets: CachedTweet[]; } interface CachedTweet { id: string; text: string; authorUsername: string; createdAt: string; // ISO 8601 media?: TweetMediaItem[]; } interface TweetStyleSummary { xUsername: string; tweetCount: number; isOwnAccount: boolean; fetchedAt: string; } interface StyleComparison { style1: TweetStyleCache; style2: TweetStyleCache; } interface StylePerformance { xUsername: string; tweetCount: number; tweets: PerformanceTweet[]; } interface PerformanceTweet { id: string; text: string; likeCount: number; retweetCount: number; replyCount: number; quoteCount: number; viewCount: number; bookmarkCount: number; } // --- Tweet Drafts --- interface TweetDraft { id: string; text: string; topic?: string; goal?: "engagement" | "followers" | "authority" | "conversation"; createdAt: string; // ISO 8601 updatedAt: string; // ISO 8601 } interface TweetDraftList { drafts: TweetDraft[]; afterCursor: string | null; hasMore: boolean; } // --- Account Identity --- interface XIdentityResponse { success: boolean; xUsername: string; } ``` ## REST API vs MCP Field Naming The REST API and MCP server use different field names for the same data. Map these when switching between interfaces: | Type | REST API Field | MCP Field | |------|---------------|-----------| | **Monitor** | `username` | `xUsername` | | **Event** | `type` | `eventType` | | **Event** | `data` | `eventData` | | **Event** | `monitorId` | `monitoredAccountId` | | **UserProfile** | `followers` | `followersCount` | | **UserProfile** | `following` | `followingCount` | | **FollowerCheck** | `isFollowing` / `isFollowedBy` | `following` / `followedBy` | **MCP `get-user-info` returns a subset** of the full `UserProfile` type. Fields not returned by MCP: `verified`, `location`, `createdAt`, `statusesCount`. Use the REST API `GET /x/users/{username}` for the complete profile. ## MCP Output Schemas MCP tools return structured data with these shapes. Field names differ from the REST API (see mapping table above). ```typescript // ─── MCP: get-user-info ───────────────────────────────── interface McpUserInfo { username: string; // X username (without @) name: string; // Display name description: string; // User bio text followersCount: number; // Number of followers followingCount: number; // Number of accounts followed profilePicture: string; // Profile picture URL // Not returned: verified, location, createdAt, statusesCount // Use REST GET /x/users/{username} for the full profile } // ─── MCP: search-tweets ───────────────────────────────── interface McpSearchResult { tweets: { id: string; // Tweet ID (use with lookup-tweet for full metrics) text: string; // Full tweet text authorUsername: string; // X username of the tweet author authorName: string; // Display name of the tweet author createdAt: string; // ISO 8601 timestamp when tweet was posted media?: { mediaUrl: string; type: string; url: string }[]; // Attached photos/videos // No engagement metrics. Use lookup-tweet for those }[]; } // ─── MCP: lookup-tweet ────────────────────────────────── interface McpTweetLookup { tweet: { id: string; // Tweet ID text: string; // Tweet text likeCount: number; // Number of likes retweetCount: number; // Number of retweets replyCount: number; // Number of replies quoteCount: number; // Number of quote tweets viewCount: number; // Number of views bookmarkCount: number; // Number of bookmarks media?: { mediaUrl: string; type: string; url: string }[]; // Attached photos/videos }; author?: { // Tweet author details id: string; // Author user ID username: string; // Author X username followers: number; // Author follower count verified: boolean; // Whether the author is verified }; } // ─── MCP: check-follow ───────────────────────────────── interface McpFollowCheck { following: boolean; // Whether the source follows the target followedBy: boolean; // Whether the target follows the source } // ─── MCP: get-events ──────────────────────────────────── interface McpEventList { events: { id: string; // Event ID (use with get-event for full details) xUsername: string; // Username of the monitored account eventType: string; // Event type (tweet.new, tweet.reply, etc.) eventData: unknown; // Full event payload (tweet text, author, metrics) monitoredAccountId: string; // ID of the monitored account createdAt: string; // ISO 8601 when event was recorded occurredAt: string; // ISO 8601 when event occurred on X }[]; hasMore: boolean; // Whether more results are available nextCursor?: string; // Pass as afterCursor to fetch the next page } // ─── MCP: list-monitors ───────────────────────────────── interface McpMonitorList { monitors: { id: string; // Monitor ID (use with remove-monitor, get-events monitorId filter) xUsername: string; // Monitored X username eventTypes: string[]; // Subscribed event types isActive: boolean; // Whether the monitor is currently active createdAt: string; // ISO 8601 timestamp }[]; } // ─── MCP: add-webhook ─────────────────────────────────── interface McpWebhookCreated { id: string; // Webhook ID url: string; // HTTPS endpoint URL eventTypes: string[]; // Event types delivered to this webhook isActive: boolean; // Whether the webhook is active createdAt: string; // ISO 8601 timestamp secret: string; // HMAC signing secret for verifying webhook payloads. Store securely. } // ─── MCP: test-webhook ────────────────────────────────── interface McpWebhookTest { success: boolean; statusCode: number; error?: string; } // ─── MCP: run-extraction ──────────────────────────────── interface McpExtractionJob { id: string; // Extraction job ID (use with get-extraction for results) toolType: string; // Extraction tool type used status: string; // Job status totalResults: number; // Number of results extracted } // ─── MCP: estimate-extraction ─────────────────────────── interface McpExtractionEstimate { allowed?: boolean; // Whether the extraction is allowed within budget estimatedResults?: number; // Estimated number of results creditsRequired?: string; // Required credits, bigint string creditsAvailable?: string; // Available credits, bigint string source?: string; // Data source used for estimation resolvedXUserId?: string; // Resolved user ID for username-based estimates error?: string; // Error message if estimation failed } // ─── MCP: run-draw ────────────────────────────────────── interface McpDrawResult { id: string; // Draw ID (use with get-draw for full details) tweetId: string; // Giveaway tweet ID totalEntries: number; // Total reply count before filtering validEntries: number; // Valid entries after filtering winners: { position: number; // Winner position (1-based) authorUsername: string; // X username of the winner tweetId: string; // Tweet ID of the winning reply isBackup: boolean; // Whether this is a backup winner }[]; } // ─── MCP: get-draw ────────────────────────────────────── interface McpDrawDetails { draw: { id: string; // Draw ID status: string; // Draw status (completed, failed) createdAt: string; // ISO 8601 timestamp drawnAt?: string; // ISO 8601 timestamp when winners were drawn totalEntries: number; // Total reply count before filtering validEntries: number; // Entries remaining after filters applied tweetId: string; // Giveaway tweet ID tweetUrl: string; // Full URL of the giveaway tweet tweetText: string; // Giveaway tweet text tweetAuthorUsername: string; // Username of the giveaway tweet author tweetLikeCount: number; // Tweet like count at draw time tweetRetweetCount: number; // Tweet retweet count at draw time tweetReplyCount: number; // Tweet reply count at draw time tweetQuoteCount: number; // Tweet quote count at draw time }; winners: { position: number; // Winner position (1-based) authorUsername: string; // X username of the winner tweetId: string; // Tweet ID of the winning reply isBackup: boolean; // Whether this is a backup winner }[]; } // ─── MCP: get-account ─────────────────────────────────── interface McpAccount { plan: "active" | "inactive"; monitorsAllowed: number; // Deprecated; monitor slots are unlimited monitorsUsed: number; // Number of active monitors monitorBilling: { activeDailyEstimate: string; activeHourlyBurn: string; creditsPerActiveMonitorDay: string; creditsPerActiveMonitorHour: string; eventsIncluded: boolean; instantCheckIntervalSeconds: number; unlimitedSlots: boolean; }; creditInfo?: { balance: string; lifetimePurchased: string; lifetimeUsed: string; autoTopupEnabled: boolean; autoTopupAmountDollars: number; autoTopupThreshold: string; }; xUsername?: string; } // ─── MCP: get-trends ──────────────────────────────────── interface McpTrends { woeid: number; total: number; trends: { name: string; // Trend name or hashtag rank?: number; // Trend rank position description?: string; // Trend description or context query?: string; // Search query to find tweets for this trend }[]; } // ─── MCP: subscribe ──────────────────────────────────── interface McpSubscribe { status: "already_subscribed" | "checkout_created" | "payment_issue"; url: string; // Checkout or Customer Portal URL. Open in browser. message: string; // Human-readable status message } // ─── MCP: compose-tweet ──────────────────────────────── interface McpComposeTweet { algorithmInsights: { name: string; // Signal name from PhoenixScores polarity: "positive" | "negative"; // Whether this signal helps or hurts ranking description: string; // What this signal measures }[]; contentRules: { rule: string; // Actionable content rule description: string; // Why this rule matters based on algorithm architecture }[]; engagementMultipliers: { action: string; // Engagement action (e.g. reply chain, quote tweet) multiplier: string; // Relative value compared to a like (e.g. "27x a like") source: string; // Data source for this multiplier }[]; engagementVelocity: string; // How early engagement velocity affects distribution followUpQuestions: string[]; // Questions for the AI to ask the user before composing scorerWeights: { signal: string; // Signal name in the scoring model weight: number; // Weight applied to predicted probability context: string; // Practical meaning of this weight }[]; topPenalties: string[]; // Most severe negative signals to avoid source: string; // Attribution to algorithm source code } // ─── MCP: refine-tweet ───────────────────────────────── interface McpRefineTweet { compositionGuidance: string[]; // Targeted guidance based on user preferences examplePatterns: { pattern: string; // Tweet structure template description: string; // What this pattern achieves }[]; } // ─── MCP: score-tweet ────────────────────────────────── interface McpScoreTweet { totalChecks: number; // Total number of checks performed passedCount: number; // Number of checks that passed topSuggestion: string; // Highest-impact improvement suggestion checklist: { factor: string; // What was checked passed: boolean; // Whether the check passed suggestion?: string; // Improvement suggestion (present only if failed) }[]; } // ─── X Accounts (Connected) ────────────────────────── interface ConnectedXAccount { id: string; // Unique account ID username: string; // X username displayName?: string; // Display name on X isActive: boolean; // Whether the connection is active createdAt: string; // ISO 8601 timestamp } // Connecting an X account is done by the user in the Xquik dashboard, // not through this skill. The skill never handles X login material. // ─── X Write ────────────────────────────────────────── interface CreateTweetRequest { account: string; // Connected X username or account ID text: string; // Tweet text (280 chars, or 25,000 if is_note_tweet) reply_to_tweet_id?: string; // Tweet ID to reply to attachment_url?: string; // URL to attach as card community_id?: string; // Community ID to post into is_note_tweet?: boolean; // Long-form note tweet (up to 25,000 chars) media_ids?: string[]; // Media IDs from POST /x/media (max 4 images or 1 video) } interface CreateTweetResponse { tweetId: string; // ID of the newly created tweet success: boolean; // Always true on success } interface WriteActionRequest { account: string; // Connected X username or account ID } interface SendDmRequest { account: string; // Connected X username or account ID text: string; // Message text media_ids?: string[]; // Media IDs to attach reply_to_message_id?: string; // Message ID to reply to } interface UpdateProfileRequest { account: string; // Connected X username or account ID name?: string; // Display name description?: string; // Bio location?: string; // Location url?: string; // Website URL } ```