Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.corti.ai/llms.txt

Use this file to discover all available pages before exploring further.

When the Corti Assistant is embedded in a host application, all network traffic from the embedded app may be routed through a proxy controlled by the host application. The proxy sits between the client and the Corti backend services.
Host application
  └── Embedded Corti Assistant
       ├── HTTP requests  → Proxy → Corti web app
       └── WebSocket       → Proxy → Corti WebSocket backend
The Corti web app already proxies all third-party service traffic (analytics, feature flags) server-side through its own API routes. This means the proxy only needs to handle two types of traffic:
  1. HTTP requests to the Corti web app
  2. WebSocket connections to the Corti real-time backend

Upstream URLs

The proxy forwards traffic to two upstream services. The exact URLs depend on your region:
RegionCorti web appWebSocket backend
EUhttps://assistant.eu.corti.appwss://api.eu.corti.app
EU MDhttps://assistantmd.eu.corti.appwss://api.eu.corti.app
UShttps://assistant.us.corti.appwss://api.us.corti.app
Use the URLs that match the region your Corti tenant is provisioned in. Contact support if you are unsure which region applies.

Choose a Proxy Mode

Configure your proxy in one of two ways. Use the same mode consistently for the iframe URL, HTTP routing, and WebSocket routing.
ModePublic Assistant URLHTTP request sent to Corti web appPrefix headerPublic WebSocket URL
Proxy root (without path)https://proxy.example.com/embedded/embeddedDo not set Corti-Forwarded-Prefixwss://proxy.example.com/audio-bridge/*
Proxy subpath (with path)https://proxy.example.com/assistant/embedded/assistant/embeddedSet Corti-Forwarded-Prefix: /assistantwss://proxy.example.com/assistant/audio-bridge/*
For subpath deployments, /assistant is only an example. You can choose any external path prefix, such as /corti-assistant or /vendor/corti, as long as your proxy forwards HTTP requests with that prefix intact and sends the same value in Corti-Forwarded-Prefix.

HTTP Request Forwarding

All HTTP requests from the embedded app are forwarded to a single upstream — the Corti web app.

Proxy root (without path)

When Corti Assistant is hosted at the proxy root, forward the request path unchanged and do not set Corti-Forwarded-Prefix.
Client → https://proxy.example.com/* → https://assistant.eu.corti.app/*
No path rewriting is needed. The proxy passes through the full request path, query string, method, and body unchanged.

Proxy subpath (with path)

