Summary
Self-hosted Nango already lets operators put several public surfaces on their own hosts/paths — Connect UI (NANGO_PUBLIC_CONNECT_URL), the WebSocket path (NANGO_SERVER_WEBSOCKETS_PATH), and the OAuth callback URL (customizable in Environment Settings > Callback URL). The inbound integration webhook URL (the per-integration URL Nango generates, shows under Integrations > [Integration] > Webhooks, and that we register in each provider's portal) is the one public surface with no independent configuration: it is derived from NANGO_SERVER_URL.
We'd like the inbound webhook base URL to be independently configurable as well, consistent with how the OAuth callback URL already works.
Current behavior
- NANGO_SERVER_URL defines the base instance URL, which also determines the generated inbound webhook URLs.
- The OAuth callback URL can already be overridden independently (Environment Settings > Callback URL).
- Connect UI and WebSocket path are independently configurable.
- There is no equivalent override for the inbound webhook URL: it always reflects NANGO_SERVER_URL.
The gap / asymmetry
The OAuth callback URL is decoupled from NANGO_SERVER_URL, but the inbound webhook URL is not — even though both are public, third-party-facing surfaces. Because Nango generates and advertises the webhook URL (shown in the dashboard and registered with providers), this cannot be solved purely at our reverse proxy / ingress layer: even if we route /webhook/* to a dedicated host, the URL Nango displays and registers would still point at the NANGO_SERVER_URL host. Only Nango can make the advertised webhook base URL configurable.
Why this is generally useful (not deployment-specific)
Inbound webhooks are a distinct trust surface from the API and dashboard: public, machine-to-machine, signature-authenticated endpoints receiving traffic from external SaaS providers with broad/unpredictable source IPs. This enables:
- Network segmentation: route /webhook/* to a dedicated ingress/gateway with its own WAF, rate-limiting, and DDoS posture, separate from the API/dashboard surface — a standard requirement for the large/regulated enterprises self-hosting targets.
- Minimize public attack surface: keep the API surface private/internal (consumed only by your own backend) and expose only the webhook surface publicly. Today, coupling the webhook URL to NANGO_SERVER_URL forces the server host to be the public webhook host.
- Stable, dedicated webhook domain: webhook URLs are registered with providers and are effectively permanent; operators often want them on a dedicated domain decoupled from the app/API domain.
Proposed solution
Allow the inbound webhook base URL to be configured independently of NANGO_SERVER_URL, in the same spirit as the existing OAuth callback URL override. Either mechanism works for us:
- a new env var (e.g. NANGO_WEBHOOK_URL / NANGO_PUBLIC_WEBHOOK_URL), and/or
- an Environment Settings field (mirroring the existing "Callback URL" setting).
Requirements:
- The generated/advertised integration webhook URL (dashboard display + what gets registered with providers) uses the configured base, not NANGO_SERVER_URL.
- Inbound requests are accepted on the configured webhook host when arriving via a different DNS/ingress.
- Backward compatible: when unset, behavior is unchanged and the webhook URL falls back to NANGO_SERVER_URL.
Acceptance criteria
- With the new setting configured, the webhook URL shown under Integrations > [Integration] > Webhooks reflects the configured base.
- A provider POST to the configured webhook host is accepted and attributed correctly.
- With the setting unset, current behavior is unchanged.
Open question for maintainers
Is there already any supported way to override the advertised inbound webhook base URL independently of NANGO_SERVER_URL that we may have missed?
Context (one motivating deployment)
We self-host Nango (Enterprise, multi-region) and expose public surfaces through separate gateways by trust level. We can place /oauth/callback and /connect/* on a customer-facing gateway and the dashboard on an internal, IP-restricted gateway. We'd like to place the inbound /webhook/* surface on a dedicated public gateway with webhook-appropriate protections, while keeping the API surface internal — currently blocked only by the webhook URL being tied to NANGO_SERVER_URL.
Summary
Self-hosted Nango already lets operators put several public surfaces on their own hosts/paths — Connect UI (NANGO_PUBLIC_CONNECT_URL), the WebSocket path (NANGO_SERVER_WEBSOCKETS_PATH), and the OAuth callback URL (customizable in Environment Settings > Callback URL). The inbound integration webhook URL (the per-integration URL Nango generates, shows under Integrations > [Integration] > Webhooks, and that we register in each provider's portal) is the one public surface with no independent configuration: it is derived from NANGO_SERVER_URL.
We'd like the inbound webhook base URL to be independently configurable as well, consistent with how the OAuth callback URL already works.
Current behavior
The gap / asymmetry
The OAuth callback URL is decoupled from NANGO_SERVER_URL, but the inbound webhook URL is not — even though both are public, third-party-facing surfaces. Because Nango generates and advertises the webhook URL (shown in the dashboard and registered with providers), this cannot be solved purely at our reverse proxy / ingress layer: even if we route /webhook/* to a dedicated host, the URL Nango displays and registers would still point at the NANGO_SERVER_URL host. Only Nango can make the advertised webhook base URL configurable.
Why this is generally useful (not deployment-specific)
Inbound webhooks are a distinct trust surface from the API and dashboard: public, machine-to-machine, signature-authenticated endpoints receiving traffic from external SaaS providers with broad/unpredictable source IPs. This enables:
Proposed solution
Allow the inbound webhook base URL to be configured independently of NANGO_SERVER_URL, in the same spirit as the existing OAuth callback URL override. Either mechanism works for us:
Requirements:
Acceptance criteria
Open question for maintainers
Is there already any supported way to override the advertised inbound webhook base URL independently of NANGO_SERVER_URL that we may have missed?
Context (one motivating deployment)
We self-host Nango (Enterprise, multi-region) and expose public surfaces through separate gateways by trust level. We can place /oauth/callback and /connect/* on a customer-facing gateway and the dashboard on an internal, IP-restricted gateway. We'd like to place the inbound /webhook/* surface on a dedicated public gateway with webhook-appropriate protections, while keeping the API surface internal — currently blocked only by the webhook URL being tied to NANGO_SERVER_URL.