TLS API Examples: Twitter Guest Token Flow
Step-by-step guide to using the TLS API for Twitter guest and flow tokens
This guide provides a multi-step example of how to use the TLS API to perform a common flow: obtaining a guest token and flow token from api.x.com (Twitter).
This flow demonstrates how to:
- Make initial POST requests to get tokens
- Pass required authorization and client headers
- Use the output from one request (like the
guest_token) as an input for the next request
Step 1: Get Guest Token
This first request activates a guest session and returns a guest_token.
Request (POST /tls)
{
"url": "https://api.x.com/1.1/guest/activate.json",
"method": "POST",
"headers": {
"sec-ch-ua-platform": "\"Windows\"",
"authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
"sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"",
"x-twitter-client-language": "en",
"sec-ch-ua-mobile": "?0",
"x-twitter-active-user": "yes",
"x-client-transaction-id": "",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
"accept": "*/*",
"origin": "https://x.com",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://x.com/",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "en-US,en;q=0.9"
},
"timeout": 80,
"json": {}
}
Expected Output:
The response text will be a JSON string. Parse this string to extract the guest_token value.
Step 2: Get Flow Token
Using the guest_token from Step 1 in the headers, this request initiates a signup flow to get a flow_token.
Request (POST /tls)
{
"url": "https://api.x.com/1.1/onboarding/task.json?flow_name=signup",
"method": "POST",
"headers": {
"sec-ch-ua-platform": "\"Windows\"",
"authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
"sec-ch-ua": "\"Google Chrome\";v=\"141\", \"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"141\"",
"x-twitter-client-language": "en",
"sec-ch-ua-mobile": "?0",
"x-twitter-active-user": "yes",
"x-client-transaction-id": "",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
"accept": "*/*",
"origin": "https://x.com",
"sec-fetch-site": "same-site",
"x-guest-token": "<guest_token_from_step_1>",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://x.com/",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "en-US,en;q=0.9"
},
"timeout": 60,
"json": {
"input_flow_data": {
"flow_context": {
"debug_overrides": {},
"start_location": {
"location": "manual_link"
}
}
},
"subtask_versions": {
"action_list": 2,
"alert_dialog": 1,
"app_download_cta": 1,
"check_logged_in_account": 1,
"choice_selection": 3,
"contacts_live_sync_permission_prompt": 0,
"cta": 7,
"email_verification": 2,
"end_flow": 1,
"enter_date": 1,
"enter_email": 2,
"enter_password": 5,
"enter_phone": 2,
"enter_recaptcha": 1,
"enter_text": 5,
"enter_username": 2,
"generic_urt": 3,
"in_app_notification": 1,
"interest_picker": 3,
"js_instrumentation": 1,
"menu_dialog": 1,
"notifications_permission_prompt": 2,
"open_account": 2,
"open_home_timeline": 1,
"open_link": 1,
"phone_verification": 4,
"privacy_options": 1,
"security_key": 3,
"select_avatar": 4,
"select_banner": 2,
"settings_list": 7,
"show_code": 1,
"sign_up": 2,
"sign_up_review": 4,
"tweet_selection_urt": 1,
"update_users": 1,
"upload_media": 1,
"user_recommendations_list": 4,
"user_recommendations_urt": 1,
"wait_spinner": 3,
"web_modal": 1
}
}
}
Expected Output:
The response text will contain the new flow data. Parse this JSON to extract the flow_token.
Step 3: Begin Verification (Send Castle Token)
This request submits user details and a castle_token (which you must obtain separately) to proceed with verification, using both the guest_token and the flow_token.
Request (POST /tls)
{
"url": "https://api.x.com/1.1/onboarding/begin_verification.json",
"method": "POST",
"headers": {
"sec-ch-ua-platform": "\"Windows\"",
"authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
"sec-ch-ua": "\"Google Chrome\";v=\"142\", \"Not?A_Brand\";v=\"99\", \"Chromium\";v=\"142\"",
"x-twitter-client-language": "en",
"sec-ch-ua-mobile": "?0",
"x-twitter-active-user": "yes",
"x-client-transaction-id": "",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
"accept": "*/*",
"origin": "https://x.com",
"sec-fetch-site": "same-site",
"x-guest-token": "<guest_token_from_step_1>",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://x.com/",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": "<your_accept_lang>"
},
"timeout": 60,
"json": {
"email": "<YOUR_EMAIL>",
"display_name": "<YOUR_NAME>",
"castle_token": "<your_castle_token>",
"flow_token": "<flow_token_from_step_2>"
}
}
Expected Output: The response will contain verification results and next steps for onboarding.
Ready to use python script
import requests
import json
import random
import string
# Fake info generator
def generate_fake_email():
username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
domains = ['gmail.com', 'yahoo.com', 'outlook.com']
return f"{username}@{random.choice(domains)}"
def generate_fake_name():
first_names = ['John', 'Jane', 'Bob', 'Alice', 'Charlie', 'Diana', 'Eve', 'Frank', 'Grace', 'Henry']
last_names = ['Doe', 'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis', 'Wilson']
return random.choice(first_names) + ' ' + random.choice(last_names)
# Function to make TLS bypassed request via castlebreaker
def make_tls_request(target_url, method='POST', headers=None, json_data=None, proxy=None, timeout=60):
if headers is None:
headers = {}
tls_url = "https://castlebreaker.cc/tls"
tls_payload = {
"url": target_url,
"method": method,
"headers": headers,
"json": json_data or {}
}
if proxy:
tls_payload["proxy"] = proxy # Optional proxy support
response = requests.post(tls_url, json=tls_payload, timeout=timeout)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"TLS request failed: {response.status_code} - {response.text}")
# Main script
if __name__ == "__main__":
# Step 1: Fetch castle data
print("Fetching castle token...")
castle_url = "https://castlebreaker.cc/getCastleTokenProxyless"
castle_response = requests.get(castle_url)
castle_data = castle_response.json()
if castle_data.get('status') != 'success':
raise Exception("Failed to fetch castle token")
data = castle_data['data']
castle_token = data['castle_token']
accept_lang = data['accept_lang']
sec_ch_ua = data['sec_ch_ua']
user_agent = data['user_agent']
cid = data['cid'] # Not sure if needed, but captured
print(f"Castle token fetched: {castle_token[:20]}...")
# Base headers updated with castle data
base_headers = {
"sec-ch-ua-platform": "\"Windows\"",
"authorization": "Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA",
"sec-ch-ua": sec_ch_ua,
"x-twitter-client-language": "en",
"sec-ch-ua-mobile": "?0",
"x-twitter-active-user": "yes",
"x-client-transaction-id": "",
"user-agent": user_agent,
"accept": "*/*",
"origin": "https://x.com",
"sec-fetch-site": "same-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://x.com/",
"accept-encoding": "gzip, deflate, br, zstd",
"accept-language": accept_lang
}
# Step 2: Get guest token
print("Getting guest token...")
guest_url = "https://api.x.com/1.1/guest/activate.json"
guest_data = make_tls_request(guest_url, headers=base_headers, json_data={}, timeout=80)
guest_token = guest_data.get('guest_token')
if not guest_token:
raise Exception("Failed to get guest token")
print(f"Guest token: {guest_token}")
# Step 3: Get flow token
print("Getting flow token...")
flow_url = "https://api.x.com/1.1/onboarding/task.json?flow_name=signup"
flow_headers = base_headers.copy()
flow_headers["x-guest-token"] = guest_token
flow_json = {
"input_flow_data": {
"flow_context": {
"debug_overrides": {},
"start_location": {
"location": "manual_link"
}
}
},
"subtask_versions": {
"action_list": 2,
"alert_dialog": 1,
"app_download_cta": 1,
"check_logged_in_account": 1,
"choice_selection": 3,
"contacts_live_sync_permission_prompt": 0,
"cta": 7,
"email_verification": 2,
"end_flow": 1,
"enter_date": 1,
"enter_email": 2,
"enter_password": 5,
"enter_phone": 2,
"enter_recaptcha": 1,
"enter_text": 5,
"enter_username": 2,
"generic_urt": 3,
"in_app_notification": 1,
"interest_picker": 3,
"js_instrumentation": 1,
"menu_dialog": 1,
"notifications_permission_prompt": 2,
"open_account": 2,
"open_home_timeline": 1,
"open_link": 1,
"phone_verification": 4,
"privacy_options": 1,
"security_key": 3,
"select_avatar": 4,
"select_banner": 2,
"settings_list": 7,
"show_code": 1,
"sign_up": 2,
"sign_up_review": 4,
"tweet_selection_urt": 1,
"update_users": 1,
"upload_media": 1,
"user_recommendations_list": 4,
"user_recommendations_urt": 1,
"wait_spinner": 3,
"web_modal": 1
}
}
flow_data = make_tls_request(flow_url, headers=flow_headers, json_data=flow_json, timeout=60)
flow_token = flow_data.get('flow_token')
if not flow_token:
raise Exception("Failed to get flow token")
print(f"Flow token: {flow_token[:20]}...")
# Step 4: Generate fake info and send to begin verification
print("Generating fake info...")
fake_email = generate_fake_email()
fake_name = generate_fake_name()
print(f"Fake email: {fake_email}")
print(f"Fake name: {fake_name}")
verify_url = "https://api.x.com/1.1/onboarding/begin_verification.json"
verify_headers = base_headers.copy()
verify_headers["x-guest-token"] = guest_token
verify_json = {
"email": fake_email,
"display_name": fake_name,
"castle_token": castle_token,
"flow_token": flow_token
}
# Optional proxy - set proxy_var = "http://your-proxy:port" if needed, else None
proxy_var = None # Change this if you have a proxy
print("Sending verification request...")
verify_response = make_tls_request(verify_url, headers=verify_headers, json_data=verify_json, proxy=proxy_var, timeout=60)
print("Verification response:")
print(json.dumps(verify_response, indent=2))