Skip to content

Multi-Tenant Lead Routing

HomeStar’s multi-tenant architecture automatically routes leads to the correct brokerage based on the request domain, enabling white-label deployments without frontend configuration.

Lead routing is automatic and transparent:

  1. Client submits form on www.your-domain.com
  2. Request includes Host: www.your-domain.com header
  3. API looks up domain → finds brokerage_id: 1
  4. Lead is created with brokerage_id: 1

No frontend configuration is required. The system uses the HTTP Host header to determine the target brokerage.

The API checks headers in this order:

  1. X-Forwarded-Host — Set by reverse proxies (Caddy, nginx, etc.)
  2. Host — Standard HTTP header

This ensures correct routing when the API is behind a reverse proxy or load balancer.

The system maintains a domain-to-brokerage mapping table:

SELECT brokerage_id
FROM brokerages
WHERE domain = 'www.your-domain.com';

If no match is found, the request is rejected with a 404 Not Found error.

Zero frontend configuration:

  • No hardcoded brokerage IDs in JavaScript
  • Same frontend code deployed across all brokerages
  • White-label sites work immediately after DNS configuration

Security:

  • Brokerages cannot accidentally access each other’s leads
  • Domain ownership proves authorization
  • No API key management for public endpoints

Scalability:

  • Add new brokerages by configuring DNS and database entry
  • No code changes required per deployment
  • Supports unlimited white-label instances

Domain required:

  • Cannot submit leads without a valid domain mapping
  • Testing requires domain configuration or hosts file modification

DNS dependency:

  • Domain must resolve to the API server
  • DNS changes have propagation delay

No IP-based routing:

  • Cannot route based on client IP geolocation
  • Requires domain per brokerage (subdomains acceptable)

If the request domain has no brokerage mapping:

{
"detail": "Domain 'unknown.example.com' is not configured. Unable to process lead."
}

Status: 404 Not Found

Resolution: Add domain mapping in admin panel or database.

If neither Host nor X-Forwarded-Host is present:

{
"detail": "Missing Host header"
}

Status: 400 Bad Request

Resolution: Check reverse proxy configuration. Ensure headers are forwarded correctly.

If the brokerage exists but is disabled:

{
"detail": "Brokerage not found"
}

Status: 404 Not Found

Resolution: Re-enable brokerage in admin panel.

Map a test domain to localhost:

/etc/hosts
127.0.0.1 test.homestar.local

Then submit requests with that domain:

Terminal window
curl -H "Host: test.homestar.local" \
-X POST \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", ...}' \
http://localhost:8000/api/contact

Override the host header directly:

Terminal window
curl -H "X-Forwarded-Host: www.your-domain.com" \
-X POST \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", ...}' \
http://localhost:8000/api/contact
CREATE TABLE brokerages (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
domain VARCHAR(255) UNIQUE NOT NULL,
active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_brokerages_domain ON brokerages(domain);

The domain column must exactly match the request Host header for routing to work.

CREATE TABLE leads (
id SERIAL PRIMARY KEY,
brokerage_id INTEGER REFERENCES brokerages(id),
email VARCHAR(255) NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
message TEXT,
source_page VARCHAR(500),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_leads_brokerage_id ON leads(brokerage_id);

The brokerage_id foreign key ensures referential integrity and efficient filtering.

Caddy automatically forwards the Host header:

your-domain.com {
reverse_proxy backend:8000
}

No additional configuration needed.

Ensure X-Forwarded-Host is set:

location / {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

Some brokerages may have multiple domains (e.g., www.example.com and example.com):

Approach 1: Domain Aliases Table

CREATE TABLE domain_aliases (
id SERIAL PRIMARY KEY,
brokerage_id INTEGER REFERENCES brokerages(id),
domain VARCHAR(255) UNIQUE NOT NULL
);

Lookup checks both brokerages.domain and domain_aliases.domain.

Approach 2: Primary Domain with Redirects

Configure DNS and proxy to redirect all variants to a canonical domain. Only the canonical domain needs database mapping.