Support/Proxy Guides
Proxy Guides

Proxying Flowsery Analytics with FastAPI

Route Flowsery Analytics through your FastAPI server to prevent adblocker interference and capture more accurate visitor data.

1. Install Dependencies

Terminal
pip install fastapi uvicorn httpx

2. Set Up the Proxy

Add the following to your FastAPI application:

Python
from fastapi import FastAPI, Request
from fastapi.responses import Response
import httpx
 
app = FastAPI()
 
def get_client_ip(request: Request) -> str:
    """Resolve the actual visitor IP address"""
    # Prefer Cloudflare's CF-Connecting-IP if available
    if cf_connecting_ip := request.headers.get("cf-connecting-ip"):
        return cf_connecting_ip
 
    # Then X-Real-IP
    if x_real_ip := request.headers.get("x-real-ip"):
        return x_real_ip
 
    # Fall back to X-Forwarded-For (first entry)
    if x_forwarded_for := request.headers.get("x-forwarded-for"):
        return x_forwarded_for.split(",")[0].strip()
 
    # Last resort: direct connection host
    return request.client.host if request.client else ""
 
@app.get("/js/main.js")
async def proxy_script():
    async with httpx.AsyncClient() as client:
        response = await client.get('https://cdn.flowsery.com/main.js')
        return Response(
            content=response.content,
            media_type='application/javascript',
            headers={
                'Cache-Control': 'public, max-age=31536000'
            }
        )
 
@app.post("/api/track")
async def proxy_events(request: Request):
    body = await request.json()
 
    # Determine the origin from the request or construct it from the base URL
    origin = request.headers.get('origin') or str(request.base_url).rstrip('/')
 
    # Resolve visitor IP for accurate geolocation
    client_ip = get_client_ip(request)
 
    async with httpx.AsyncClient() as client:
        headers = {
            'Content-Type': 'application/json',
            'User-Agent': request.headers.get('user-agent'),
            'Origin': origin,
            'x-forwarded-for': client_ip
        }
 
        if client_ip:
            # CRITICAL: Flowsery reads this as the authoritative visitor IP. Without it, every visitor resolves to your server's region.
            headers['x-flowsery-real-ip'] = client_ip
 
        response = await client.post(
            'https://analytics.flowsery.com/analytics/events',
            json=body,
            headers=headers
        )
        return Response(
            content=response.content,
            media_type='application/json',
            status_code=response.status_code
        )
 
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

Note: If your application already has an /api/track endpoint, use the data-api attribute on the Flowsery Analytics script tag to direct events to a different path. For example, data-api="/flowsery-events" sends data to /flowsery-events instead.

Important: If every visitor appears to be in the same location in your dashboard, confirm that the x-flowsery-real-ip header is being set to the real visitor IP (not the proxy server IP) when forwarding requests to the Flowsery Analytics /events endpoint. If FastAPI sits behind another proxy (Cloudflare, Vercel, etc.), request.client.host will be the upstream proxy — read cf-connecting-ip or x-real-ip directly instead.

3. Modify the Script Tag

Replace the original Flowsery Analytics snippet with the proxied version:

HTML
<script defer data-fl-website-id="flid_******" src="/js/main.js"></script>

4. Deploy

After deploying your server, the proxy configuration activates automatically.

Confirming It Works

To validate that the proxy is functioning correctly:

  1. Navigate to your website
  2. Open your browser's developer tools and switch to the Network tab
  3. Verify that analytics requests are served from your domain rather than analytics.flowsery.com