Getting Started
Errors
HTTP status codes TwitterAPIs returns, the JSON error shape, and how to handle each one in your client.
TwitterAPIs uses standard HTTP status codes. A 2xx means the call worked. Anything else carries a JSON error body that tells you what went wrong. Read the status code first, then the body.
Status codes
| Code | Meaning | What to do |
|---|---|---|
200 | Success | Parse the JSON body. The data is ready. |
400 | Bad request | A parameter is missing or malformed. Fix the request before retrying. |
401 | Unauthorized | The API key is missing, malformed, or revoked. Check the Authorization header. |
402 | Insufficient credits | Your balance is exhausted. Top up in the dashboard, then retry. |
404 | Not found | The resource does not exist, for example a deleted tweet or a private account. |
429 | Rate limited | You are sending requests too fast. Back off, then retry. See Rate limits. |
5xx | Server error | Something failed on our side. Retry with backoff. If it persists, contact support. |
Error shape
Every non-2xx response uses the same JSON envelope, so you can parse errors with one code path:
{
"status": "error",
"code": 402,
"message": "Insufficient credits. Top up your balance to continue."
}| Field | Type | Description |
|---|---|---|
status | string | Always "error" on a failed call. |
code | number | Mirrors the HTTP status code. |
message | string | A human-readable explanation of the failure. |
Handling errors
Branch on the status code. Retry the transient classes (429 and 5xx) with exponential backoff, and surface the rest to the caller because a human needs to act.
async function call(url) {
for (let attempt = 0; attempt < 4; attempt++) {
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.TWITTERAPIS_KEY}` },
});
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;
}
// 400, 401, 402, 404 need a human, not a retry.
const err = await res.json();
throw new Error(`${err.code}: ${err.message}`);
}
throw new Error("Exhausted retries");
}import os
import time
import requests
def call(url):
for attempt in range(4):
res = requests.get(
url,
headers={"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"},
)
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
# 400, 401, 402, 404 need a human, not a retry.
err = res.json()
raise RuntimeError(f"{err['code']}: {err['message']}")
raise RuntimeError("Exhausted retries")A 402 is not a bug
402 Insufficient credits means the request was valid but your balance ran out. Add credits in the dashboard and the same request will succeed.