Twitter API Client Libraries | JS and Python
Copy-paste minimal TwitterAPIs clients for JavaScript and Python, built on the bearer-token pattern, with retries and cursor pagination handled for you.
The API is plain HTTP and JSON, so you do not need a heavy SDK to use it. A thin client over fetch or requests gets you typed calls, automatic bearer auth, retry on the transient error classes, and a one-line pagination loop. Copy one of the clients below into your project and you are done.
One key, one header
Every method sends Authorization: Bearer <API_KEY> from an environment variable. Keep the key on your backend, never in browser code. See Authentication.
JavaScript / TypeScript
A single class with no dependencies beyond the built-in fetch. The search and userFollowers methods show single calls; paginate walks every page of any cursor-paginated endpoint.
// twitterapis.js
const BASE_URL = "https://api.twitterapis.com/twitter";
export class TwitterAPIs {
constructor(apiKey = process.env.TWITTERAPIS_KEY, baseUrl = BASE_URL) {
if (!apiKey) throw new Error("TWITTERAPIS_KEY is required");
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}
async get(path, params = {}) {
const url = new URL(`${this.baseUrl}/${path}`);
url.search = new URLSearchParams(params).toString();
for (let attempt = 0; attempt < 4; attempt++) {
const res = await fetch(url, {
headers: { Authorization: `Bearer ${this.apiKey}` },
});
if (res.ok) return res.json();
// Retry only the transient classes.
if (res.status === 429 || res.status >= 500) {
await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
continue;
}
const err = await res.json();
throw new Error(`${err.error}: ${err.message}`);
}
throw new Error("Exhausted retries");
}
// Walk every page of a cursor-paginated endpoint, yielding each item.
async *paginate(path, params, field) {
let cursor = "";
while (true) {
const data = await this.get(path, { ...params, cursor });
const items = data[field] ?? [];
// The empty collection is the universal stop signal.
if (items.length === 0) break;
for (const item of items) yield item;
// List and affiliate endpoints end with a null cursor; follower-graph
// endpoints keep returning one, so the empty check above stops them.
if (!data.next_cursor) break;
cursor = data.next_cursor;
}
}
search(query, product = "Latest") {
return this.get("tweet/advanced_search", { query, product });
}
userInfo(username) {
return this.get("user/info", { username });
}
userFollowers(username, cursor = "") {
return this.get("user/followers", { username, cursor });
}
}// usage
import { TwitterAPIs } from "./twitterapis.js";
const client = new TwitterAPIs();
// Single call.
const { tweets } = await client.search("from:naval min_faves:1000");
console.log(tweets.length);
// Page through every follower.
for await (const user of client.paginate("user/followers", { username: "naval" }, "users")) {
console.log(user.username);
}Python
A small class over requests, same shape: bearer auth, retry on 429 and 5xx, and a paginate generator.
# twitterapis.py
import os
import time
import requests
BASE_URL = "https://api.twitterapis.com/twitter"
class TwitterAPIs:
def __init__(self, api_key=None, base_url=BASE_URL):
self.api_key = api_key or os.environ["TWITTERAPIS_KEY"]
self.base_url = base_url
self.session = requests.Session()
self.session.headers["Authorization"] = f"Bearer {self.api_key}"
def get(self, path, **params):
for attempt in range(4):
res = self.session.get(f"{self.base_url}/{path}", params=params)
if res.ok:
return res.json()
# Retry only the transient classes.
if res.status_code == 429 or res.status_code >= 500:
time.sleep(2 ** attempt * 0.5)
continue
err = res.json()
raise RuntimeError(f"{err['error']}: {err['message']}")
raise RuntimeError("Exhausted retries")
def paginate(self, path, field, **params):
cursor = ""
while True:
data = self.get(path, cursor=cursor, **params)
items = data.get(field, [])
# The empty collection is the universal stop signal.
if not items:
break
yield from items
# List and affiliate endpoints end with a null cursor; follower-graph
# endpoints keep returning one, so the empty check above stops them.
if not data.get("next_cursor"):
break
cursor = data["next_cursor"]
def search(self, query, product="Latest"):
return self.get("tweet/advanced_search", query=query, product=product)
def user_info(self, username):
return self.get("user/info", username=username)
def user_followers(self, username, cursor=""):
return self.get("user/followers", username=username, cursor=cursor)# usage
from twitterapis import TwitterAPIs
client = TwitterAPIs()
# Single call.
tweets = client.search("from:naval min_faves:1000")["tweets"]
print(len(tweets))
# Page through every follower.
for user in client.paginate("user/followers", "users", username="naval"):
print(user["username"])Where to go next
Pagination
How the cursor model works under the paginate helpers above.
Errors
The status codes the retry logic branches on.
MCP Server
Skip the client entirely and call the API from your AI agent.
API Reference
Every endpoint these clients can call.
FAQ
Is there an official SDK package?
The API is simple enough that a thin client over fetch or requests is all you need. This page provides ready clients for JavaScript and Python to copy in.
What do the clients handle for me?
Bearer auth from an environment variable, retry on the transient 429 and 5xx classes, and a paginate helper that walks every page of any cursor endpoint.
Which languages are covered?
JavaScript or TypeScript over the built-in fetch, and Python over requests. Both follow the same shape so you can port between them easily.