When you're building a B2B SaaS product, at some point an enterprise customer asks: "Can we have webhooks?" And then shortly after: "Can those webhooks come from our domain? With our branding? And documentation that looks like our developer portal?"
This is white-labeling, and it's one of the most requested features in B2B developer tooling. Your customers want to give their own developers a seamless experience — not a third-party integration that breaks the illusion of a unified platform.
This post covers the architecture for building a white-label webhook system, the decisions that matter, and how GetHook's white-labeling features support this pattern.
What White-Labeling Actually Means
Before building, clarify what your customers are asking for. "White-label webhooks" can mean several different things:
Level 1: Custom documentation branding
Logo, colors, and company name on the webhook documentation portal. The endpoint URLs still say yoursaas.com.
Level 2: Custom inbound domain
Customer's developers register webhook endpoints at webhooks.customer.com/ingest/... instead of yoursaas.com/ingest/....
Level 3: Custom outbound domain
When your system sends webhooks to your customer's systems, the User-Agent header and signature format are branded to the customer, not to you.
Level 4: Full developer portal Your customer has their own hosted developer documentation portal with your webhook API reference, under their domain, with their branding.
Most enterprise deals require Level 1 + Level 2 at minimum. Level 3 and 4 are premium tier.
The Architecture
White-label webhook infrastructure has three planes:
┌─────────────────────────────────────────────────────────┐
│ Control Plane (your SaaS backend) │
│ - Customer account management │
│ - Tenant configuration (brand settings, domains) │
│ - Route and destination management per customer │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ Data Plane (GetHook / webhook gateway) │
│ - Event ingest at customer-specific URLs │
│ - Durable storage per tenant │
│ - Delivery with tenant-specific signing │
│ - Retry and DLQ per tenant │
└────────────────────────┬────────────────────────────────┘
│
┌────────────────────────▼────────────────────────────────┐
│ Customer-Facing Layer │
│ - Custom domain (webhooks.customer.com) │
│ - Branded developer documentation │
│ - Customer's developer API keys │
└─────────────────────────────────────────────────────────┘The key insight: your customers' developers interact only with the customer-facing layer. They never see GetHook or your internal implementation.
Custom Domain Architecture
The most impactful white-labeling feature for developers is inbound URL customization. A developer webhook endpoint that reads:
https://webhooks.acme-corp.com/ingest/src_abc123...looks fundamentally different from:
https://yoursaas.com/ingest/src_abc123DNS Setup
Custom domains require your customer to add a CNAME or ALIAS record:
webhooks.acme-corp.com CNAME ingress.yoursaas.comYour ingress layer reads the Host header to determine which tenant's configuration to use for routing, signature verification, and authentication.
TLS Provisioning
Custom HTTPS requires a certificate for webhooks.acme-corp.com. You have two options:
Let's Encrypt via ACME — automatic certificate provisioning and renewal. Works well but requires your infrastructure to complete DNS-01 or HTTP-01 challenges.
Certificate delegation — customer provides their own certificate (common in enterprise security-conscious accounts).
GetHook handles TLS provisioning automatically for custom domains, including automatic renewal.
Wildcard vs. per-customer subdomains
Some platforms use a single wildcard certificate (*.customer-webhooks.com) with per-customer subdomain routing. This reduces the per-customer TLS overhead but limits flexibility (customer can't use their own domain, only a subdomain of yours).
The premium approach is a custom domain per customer — each with its own TLS certificate.
Tenant Isolation at the Data Layer
White-labeling is cosmetic. Tenant isolation is architectural. Every piece of data in your webhook system must be scoped to a single tenant.
Required isolation guarantees
- ›Event data — a customer can only query events belonging to their account
- ›Delivery logs — delivery attempts are visible only to the owning tenant
- ›Signing secrets — per-destination HMAC secrets are never shared between tenants
- ›Custom domains — domain configuration is per-tenant and cannot be claimed by another tenant
- ›API keys — each tenant's API key can only access their own data
GetHook enforces this at the query layer — every query includes an account_id filter. There's no cross-tenant data path.
Row-level security vs. separate schemas
For strict enterprise isolation requirements, some teams use PostgreSQL row-level security (RLS) policies:
ALTER TABLE events ENABLE ROW LEVEL SECURITY;
CREATE POLICY events_isolation ON events
USING (account_id = current_setting('app.current_account_id')::uuid);This prevents any query path (even a buggy application query) from leaking cross-tenant data. The trade-off is complexity in query planning and connection management.
For most SaaS products, application-layer account_id filtering with careful code review is sufficient.
Brand Settings Implementation
Brand settings allow per-tenant customization of the developer-facing experience:
type BrandSettings struct {
AccountID uuid.UUID `json:"account_id"`
CompanyName string `json:"company_name"`
LogoURL string `json:"logo_url"`
PrimaryColor string `json:"primary_color"` // hex
DocsTitle string `json:"docs_title"`
SupportEmail string `json:"support_email"`
CustomDomain string `json:"custom_domain,omitempty"`
}The developer portal reads these settings at render time and applies them to the documentation. Key things to brand:
- ›Logo and color scheme
- ›Documentation page title (e.g., "Acme Developer Portal — Webhooks")
- ›Support contact information
- ›Code examples (use the customer's domain in curl examples, not yours)
- ›Error messages and status pages
Generating branded code examples
This is often overlooked but important. If your docs show:
curl -X POST https://yoursaas.com/ingest/src_abc123 \
-H "Content-Type: application/json" \
-d '{"event": "order.created"}'...the illusion breaks. The code example should reflect the tenant's custom domain:
curl -X POST https://webhooks.acme-corp.com/ingest/src_abc123 \
-H "Content-Type: application/json" \
-d '{"event": "order.created"}'This requires your documentation to be dynamically rendered with the correct domain substituted in.
The Developer Portal
A white-label developer portal is a hosted documentation site that:
- ›Shows the API reference with your customer's branding
- ›Includes live examples using the customer's actual ingest URLs
- ›Has an authentication flow for the customer's developers to get their own API keys
- ›Provides webhook testing and debugging tools
Implementation options
Static site with brand config — generate a static documentation site per tenant at deploy time. Simple but doesn't support dynamic content.
Dynamically rendered docs — a single documentation application that reads brand config from the API and renders appropriately. More complex but supports real-time brand changes.
iFrame embedding — your customer embeds your documentation in their existing developer portal via iFrame. Fast to ship but limited customization.
GetHook's brand settings API supports custom domain, logo, colors, and title — the foundation for building a Level 1–3 white-label experience.
What Customers Actually Ask For
Based on common B2B patterns, here's what enterprise customers prioritize:
| Feature | How Often Requested | Effort |
|---|---|---|
| Custom inbound domain | Very common | Medium |
| Logo + color branding in docs | Very common | Low |
| Remove third-party attribution | Common | Low |
| Custom support email in error messages | Common | Low |
| Dedicated infrastructure (not shared) | Less common | High |
| Custom signing signature format | Rare | High |
Start with custom domains and brand settings. The ROI on dedicated infrastructure is low unless you have a contractual requirement for it.
Checklist for White-Label Launch
- › Custom domain with HTTPS (CNAME + automatic TLS)
- › Brand settings: logo, primary color, company name, docs title
- › All developer-facing documentation uses tenant's domain in examples
- › API responses use tenant's domain (no leaking of your internal domain)
- › Tenant isolation verified — run a cross-tenant data access test
- › Custom domain verification flow documented (DNS CNAME instructions)
- › Support handoff defined — who handles white-label customer support?
- › Error pages and status pages are branded (not your default 502 page)
GetHook's white-labeling features cover the inbound and outbound layers so you can focus on your product's core value. See white-label documentation →