Overview
Gateway Mode transforms APITHON from a passive protocol analyzer into an active API gateway. After successful Session Synchronization , APITHON launches a Flask web server that accepts standard OpenAI-compatible API requests and translates them into the target service’s internal protocol.
What Gateway Mode Does
Gateway Mode provides:
Protocol Translation Converts OpenAI /v1/chat/completions format to the target’s internal streaming protocol
Authentication Layer Implements Bearer token authentication to secure gateway access
Network Flexibility Supports both localhost-only and LAN-wide deployment modes
Cross-Platform CLI Generates platform-specific curl commands for Windows (PowerShell/CMD) and Linux (Bash)
Flask Server Architecture
APItHON uses Flask as a lightweight HTTP server framework:
from flask import Flask, request, jsonify
app = Flask( __name__ )
API_KEY_GATEWAY = "UnHackerEnCapital"
The Gateway Endpoint
The core endpoint is defined at line 132 in apithon.py:
@app.route ( '/v1/chat/completions' , methods = [ 'POST' ])
def apithon_gateway ():
auth_header = request.headers.get( "Authorization" )
if auth_header != f "Bearer { API_KEY_GATEWAY } " :
return jsonify({ "error" : "Unauthorized" }), 401
user_input = request.json.get( "messages" , [{}])[ - 1 ].get( "content" , "" )
output_text = ejecutar_request_protocolo(user_input)
return jsonify({
"choices" : [{
"message" : {
"role" : "assistant" ,
"content" : output_text
}
}],
"model" : "apithon-v3"
})
Endpoint Breakdown
Route : /v1/chat/completions
Method : POST
Purpose : OpenAI-compatible chat completion endpoint
Authentication Check
Validates the Authorization header contains the correct Bearer token. if auth_header != f "Bearer { API_KEY_GATEWAY } " :
return jsonify({ "error" : "Unauthorized" }), 401
Message Extraction
Extracts the user’s message content from the OpenAI-style request body. user_input = request.json.get( "messages" , [{}])[ - 1 ].get( "content" , "" )
Protocol Execution
Calls ejecutar_request_protocolo() to send the message via the captured protocol.
Response Formatting
Wraps the response in OpenAI-compatible JSON structure.
Request Execution Logic
The ejecutar_request_protocolo function (lines 103-129) handles the actual protocol translation:
def ejecutar_request_protocolo ( user_query ):
base_domain = urllib.parse.urlparse( SESS [ "target_url" ]).netloc
backend_endpoint = (
f "https:// { base_domain } /_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate"
f "?bl= { SESS [ 'build_id' ] } &f.sid= { SESS [ 'session_id' ] } &hl=es-419&_reqid=2202684&rt=c"
)
headers = {
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36" ,
"Cookie" : SESS [ "auth_cookie" ],
"Content-Type" : "application/x-www-form-urlencoded;charset=UTF-8" ,
"X-Same-Domain" : "1" ,
"Origin" : f "https:// { base_domain } " ,
"Referer" : f "https:// { base_domain } /"
}
inner_structure = [
[user_query, 0 , None , None , None , None , 0 ],
[ "es-419" ],
[ "" , "" , "" , None , None , None , None , None , None , "" ],
SESS [ "internal_context" ],
"eb594bcd367d878b1514dd3b7c68bb91"
]
payload = { "f.req" : json.dumps([ None , json.dumps(inner_structure)]), "at" : "" }
try :
r = requests.post(backend_endpoint, headers = headers, data = payload, impersonate = "chrome120" )
patterns = re.findall( r 'rc_ [ a-z0-9 ] + . *? \[\\ " ( . *? ) \\ " \] ' , r.text)
if patterns:
return patterns[ - 1 ].replace( ' \\\\ n' , ' \n ' ).replace( ' \\ n' , ' \n ' ).replace( ' \\ "' , '"' )
return "Aviso: Flujo de datos vacío."
except Exception as e:
return f "Error en el túnel: { str (e) } "
Endpoint Construction
The backend URL is dynamically constructed using captured tokens:
backend_endpoint = (
f "https:// { base_domain } /_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate"
f "?bl= { SESS [ 'build_id' ] } &f.sid= { SESS [ 'session_id' ] } &hl=es-419&_reqid=2202684&rt=c"
)
Parameters:
bl: Build ID (captured during synchronization)
f.sid: Session ID (captured during synchronization)
hl: Language hint (hardcoded to Spanish)
_reqid: Request ID (static for simplicity)
rt: Request type (“c” for chat)
Critical headers for protocol compatibility:
User-Agent
Cookie
Content-Type
X-Same-Domain
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36"
The X-Same-Domain header is critical for bypassing CSRF protections that expect same-origin requests.
Payload Structure
The request payload follows a nested JSON structure:
inner_structure = [
[user_query, 0 , None , None , None , None , 0 ], # Message with metadata
[ "es-419" ], # Language code
[ "" , "" , "" , None , None , None , None , None , None , "" ], # Optional parameters
SESS [ "internal_context" ], # Critical: conversation context
"eb594bcd367d878b1514dd3b7c68bb91" # Protocol version/checksum
]
payload = { "f.req" : json.dumps([ None , json.dumps(inner_structure)]), "at" : "" }
Key Components:
User query in first position of first array
Language code for response formatting
Empty optional parameter array
Internal context token (maintains conversation state)
Static protocol identifier
The internal_context token is the most critical element. Without it, the backend cannot maintain conversation continuity.
TLS Fingerprinting
APItHON uses curl_cffi with Chrome 120 impersonation:
from curl_cffi import requests
r = requests.post(backend_endpoint, headers = headers, data = payload, impersonate = "chrome120" )
This mimics Chrome’s TLS fingerprint, helping avoid detection as a bot or automation tool.
Response Parsing
The backend response is parsed using regex to extract the assistant’s message:
patterns = re.findall( r 'rc_ [ a-z0-9 ] + . *? \[\\ " ( . *? ) \\ " \] ' , r.text)
if patterns:
return patterns[ - 1 ].replace( ' \\\\ n' , ' \n ' ).replace( ' \\ n' , ' \n ' ).replace( ' \\ "' , '"' )
Pattern Explanation:
rc_[a-z0-9]+: Matches response chunk identifiers
.*?\[\\"(.*?)\\"\]: Captures content between escaped quotes in JSON array
Uses last match (most recent/complete response)
Unescapes newlines and quotes
The gateway accepts standard OpenAI API request format:
{
"messages" : [
{
"role" : "user" ,
"content" : "Your message here"
}
]
}
And returns OpenAI-compatible responses:
{
"choices" : [
{
"message" : {
"role" : "assistant" ,
"content" : "Response from the target LLM"
}
}
],
"model" : "apithon-v3"
}
This compatibility allows APITHON to work with any tool or library that supports the OpenAI API format, such as LangChain, LlamaIndex, or custom applications.
Authentication with API_KEY_GATEWAY
Gateway access is protected by Bearer token authentication:
API_KEY_GATEWAY = "UnHackerEnCapital"
auth_header = request.headers.get( "Authorization" )
if auth_header != f "Bearer { API_KEY_GATEWAY } " :
return jsonify({ "error" : "Unauthorized" }), 401
Default Key : UnHackerEnCapital
Security Recommendation : Change the API_KEY_GATEWAY value before deploying in production or LAN mode. The default key is publicly known.
Usage Example
curl http://localhost:5000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer UnHackerEnCapital" \
-d '{"messages": [{"role": "user", "content": "Hello"}]}'
Network Deployment Modes
Gateway Mode supports two network configurations:
Local Mode (Localhost)
Restricts access to the current machine only:
def run_gateway_service ( bind_all = False ):
host = "0.0.0.0" if bind_all else "127.0.0.1"
# ...
app.run( host = host, port = 5000 , debug = False , use_reloader = False )
When bind_all=False:
Binds to 127.0.0.1
Only accessible from localhost
Ideal for personal use and testing
Use Case: Local Development Perfect for testing integrations or using APITHON as a personal proxy for LLM services without exposing it to your network.
LAN Mode (Network-Wide)
Exposes the gateway to all devices on the local network:
When bind_all=True:
Binds to 0.0.0.0 (all network interfaces)
Accessible from any device on the LAN
Automatically detects and displays LAN IP address
def get_lan_ip ():
try :
s = socket.socket(socket. AF_INET , socket. SOCK_DGRAM )
s.connect(( "8.8.8.8" , 80 ))
ip = s.getsockname()[ 0 ]
s.close()
return ip
except Exception :
return "127.0.0.1"
Use Case: Multi-Device Access Share gateway access across multiple devices (laptops, tablets, smartphones) without installing APITHON on each one.
Security Notice : LAN mode exposes the gateway to all devices on your network. Ensure your network is trusted and consider changing the default API key.
Dynamic Tutorial Generation
APItHON automatically generates platform-specific usage instructions:
def mostrar_tutorial ( host_ip ):
es_windows = platform.system() == "Windows"
# ... prints tutorial ...
The tutorial adapts based on the operating system:
PowerShell (Windows)
CMD (Windows)
Bash (Linux/Mac)
curl.exe http: // 192.168 . 1.100 : 5000 / v1 / chat / completions - H "Content-Type: application/json" - H "Authorization: Bearer UnHackerEnCapital" - d "{\" messages\ ": [{\" role\ ": \" user\ ", \" content\ ": \" Hello\ "}]}"
Uses curl.exe to avoid PowerShell’s Invoke-WebRequest alias and specific quote escaping. curl http:// 192.168.1.100 : 5000 / v1 / chat / completions - H "Content-Type: application/json" - H "Authorization: Bearer UnHackerEnCapital" - d "{\" messages \ ": [{\" role \ ": \" user \ ", \" content \ ": \" Hello \ "}]}"
Standard Windows CMD syntax with escaped quotes. curl http://192.168.1.100:5000/v1/chat/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer UnHackerEnCapital' \
-d '{"messages": [{"role": "user", "content": "Hello"}]}'
Uses single quotes for JSON and line continuation backslashes.
Gateway Lifecycle
The gateway runs in a dedicated thread:
threading.Thread( target = run_gateway_service, args = ( False ,), daemon = True ).start()
print ( " \n [MANTENIENDO PASARELA... Ctrl+C para cerrar]" )
while True :
time.sleep( 1 )
Runs as a daemon thread (terminates when main thread exits)
Keeps the main thread alive with an infinite sleep loop
User must press Ctrl+C to stop
Error Handling
Authentication Failure
if auth_header != f "Bearer { API_KEY_GATEWAY } " :
return jsonify({ "error" : "Unauthorized" }), 401
Returns HTTP 401 with error message.
Protocol Execution Failure
try :
r = requests.post(backend_endpoint, headers = headers, data = payload, impersonate = "chrome120" )
# ...
except Exception as e:
return f "Error en el túnel: { str (e) } "
Captures and returns exception details to the client.
Empty Response
if patterns:
return patterns[ - 1 ].replace( ' \\\\ n' , ' \n ' ).replace( ' \\ n' , ' \n ' ).replace( ' \\ "' , '"' )
return "Aviso: Flujo de datos vacío."
Returns a warning message if no response content is found.
Diagram: Gateway Request Flow
Integration Examples
Python with Requests
import requests
response = requests.post(
"http://localhost:5000/v1/chat/completions" ,
headers = {
"Content-Type" : "application/json" ,
"Authorization" : "Bearer UnHackerEnCapital"
},
json = {
"messages" : [
{ "role" : "user" , "content" : "What is protocol interception?" }
]
}
)
print (response.json()[ "choices" ][ 0 ][ "message" ][ "content" ])
JavaScript with Fetch
fetch ( 'http://localhost:5000/v1/chat/completions' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : 'Bearer UnHackerEnCapital'
},
body: JSON . stringify ({
messages: [
{ role: 'user' , content: 'Explain gateway mode' }
]
})
})
. then ( res => res . json ())
. then ( data => console . log ( data . choices [ 0 ]. message . content ));
Next Steps
Now that you understand Gateway Mode, explore how to use it in practice:
Quickstart Guide Follow the step-by-step guide to set up and run APITHON
Protocol Interception Deep dive into how tokens are captured
Session Synchronization Learn about the validation process
API Reference Complete API documentation and examples