+ Integration Guide
Twitter/X API with TypeScript: Complete Guide
How to search X/Twitter and scrape tweets using TypeScript with full type safety. Working examples with typed responses for every FetchLayer endpoint.
Written by Alex P.
- TypeScript
- twitter scraping
- X API
- Twitter API
- API integration
- type safety
This guide shows you how to use the FetchLayer Twitter/X API with TypeScript. You get full type safety on API responses with zero external dependencies.
If you want the official TypeScript package instead of defining the response types yourself, FetchLayer now ships @fetchlayer/twitter. It includes typed response interfaces for all 10 endpoints and is open source on GitHub.
Setup
- Get a free API key (no credit card)
- TypeScript 5+ and Node 18+ (or Bun/Deno)
Optional, if you want the official SDK with built-in endpoint types:
npm install @fetchlayer/twitter
Type Definitions
Define the response types for the endpoints you’ll use:
interface TwitterAuthor {
handle: string;
displayName: string;
isVerified: boolean;
followersCount?: number;
}
interface Tweet {
id: string;
text: string;
author: TwitterAuthor;
createdAt: string;
likeCount: number;
retweetCount: number;
replyCount: number;
quoteCount?: number;
viewCount?: number;
url: string;
lang?: string;
}
interface SearchResponse {
results: Tweet[];
cursor?: string;
}
interface TweetDetailResponse {
id: string;
text: string;
author: TwitterAuthor;
createdAt: string;
likeCount: number;
retweetCount: number;
replyCount: number;
quoteCount: number;
viewCount: number;
url: string;
lang: string;
}
interface TweetRepliesResponse {
replies: Tweet[];
cursor?: string;
}
interface UserProfile {
handle: string;
displayName: string;
description: string;
isVerified: boolean;
followersCount: number;
followingCount: number;
tweetsCount: number;
joinedAt: string;
location?: string;
website?: string;
avatarUrl: string;
bannerUrl?: string;
}
interface UserTweetsResponse {
tweets: Tweet[];
cursor?: string;
}
interface AccountEntry {
handle: string;
displayName: string;
isVerified: boolean;
followersCount: number;
description?: string;
}
interface FollowersResponse {
accounts: AccountEntry[];
cursor?: string;
}
Typed API Client
const API_KEY = process.env.FETCHLAYER_API_KEY!;
const BASE_URL = 'https://api.fetchlayer.dev/twitter';
async function twitter<T>(endpoint: string, body: Record<string, unknown>): Promise<T> {
const res = await fetch(`${BASE_URL}/${endpoint}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!res.ok) {
throw new Error(`FetchLayer ${res.status}: ${await res.text()}`);
}
return res.json() as Promise<T>;
}
Search Twitter/X
const data = await twitter<SearchResponse>('search', {
query: 'best CI/CD tools',
product: 'Top',
count: 10,
});
// Full type safety — TypeScript knows data.results is Tweet[]
for (const tweet of data.results) {
console.log(`[${tweet.likeCount} likes] @${tweet.author.handle}: ${tweet.text.slice(0, 100)}`);
}
// Paginate
if (data.cursor) {
const page2 = await twitter<SearchResponse>('search', {
query: 'best CI/CD tools',
product: 'Top',
count: 10,
cursor: data.cursor,
});
}
Get a Tweet by ID
const tweet = await twitter<TweetDetailResponse>('tweet-detail', {
tweetId: '1942939879222220800',
});
console.log(`@${tweet.author.handle} (${tweet.author.followersCount?.toLocaleString()} followers)`);
console.log(`${tweet.likeCount} likes · ${tweet.retweetCount} retweets · ${tweet.replyCount} replies`);
Get Replies to a Tweet
const data = await twitter<TweetRepliesResponse>('tweet-replies', {
tweetId: '1942939879222220800',
});
const highEngagementReplies = data.replies.filter(r => (r.likeCount ?? 0) > 10);
console.log(`${highEngagementReplies.length} replies with 10+ likes`);
Get a User Profile
const profile = await twitter<UserProfile>('user-profile-details', {
handle: 'openai',
});
console.log(`${profile.displayName} (@${profile.handle})`);
console.log(`Followers: ${profile.followersCount.toLocaleString()}`);
console.log(`Joined: ${new Date(profile.joinedAt).getFullYear()}`);
console.log(`Bio: ${profile.description}`);
Get a User’s Tweets
const data = await twitter<UserTweetsResponse>('user-tweets', {
handle: 'rauchg',
count: 20,
});
const topTweets = (data.tweets ?? [])
.sort((a, b) => (b.likeCount ?? 0) - (a.likeCount ?? 0))
.slice(0, 5);
for (const tweet of topTweets) {
console.log(`[${tweet.likeCount} likes] ${tweet.text.slice(0, 120)}`);
}
Get Followers and Following
// Who a user follows
const following = await twitter<FollowersResponse>('following', {
handle: 'openai',
count: 50,
});
for (const account of following.accounts ?? []) {
console.log(`@${account.handle} — ${account.followersCount.toLocaleString()} followers`);
}
// Verified followers
const verified = await twitter<FollowersResponse>('verified-followers', {
handle: 'openai',
count: 20,
});
console.log(`${verified.accounts?.length ?? 0} verified followers`);
Full Example: Audience Analysis
async function analyzeAudience(handle: string) {
const profile = await twitter<UserProfile>('user-profile-details', { handle });
// Get recent tweets and their engagement
const tweets = await twitter<UserTweetsResponse>('user-tweets', { handle, count: 50 });
const avgLikes = (tweets.tweets ?? []).reduce((sum, t) => sum + (t.likeCount ?? 0), 0) / (tweets.tweets?.length || 1);
const avgRetweets = (tweets.tweets ?? []).reduce((sum, t) => sum + (t.retweetCount ?? 0), 0) / (tweets.tweets?.length || 1);
console.log(`${profile.displayName} (@${profile.handle})`);
console.log(`Followers: ${profile.followersCount.toLocaleString()}`);
console.log(`Avg engagement: ${avgLikes.toFixed(0)} likes, ${avgRetweets.toFixed(0)} retweets per tweet`);
console.log(`Engagement rate: ${((avgLikes / profile.followersCount) * 100).toFixed(2)}%`);
}
analyzeAudience(process.argv[2] || 'openai');
What’s Next
- Twitter API with Python — Python version
- Twitter API with Node.js — JavaScript/Node version
- Twitter API with Bun — Bun runtime version
- Twitter API with Go — Go integration
- How to Scrape Twitter/X in 2026 — all scraping methods
- FetchLayer API Reference