TwitterAPIs Docs
Getting Started

Twitter Write Sessions | Post as Your X Account

Register your own X session once, then run write actions (like, retweet, bookmark, follow) that post as your account.

Read endpoints pull public data and need nothing but your API key. Write endpoints are different. A like, a retweet, a bookmark, or a follow has to belong to a real X account, and TwitterAPIs runs every write as your account, not a shared pool. So before you can write, you register your X session once. After that, the write endpoints act as you until that session expires.

Why writes need a session

A read call asks X a public question, so any account can ask it. A write call changes state on a specific account: it adds a like to your timeline, a follow to your graph, a bookmark to your list. There is no way to do that anonymously, and we will not borrow someone else's account to do it for you. The write has to run as the account it affects.

That account is yours. You hand us your X session once, we attach it to your API key, and from then on a write call posts as your account. Reads are unaffected and keep working with just the bearer token.

Writes are billed per call

Most successful writes cost $0.0008, the same as a standard read; posting a new tweet (tweet/create) is $0.0016. A write that fails before it reaches X (for example a session_required rejection) is not billed.

What a session is

Your X session is two cookies from a logged-in x.com browser tab: auth_token and ct0. Together they identify your account to X the same way your browser does. You read them once and register them with TwitterAPIs, and we use them to sign your write calls.

The supported documented way to obtain a session is to bring your own cookies.

  • Bring your own cookies. Copy auth_token and ct0 from a logged-in x.com tab and register them via POST /twitter/customer/session. This is reliable, instant, and works on every account type.

For anything you want to run on a schedule, register cookies.

Reading your cookies

In a logged-in x.com tab, open your browser dev tools, go to the Application (or Storage) panel, and find Cookies for https://x.com. Copy the values of auth_token and ct0. Treat both like passwords: anyone holding them can act as your account.

Register your session

Send the two cookies as a JSON body to POST /twitter/customer/session, authenticated with your API key. You register once; the session stays attached to your key until it expires.

const res = await fetch("https://api.twitterapis.com/twitter/customer/session", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TWITTERAPIS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    auth_token: process.env.X_AUTH_TOKEN,
    ct0: process.env.X_CT0,
  }),
});

if (!res.ok) {
  const err = await res.json();
  throw new Error(`${err.error}: ${err.message}`);
}

console.log("Session registered. Write endpoints now act as your account.");
import os
import requests

res = requests.post(
    "https://api.twitterapis.com/twitter/customer/session",
    headers={"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"},
    json={
        "auth_token": os.environ["X_AUTH_TOKEN"],
        "ct0": os.environ["X_CT0"],
    },
)
res.raise_for_status()
print("Session registered. Write endpoints now act as your account.")

Register from your backend only

The cookies grant full control of your X account. Send them from a server you control, store them in environment variables or a secret manager, and never put them in browser code or a committed file.

Run a write

Once the session is registered, the write endpoints take your API key as usual and act as your account. Here is a favorite (like) on a tweet by its ID.

const res = await fetch("https://api.twitterapis.com/twitter/tweet/favorite", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TWITTERAPIS_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ tweet_id: "1759123456789012345" }),
});

const data = await res.json();
console.log(data);
import os
import requests

res = requests.post(
    "https://api.twitterapis.com/twitter/tweet/favorite",
    headers={"Authorization": f"Bearer {os.environ['TWITTERAPIS_KEY']}"},
    json={"tweet_id": "1759123456789012345"},
)
print(res.json())

The same pattern covers every write action. Each takes your API key, runs as your registered account, and returns the standard {error, message} envelope on failure.

EndpointAction
POST /twitter/tweet/favoriteLike a tweet
POST /twitter/tweet/unfavoriteRemove a like
POST /twitter/tweet/retweetRetweet
POST /twitter/tweet/unretweetUndo a retweet
POST /twitter/tweet/bookmarkBookmark a tweet
POST /twitter/tweet/unbookmarkRemove a bookmark
POST /twitter/user/followFollow a user
POST /twitter/user/unfollowUnfollow a user

If you skip registration

A write call before you have registered a session returns 409 with session_required. It means the request was valid but there is no account attached to your key yet. Register via POST /twitter/customer/session, then retry the same call.

{
  "error": "session_required",
  "message": "No X session is registered for this API key. Register one via POST /twitter/customer/session before writing."
}

This response is not billed. Branch on the error field, register the session, and retry.

When a session goes dead

X sessions do not last forever. Logging out of that x.com tab, a password change, or X expiring the cookies will invalidate the session you registered. When that happens, a write returns 401 with a session-dead error: the key is fine, but the X account behind it can no longer act.

{
  "error": "session_dead",
  "message": "The registered X session is no longer valid. Re-register fresh cookies via POST /twitter/customer/session."
}

Recover by reading fresh auth_token and ct0 cookies from a logged-in tab and registering them again at POST /twitter/customer/session. The new session replaces the old one and writes resume.

Build for re-registration

Treat session death as a normal event, not an outage. Catch session_dead on writes, alert whoever owns the account, and re-register. A scheduled job that does writes should expect to refresh its session periodically.

Where to go next

FAQ

Why do writes need a session?

A write changes state on a specific account: a like, a follow, a bookmark. It must run as that account, so you register your own X session first.

What is an X session here?

Two cookies from a logged-in x.com tab: auth_token and ct0. Register them via POST /twitter/customer/session. Treat both like passwords.

What happens when a session expires?

A write returns 401 with session_dead. Read fresh auth_token and ct0 cookies and re-register them. The new session replaces the old one.

On this page