If you host the embedded app under a subpath (for example https://proxy.example.com/assistant/), forward the public prefixed HTTP path to the Corti web app unchanged and set Corti-Forwarded-Prefix to the external base path.
Client → https://proxy.example.com/assistant/embedded
      → https://assistant.eu.corti.app/assistant/embedded
Do not strip the subpath before forwarding HTTP requests to the Corti web app. The Corti Assistant runtime base path shim strips the prefix internally and rewrites response URLs so browser requests continue to stay under the public subpath.
X-Forwarded-Prefix is not the supported external contract for Corti Assistant subpath hosting. Use Corti-Forwarded-Prefix.

Required Headers

The proxy must set the following headers on every HTTP request forwarded to the Corti web app:
HeaderValueExample
Corti-Forwarded-ForThe original client IP, or a trusted client IP chain maintained by proxy.192.168.1.100
Corti-Forwarded-HostThe Host header as seen by the proxy (the proxy’s own hostname).proxy.example.com
Corti-Forwarded-ProtoThe protocol used between the client and the proxy.https
If you host the embedded app under a subpath, also set:
HeaderValueExample
Corti-Forwarded-PrefixThe external base path used for subpath hosting./assistant
Corti may translate these headers into standard X-Forwarded-* headers inside Corti-controlled infrastructure. Customer proxies should use the Corti-Forwarded-* headers documented here.
In production, set Corti-Forwarded-Host from a normalized or fixed proxy hostname. If your proxy runs behind another trusted load balancer, configure your proxy’s real IP handling before setting Corti-Forwarded-For.
Example — forwarding a request: Proxy root, without path:
# Original request from client
GET https://proxy.example.com/api/interactions HTTP/1.1
Host: proxy.example.com

# Forwarded to upstream
GET https://assistant.eu.corti.app/api/interactions HTTP/1.1
Host: assistant.eu.corti.app
Corti-Forwarded-For: 192.168.1.100
Corti-Forwarded-Host: proxy.example.com
Corti-Forwarded-Proto: https
Proxy subpath, with path:
# Original request from client
GET https://proxy.example.com/assistant/api/interactions HTTP/1.1
Host: proxy.example.com

# Forwarded to upstream
GET https://assistant.eu.corti.app/assistant/api/interactions HTTP/1.1
Host: assistant.eu.corti.app
Corti-Forwarded-For: 192.168.1.100
Corti-Forwarded-Host: proxy.example.com
Corti-Forwarded-Proto: https
Corti-Forwarded-Prefix: /assistant

Response Handling

Your proxy returns the upstream response to the client as-is. No modification of status codes, headers, or body is required in your proxy. For subpath deployments, the Corti web app runtime base path shim handles its own URL rewriting before the response reaches your proxy.

WebSocket Forwarding

The Corti Assistant uses WebSocket connections for real-time audio streaming and clinical sessions. The proxy must handle the HTTP Upgrade: websocket handshake and bidirectionally forward all WebSocket frames.

Routing

The Corti WebSocket backend expects the /audio-bridge/ path prefix. For proxy-root deployments, the public WebSocket path is forwarded unchanged:
wss://proxy.example.com/audio-bridge/* → wss://<websocket-backend>/audio-bridge/*
The path and query string are preserved when forwarding. For example:
wss://proxy.example.com/audio-bridge/v1/transcribe?token=Bearer%20abc123
  → wss://api.eu.corti.app/audio-bridge/v1/transcribe?token=Bearer%20abc123
For subpath deployments, the public WebSocket path includes the same prefix as the iframe URL. Strip that prefix before forwarding to the WebSocket backend:
wss://proxy.example.com/assistant/audio-bridge/v1/transcribe?token=Bearer%20abc123
  → wss://api.eu.corti.app/audio-bridge/v1/transcribe?token=Bearer%20abc123
Corti-Forwarded-Prefix is used by the Corti web app. The WebSocket backend still expects /audio-bridge/* paths.

Connection Lifecycle

  1. Upgrade — When the proxy receives a request with Upgrade: websocket, it establishes a WebSocket connection to the appropriate upstream based on the path.
  2. Message forwarding — All messages (text and binary) are forwarded bidirectionally between the client and upstream. Messages sent by the client before the upstream connection is established should be buffered and flushed once the upstream is ready.
  3. Close — When either side closes the connection, the proxy closes the other side.
  4. Idle timeout — WebSocket connections can be long-lived. Set the idle timeout high enough to avoid dropping active audio sessions (recommended: at least 4 minutes).

Client-Side Configuration

HTTP requests do not require any client-side configuration. Because the embedded Assistant is loaded from the proxy URL (the iframe src points to the proxy), all HTTP requests from the app naturally route through the proxy. WebSocket connections, however, connect to a separate backend host by default. To route them through the proxy, the host application must set websocketBaseUrl using the configure method. The host application sends the configure method with the network.websocketBaseUrl property. For implementation details, see the PostMessage API or Window API documentation.
// Using the PostMessage API
postMessage({
  type: "CORTI_EMBEDDED",
  version: "v1",
  action: "configure",
  requestId: "unique-id",
  payload: {
    network: {
      websocketBaseUrl: "wss://proxy.example.com",
    },
  },
});

// Using the Window API
await window.CortiEmbedded.v1.configure({
  network: {
    websocketBaseUrl: "wss://proxy.example.com",
  },
});
When websocketBaseUrl is set, the app sends WebSocket connections through the proxy. For proxy-root deployments, set websocketBaseUrl to the proxy origin:
Original:  wss://api.eu.corti.app/audio-bridge/v1/transcribe?token=xyz
Rewritten: wss://proxy.example.com/audio-bridge/v1/transcribe?token=xyz
The path and query string are preserved. This is what enables the proxy to route connections based on /audio-bridge/*. For subpath deployments, set websocketBaseUrl to the same public origin and subpath used by the iframe URL. The Corti Assistant runtime base path shim keeps same-origin WebSocket requests under that subpath, so your proxy can route them before stripping the prefix for the WebSocket backend.
await window.CortiEmbedded.v1.configure({
  network: {
    websocketBaseUrl: "wss://proxy.example.com/assistant",
  },
});
The configure method should be called before the user starts an interaction. It can be called at any time after the embedded app has loaded and the ready event has been received. The configuration persists for the duration of the session.

NGINX Example (Proxy Root)

A complete NGINX configuration for proxying the embedded Corti Assistant. Replace the upstream URLs with the values for your region.
This example listens on port 80 for simplicity. For production, add TLS termination (listen 443 ssl) and certificate paths.
resolver 1.1.1.1 8.8.8.8 valid=30s;

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;

    # Large auth tokens / cookies can exceed the default 8k request header limit
    large_client_header_buffers 4 32k;

    # Replace with the upstream URLs for your region
    set $corti_web assistant.eu.corti.app;
    set $corti_ws  api.eu.corti.app;

    # ── WebSocket: /audio-bridge/* → Corti WebSocket backend ──

    location /audio-bridge/ {
        proxy_pass https://$corti_ws;
        proxy_ssl_server_name on;
        proxy_set_header Host $corti_ws;

        # WebSocket upgrade
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Long-lived connections — at least 4 minutes
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    # ── Everything else → Corti web app ──

    location / {
        proxy_pass https://$corti_web;
        proxy_ssl_server_name on;
        proxy_set_header Host $corti_web;

        # Large auth tokens require bigger buffers than the default 4k
        proxy_buffer_size 16k;
        proxy_buffers 4 16k;

        # Corti Assistant forwarding headers
        proxy_set_header Corti-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Corti-Forwarded-Host $host;
        proxy_set_header Corti-Forwarded-Proto $scheme;
    }
}

NGINX Example (Subpath Hosting)

Example configuration for hosting the embedded app under /corti-assistant/. Replace every /corti-assistant occurrence with the external subpath you choose. This setup:
  • Serves all Assistant HTTP routes under /corti-assistant/*
  • Sends the prefixed HTTP path to the Corti web upstream unchanged
  • Routes WebSocket /corti-assistant/audio-bridge/* to the Corti WebSocket upstream after stripping the subpath prefix
resolver 1.1.1.1 8.8.8.8 valid=30s;

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;

    large_client_header_buffers 4 32k;

    set $corti_web assistant.eu.corti.app;
    set $corti_ws  api.eu.corti.app;

    location = /corti-assistant {
        return 308 /corti-assistant/;
    }

    # WebSocket bridge
    location ^~ /corti-assistant/audio-bridge/ {
        rewrite ^/corti-assistant(/audio-bridge/.*)$ $1 break;
        proxy_pass https://$corti_ws;
        proxy_ssl_server_name on;
        proxy_set_header Host $corti_ws;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    # Public prefixed app routes. Keep the /corti-assistant prefix intact.
    location ^~ /corti-assistant/ {
        proxy_pass https://$corti_web;
        proxy_ssl_server_name on;
        proxy_set_header Host $corti_web;

        proxy_buffer_size 16k;
        proxy_buffers 4 16k;

        proxy_set_header Corti-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Corti-Forwarded-Host $host;
        proxy_set_header Corti-Forwarded-Proto $scheme;
        proxy_set_header Corti-Forwarded-Prefix /corti-assistant;
    }
}

Implementation Checklist

  • Forward all HTTP requests to the Corti web app upstream URL
  • Set Corti-Forwarded-For, Corti-Forwarded-Host, and Corti-Forwarded-Proto headers on HTTP requests to the Corti web app
  • If using subpath hosting, set Corti-Forwarded-Prefix and keep the public subpath prefix on HTTP requests to the Corti web app
  • Handle WebSocket Upgrade requests
  • Route /audio-bridge/* WebSocket connections to the Corti WebSocket backend
  • If using subpath hosting, strip the subpath prefix before matching/forwarding WebSocket /audio-bridge/* routes
  • Buffer client WebSocket messages until the upstream connection is established
  • Send the configure action from the host application with network.websocketBaseUrl set to the proxy URL