Skip to main content

Embedded Portal

The Embedded Portal lets you drop a complete webhook management UI into your application. Your customers can create endpoints, subscribe to events, view delivery logs, and retry failed deliveries — all within your app's interface.

Plan Requirement

The Embedded Portal is available on Starter plans and above.

Live Preview

Try the portal below — customize the theme, accent color, and border radius to see how it looks in your application.

Endpoints

https://api.example.com/webhooksactive

Production endpoint

3 eventsCreated 3/15/2026
https://staging.example.com/hookspaused
1 eventCreated 3/14/2026

Overview

The portal is available in two integration modes:

ModeBest ForAdvantages
React ComponentReact/Next.js appsNative integration, callbacks, full control
iFrameAny web app (non-React)Zero dependencies, works everywhere

Both modes use the same portal token for authentication and the same backend API (/v1/waas-portal/).

Portal Token

Before embedding the portal, generate a portal token scoped to a specific tenant. This token authenticates your customer's access and controls which event types they can see.

Via API

curl -X POST https://api.zyphr.dev/v1/waas/applications/{app_id}/portal/token \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant_id": "tenant_abc",
"allowed_event_types": ["order.created", "order.updated"],
"expires_in": 3600,
"theme": { "mode": "dark", "accent": "#6366f1" }
}'

Via Dashboard

  1. Navigate to Webhooks-as-a-Service → Configure in the sidebar
  2. Click on your application
  3. Go to the Endpoints tab
  4. Use the Generate Portal Token action for a specific tenant

The token is a JWT containing:

  • tenant_id — scopes all operations to this tenant
  • application_id — scopes to this WaaS application
  • allowed_event_types — optional filter for visible event types
  • theme — portal appearance settings
  • expires_at — token expiration

React Component

Install the portal package:

npm install @zyphr/webhook-portal
# or
yarn add @zyphr/webhook-portal

Basic Usage

import { WebhookPortal } from '@zyphr/webhook-portal';

function CustomerWebhookSettings() {
const [portalToken, setPortalToken] = useState<string | null>(null);

useEffect(() => {
// Fetch portal token from your backend
fetch('/api/webhook-portal-token', {
method: 'POST',
body: JSON.stringify({ tenant_id: currentUser.tenantId }),
})
.then(res => res.json())
.then(data => setPortalToken(data.token));
}, []);

if (!portalToken) return <div>Loading...</div>;

return (
<WebhookPortal
token={portalToken}
theme={{
mode: 'dark',
accent: '#6366f1',
borderRadius: 8,
}}
locale="en"
onEndpointCreated={(endpoint) => {
console.log('Endpoint created:', endpoint);
}}
onEndpointDeleted={(endpoint) => {
console.log('Endpoint deleted:', endpoint);
}}
/>
);
}

Props

PropTypeRequiredDescription
tokenstringYesPortal token from token generation API
previewbooleanNoRender with mock data and no API calls (for demos/previews)
themeobjectNo{ mode: 'light' | 'dark', accent: string, borderRadius: number }
localestringNoLocale code (default: en)
onEndpointCreatedfunctionNoCallback when an endpoint is created
onEndpointDeletedfunctionNoCallback when an endpoint is deleted
onEndpointUpdatedfunctionNoCallback when an endpoint is updated
onDeliveryRetriedfunctionNoCallback when a delivery is retried
onErrorfunctionNoCallback when an error occurs
classNamestringNoCSS class for the portal container

iFrame Embed

For non-React applications, embed the portal as an iFrame.

Basic Usage

<iframe
id="zyphr-portal"
src="https://portal.zyphr.dev/?token={portal_token}&theme=dark"
width="100%"
height="600"
style="border: none; border-radius: 8px;"
></iframe>

Query Parameters

ParameterDescriptionExample
tokenPortal token (required)token=eyJhbG...
themeColor modetheme=dark or theme=light
accentAccent color (hex)accent=%236366f1
localeLocale codelocale=en
baseUrlCustom API base URLbaseUrl=https://api.zyphr.dev/v1/waas-portal

postMessage API

The iFrame communicates with the parent page via postMessage.

Events emitted by the portal (listen on your parent page):

window.addEventListener('message', (event) => {
// Verify origin
if (event.origin !== 'https://portal.zyphr.dev') return;

switch (event.data.type) {
case 'zyphr:ready':
console.log('Portal loaded');
break;
case 'zyphr:endpoint:created':
console.log('Endpoint created:', event.data.payload);
break;
case 'zyphr:endpoint:updated':
console.log('Endpoint updated:', event.data.payload);
break;
case 'zyphr:endpoint:deleted':
console.log('Endpoint deleted:', event.data.payload);
break;
case 'zyphr:delivery:retried':
console.log('Delivery retried:', event.data.payload);
break;
case 'zyphr:error':
console.error('Portal error:', event.data.payload);
break;
}
});

Commands you can send to the portal:

const iframe = document.getElementById('zyphr-portal');

// Refresh the portal (reloads all data)
iframe.contentWindow.postMessage({ type: 'zyphr:refresh' }, 'https://portal.zyphr.dev');

// Navigate to a specific section (reserved for future use)
iframe.contentWindow.postMessage(
{ type: 'zyphr:navigate', payload: { section: 'endpoints' } },
'https://portal.zyphr.dev'
);

Portal Features

Both the React component and iFrame provide:

  • Event Type Browser — View available event types with descriptions and example payloads
  • Endpoint Management — Create, edit, pause, and delete webhook endpoints
  • Event Subscriptions — Choose which events each endpoint receives
  • Delivery Logs — View delivery history with status, latency, and response details
  • Retry Failed Deliveries — One-click retry for failed or exhausted deliveries
  • Test Events — Send test events to verify endpoint configuration
  • Secret Rotation — Rotate the signing secret with a reveal-once UI
  • Health Indicators — Visual indicators for endpoint health and circuit breaker state

Theming

Customize the portal appearance to match your application:

{
"mode": "dark",
"accent": "#6366f1",
"border_radius": 8
}
PropertyTypeDefaultDescription
mode'light' | 'dark''light'Color mode
accentstring'#228be6'Primary accent color (hex)
border_radiusnumber4Border radius in pixels

Security

  • Portal tokens are short-lived JWTs (default: 1 hour, max: 24 hours)
  • All portal API requests are scoped to the authenticated tenant
  • Tenants cannot see or modify other tenants' endpoints or deliveries
  • The portal token does not grant access to the main WaaS management API

Next Steps