Nitter Cookie API vs OAuth API: Understanding the Authentication Variants
Nitter supports two distinct authentication mechanisms—Cookie sessions that transmit browser-style auth tokens to x.com, and OAuth 1.0a sessions that cryptographically sign requests for api.x.com—with both variants handled by the genHeaders function in src/apiutils.nim based on the SessionKind enum.
Nitter, the privacy-focused Twitter/X frontend maintained in the zedeus/nitter repository, provides dual authentication paths for accessing Twitter's private API. Understanding the difference between Nitter's Cookie API and OAuth API variants is critical for developers configuring instances or contributing to the codebase. While both methods ultimately invoke the same high-level API functions like fetch, they diverge significantly in credential storage, header construction, and endpoint targeting.
Core Authentication Mechanisms
Cookie-Based Sessions (SessionKind.cookie)
The Cookie API variant mimics browser authentication by transmitting session credentials directly to Twitter's web endpoints. In src/types.nim (lines 30-48), the cookie variant stores authToken and ct0 values within the Session record.
When constructing requests, the genHeaders function in src/apiutils.nim (lines 94-101) adds a cookie header containing auth_token and ct0 values. The function also injects the x-twitter-auth-type: OAuth2Session header and a CSRF token via x-csrf-token to satisfy Twitter's web client security requirements.
This variant targets https://x.com/i/api/... endpoints, as determined by the toUrl function's branch for SessionKind.cookie in src/apiutils.nim (lines 51-58).
OAuth 1.0a Sessions (SessionKind.oauth)
The OAuth API variant implements the OAuth 1.0a protocol, generating cryptographically signed Authorization headers using consumer key/secret pairs combined with user-specific OAuth tokens and secrets. The Session record stores these as oauthToken and oauthSecret fields according to the type definition in src/types.nim (lines 42-45).
In the genHeaders function, the SessionKind.oauth branch calls getOauthHeader to produce the signature, injecting the result as an authorization header. This variant communicates with https://api.x.com/... endpoints, selected by the toUrl function when processing OAuth sessions.
Implementation Architecture
The authentication abstraction centers on the SessionKind enum and the Session variant type defined in src/types.nim. The codebase remains agnostic to authentication method through unified wrappers:
fetchandfetchRaw: High-level API functions that accept anApiReqobject and internally delegate to the appropriate authentication logic based on the session type.
The toUrl function handles endpoint selection logic, routing cookie sessions to the x.com domain while directing OAuth traffic to api.x.com. This separation ensures that each authentication variant communicates with its expected Twitter API surface.
Practical Implementation Examples
Configuring a Cookie-Based Session
To authenticate using browser-extracted cookies, populate the Session object with kind: SessionKind.cookie and provide the extracted authToken and ct0 values:
import types, apiutils, api
let cookieReq = ApiReq(
cookie: ApiUrl(
endpoint: "1.1/statuses/user_timeline.json",
params: @[("screen_name", "example")]
),
oauth: ApiUrl(
endpoint: "1.1/statuses/user_timeline.json",
params: @[]
)
)
var sess = Session(
kind: SessionKind.cookie,
authToken: "YOUR_AUTH_TOKEN",
ct0: "YOUR_CT0"
)
let url = toUrl(cookieReq, sess.kind)
# Generates: https://x.com/i/api/1.1/statuses/user_timeline.json
let hdrs = await genHeaders(sess, url, skipTid = false)
let body = await fetch(cookieReq)
echo body
Configuring an OAuth 1.0a Session
For OAuth authentication, initialize the session with consumer credentials and user tokens, allowing getOauthHeader to generate the cryptographic signature:
import types, apiutils, api
let oauthReq = ApiReq(
oauth: ApiUrl(
endpoint: "1.1/statuses/user_timeline.json",
params: @[("screen_name", "example")]
),
cookie: ApiUrl(
endpoint: "1.1/statuses/user_timeline.json",
params: @[]
)
)
var sess = Session(
kind: SessionKind.oauth,
oauthToken: "USER_OAUTH_TOKEN",
oauthSecret: "USER_OAUTH_SECRET"
)
let url = toUrl(oauthReq, sess.kind)
# Generates: https://api.x.com/1.1/statuses/user_timeline.json
let hdrs = await genHeaders(sess, url, skipTid = false)
let body = await fetch(oauthReq)
echo body
Security and Rate Limiting Differences
Both authentication variants grant full account access if credentials are compromised, but they present different security surface areas. Cookie sessions require safeguarding auth_token and ct0 values extracted from browser sessions, while OAuth sessions protect consumer secrets and user-specific OAuth tokens.
Rate limiting implementations vary slightly between variants. Cookie sessions can optionally bypass the GraphQL "Tid" header (using authorization: bearerToken2) when the disableTid flag is set, whereas OAuth sessions consistently include the standard authorization: bearerToken header except when specifically targeting legacy /1.1/ endpoints.
Summary
- Cookie API: Uses
auth_tokenandct0cookies withx-twitter-auth-type: OAuth2Sessionandx-csrf-tokenheaders, targetinghttps://x.com/i/api/..., with implementation insrc/apiutils.nimlines 94-101. - OAuth API: Uses OAuth 1.0a signatures generated by
getOauthHeader, targetinghttps://api.x.com/..., with credentials stored inoauthTokenandoauthSecretfields persrc/types.nimlines 42-45. - Unified Interface: Both variants use the same
fetchandApiReqabstractions, switching behavior via theSessionKindenum. - Endpoint Separation: The
toUrlfunction insrc/apiutils.nim(lines 51-58) routes cookie traffic to x.com and OAuth traffic to api.x.com based on session type.
Frequently Asked Questions
Which authentication method should I use for my Nitter instance?
Choose the Cookie API when you have valid browser session tokens (auth_token and ct0) extracted from an authenticated Twitter session, as this mimics the official web client. Select the OAuth API when you possess OAuth 1.0a consumer credentials and user tokens, which provide standardized API access without requiring active browser sessions.
What files handle the authentication logic in Nitter?
The primary files are src/types.nim (defining the Session variant and SessionKind enum), src/apiutils.nim (implementing genHeaders and toUrl for header construction and endpoint selection), and src/auth.nim (managing the session pool and request routing).
Can I switch between Cookie and OAuth authentication without changing the API code?
Yes. The high-level API functions like fetch remain agnostic to the authentication method. You only need to change the Session object's kind field and corresponding credentials; the internal logic in genHeaders automatically selects the appropriate header construction and endpoint URL via toUrl.
How does Nitter handle rate limits differently for each authentication type?
Both variants respect Twitter's rate limits, but cookie sessions offer additional flexibility through the disableTid flag to bypass certain GraphQL headers. OAuth sessions maintain consistent authorization header patterns using bearerToken across all requests unless specifically targeting legacy 1.1 endpoints.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →