NexusBridge unifies 18 builders, runtimes, and hosts behind one signed webhook envelope and one normalized outbound caller. Encrypted credentials, row-level isolation, deterministic execution, scheduled triggers, full audit logs, and a flow engine you can run on Cloudflare Workers or your own infrastructure.
$ TS=$(date +%s)
$ BODY='{"email":"ceo@acme.io","plan":"enterprise"}'
$ SIG=$(printf "%s.%s" "$TS" "$BODY" \
| openssl dgst -sha256 -hmac "$NEXUS_LOVABLE_WEBHOOK_SECRET" \
| awk '{print $2}')
$ curl -sS -X POST \
https://nexusbridge.app/api/public/hooks/universal/lovable/$FLOW \
-H "content-type: application/json" \
-H "x-nexus-timestamp: $TS" \
-H "x-nexus-signature: sha256=$SIG" \
-d "$BODY"
{ "run_id": "f2a8c1…",
"status": "success",
"duration_ms": 412,
"provider": "lovable",
"steps": [
{ "type": "bubble", "ms": 118, "attempts": 1 },
{ "type": "provider_relay", "ms": 244, "attempts": 1, "target": "replit" },
{ "type": "provider_relay", "ms": 46, "attempts": 1, "target": "netlify" }
] }Bearer, header API-key, Basic, query-string, deploy hooks, signed callbacks — one config shape, every provider.
Drag steps, map fields with mustache paths, branch on condition, transform JSON inline, test any step in isolation.
Sequential executor, exponential backoff, per-step error policy, idempotent retries, per-run trace.
Every run is a row. Inputs, per-step outputs, attempts, durations, status — searchable, exportable, retryable.
pg_cron pings an internal scheduler every minute. Run every N minutes, hourly, daily — with manual override.
HMAC-SHA256 of <ts>.<body>, timing-safe compare, ±5 min replay window, per-provider secret rotation.
A single step type calls any connection. Swap Vercel for Netlify by changing one field — mappings keep working.
Runs on Cloudflare Workers out of the box. Self-host on your own Postgres + edge runtime in under an hour.
bubblesoftrbase44lovableemergentboltcursorwindsurfreplitcloudflaresupabasevercelnetlifyrenderrailwaydigitaloceancoolifydokploy| Provider | Outbound | Inbound | Signature | Auth model | Schedule | Relay |
|---|---|---|---|---|---|---|
| Bubble.io | HMAC-SHA256 | Bearer (Data API + Workflow) | ||||
| Replit | HMAC-SHA256 | Bearer / Header / Basic / Query | ||||
| Lovable.dev | HMAC-SHA256 | Bearer (project-scoped) | ||||
| Emergent.sh | HMAC-SHA256 | Agent API key | ||||
| Base44 | HMAC-SHA256 | Bearer | ||||
| Vercel | HMAC-SHA256 / SHA1 | Deploy hook + Bearer | ||||
| Netlify | HMAC-SHA256 | Build hook + PAT | ||||
| Cloudflare | HMAC-SHA256 | Bearer (Workers / Pages) | ||||
| Render | HMAC-SHA256 (ts) | Bearer (Render API) | ||||
| Railway | HMAC-SHA256 (ts) | Bearer (project token) | ||||
| DigitalOcean | HMAC-SHA256 (ts) | Bearer (PAT, app spec) | ||||
| Coolify | HMAC-SHA256 (ts) | Bearer (instance API) | ||||
| Dokploy | HMAC-SHA256 (ts) | Bearer (instance API) | ||||
| Bolt.new | HMAC-SHA256 (ts) | Bearer | ||||
| Cursor | HMAC-SHA256 (ts) | Bearer | ||||
| Windsurf | HMAC-SHA256 (ts) | Bearer | ||||
| Softr | HMAC-SHA256 | Header API key | ||||
| Supabase | HMAC-SHA256 (ts) | Bearer (service-role / anon) |
Universal inbound: POST /api/public/hooks/universal/<provider>/<flow_id> · per-provider legacy routes remain for native signature schemes.
┌─────────────────────────────────────────┐
│ Inbound webhook │
│ POST /api/public/hooks/universal/... │
│ x-nexus-signature x-nexus-timestamp │
└────────────────────┬────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ NexusBridge hub │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌───────────┐ │
│ │ Verify │─▶│ Load flow │─▶│ Executor │─▶│ Logger │ │
│ │ HMAC + ts │ │ + creds │ │ + retries │ │ flow_runs │ │
│ └────────────┘ └─────┬──────┘ └─────┬──────┘ └─────┬─────┘ │
│ ▲ │ │ │ │
│ │ ┌────▼──────┐ ┌────▼─────┐ ┌────▼─────┐ │
│ │ │ AES-256 │ │ provider │ │ Postgres │ │
│ │ │ GCM │ │ relay │ │ + RLS │ │
│ │ └───────────┘ └────┬─────┘ └──────────┘ │
│ │ │ │
│ ┌────┴────┐ ▼ │
│ │ pg_cron │ ┌────────────────────────┐ │
│ │ ticker │ │ Outbound: 18 providers │ │
│ └─────────┘ │ Bearer · Header · ... │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
The hub is a stateless TanStack Start app. Every inbound request is verified against a per-provider secret before any database read. The executor loads the flow definition, decrypts only the credentials the run needs, and runs steps sequentially with deterministic retry semantics.
Outbound calls go through a single callProvider() helper that normalizes Bearer, header, Basic, and query-string auth, then maps response bodies into the run context so the next step can reference them.
pg_cron hits an internal scheduler endpoint every minute.flow_runs.provider_relay step type makes any connection callable from any flow.Paste a token. We test it, encrypt with AES-256-GCM, and store ciphertext only.
POST /connections
{ "provider": "lovable",
"base_url": "https://project--abc.lovable.app",
"auth": { "type": "bearer", "token": "<paste once>" } }Pipe any field from any previous step using mustache paths. No code, no glue services.
{
"user_email": "{{trigger.email}}",
"score": "{{steps.step_2.body.engagement}}",
"fingerprint": "{{trigger._lovable.delivery_id}}"
}Manual run, pg_cron schedule, or a signed webhook from any provider.
curl -X POST $HUB/api/public/hooks/universal/vercel/$FLOW \
-H "x-nexus-timestamp: $(date +%s)" \
-H "x-nexus-signature: sha256=$SIG" \
-d '{"event":"deployment.succeeded"}'Expand any run to see the JSON in, the JSON out, retries, and per-step duration.
{ "run_id": "8c3…",
"status": "success",
"duration_ms": 412,
"steps": [
{ "type": "bubble", "ms": 118, "attempts": 1 },
{ "type": "provider_relay", "ms": 244, "attempts": 1 }
] }stop_success / stop_failure / skip_next).stop, continue, or retry with exponential backoff (500 ms × 2ⁿ).provider_relay calls any connection — Bubble → Lovable → Netlify in three rows.{{trigger.x}}, {{steps.step_N.body.y}}.{
"name": "Lovable signup → enrich → fan-out",
"steps": [
{ "type": "bubble", "config": {
"connection_id": "bub_…", "data_type": "user",
"operation": "search",
"mappings": [{ "target": "email", "expression": "{{trigger.email}}" }] }},
{ "type": "provider_relay", "config": {
"connection_id": "ep_replit_ai",
"method": "POST", "path": "/enrich",
"use_mappings": true,
"mappings": [
{ "target": "email", "expression": "{{trigger.email}}" },
{ "target": "bubble_user", "expression": "{{steps.step_1.body.results.0}}" } ],
"error_policy": { "on_error": "retry", "retries": 3 } }},
{ "type": "condition", "config": {
"expression": "{{steps.step_2.body.score}}",
"operator": ">",
"value": "0.8",
"true_action": "next",
"false_action": "stop_success" }},
{ "type": "provider_relay", "config": {
"connection_id": "ep_netlify_notify",
"method": "POST", "path": "/build_hooks/abc",
"body": "{ \"trigger_title\": \"score={{steps.step_2.body.score}}\" }" }}
]
}All secrets pass through crypto.server.ts. Wire format: iv ‖ tag ‖ ciphertext. Key lives in NEXUS_ENCRYPTION_KEY — never bundled, never logged, never sent to the browser.
Every inbound request carries x-nexus-signature + x-nexus-timestamp. We HMAC-SHA256 <ts>.<rawBody>, timing-safe compare, reject anything outside ±5 min.
flows, flow_runs, bubble_connections, and replit_endpoints carry owner-scoped policies. Even with a stolen token, you only see your own data.
rotate*Secret server functions re-encrypt the new value and overwrite ciphertext atomically. Old plaintext is unrecoverable from that point forward.
Every connection create, update, rotation, flow edit, and manual run is written to an immutable audit trail keyed by user and workspace.
The Worker runs with a publishable Postgres key. The service-role key is loaded lazily inside server functions only when administrative work requires it.
Data export + delete server functions, EU-residency self-host option.
Controls mapped; observability and access reviews in place.
BAA-eligible only when deployed in your own VPC with your own KMS.
SELECT
provider,
date_trunc('hour', started_at) AS bucket,
count(*) AS runs,
count(*) FILTER (WHERE status = 'success') AS ok,
percentile_cont(0.50) WITHIN GROUP (ORDER BY duration_ms) AS p50,
percentile_cont(0.95) WITHIN GROUP (ORDER BY duration_ms) AS p95,
percentile_cont(0.99) WITHIN GROUP (ORDER BY duration_ms) AS p99
FROM flow_runs
WHERE owner_id = auth.uid()
AND started_at > now() - interval '24 hours'
GROUP BY provider, bucket
ORDER BY bucket DESC;
bubble_connections replit_endpoints flow_templates
───────────────── ───────────────── ─────────────────
id uuid PK id uuid PK id uuid PK
owner_id uuid FK owner_id uuid FK title text
workspace_url text provider text definition jsonb
data_api_token bytea ▣ base_url text category text
workflow_token bytea ▣ auth_payload bytea ▣ is_public bool
created_at timestz created_at timestz created_at timestz
flows
─────────────────────────────────────
id uuid PK
owner_id uuid FK
name text
trigger_kind enum (manual|webhook|schedule)
execution_mode enum (nexus|n8n)
schedule_kind enum (every|hourly|daily)
next_run_at timestz
steps jsonb ← step definitions
created_at timestz
│
│ 1‥N
▼
flow_runs
─────────────────────────────────────
id uuid PK
flow_id uuid FK
owner_id uuid FK
trigger_source enum (manual|webhook|schedule)
status enum (pending|success|failed)
input jsonb
output jsonb ← per-step output
duration_ms int
started_at timestz
finished_at timestz
▣ = AES-256-GCM ciphertext (iv ‖ tag ‖ ct), key off-bundle
Google, GitHub, and OIDC providers today. SAML + SCIM provisioning on the enterprise plan.
Per-workspace connections, flows, and audit log. Owner / admin / operator / viewer roles enforced via RLS.
Self-host the hub on Cloudflare, Fly.io, or any Node-compatible edge. Point at your own Postgres + KMS.
99.95% uptime SLA, 1-hour response on Sev-1, named Slack channel, quarterly architecture reviews.
Need ClickUp, Linear, Snowflake, or an internal service? The connector schema is open — ship a new one in an afternoon.
Pin executors and Postgres to us-east-1, eu-west-1, or ap-southeast-2. Webhook URLs stay stable across regions.
# 1. Mint the signature
TS=$(date +%s)
BODY='{"email":"hello@example.com","plan":"pro"}'
SIG=$(printf "%s.%s" "$TS" "$BODY" | openssl dgst -sha256 -hmac "$NEXUS_LOVABLE_WEBHOOK_SECRET" -hex | awk '{print $2}')
# 2. POST to the universal endpoint — provider chosen by URL segment
curl -sS -X POST "https://nexusbridge.app/api/public/hooks/universal/lovable/$FLOW_ID" \
-H "content-type: application/json" \
-H "x-nexus-timestamp: $TS" \
-H "x-nexus-signature: sha256=$SIG" \
-d "$BODY"
# → { "run_id": "…", "status": "success", "duration_ms": 412, "provider": "lovable" }Same envelope for every provider — swap the URL segment and the secret. Per-provider legacy routes still accept native signature schemes for back-compat.
| Method | Path | Purpose |
|---|---|---|
| POST | /api/public/hooks/universal/:provider/:flow_id | Signed inbound trigger (any provider) |
| POST | /api/public/hooks/:provider | Native per-provider webhook |
| POST | /api/public/hooks/flow-scheduler | Internal pg_cron tick |
| POST | /connections | Create encrypted connection |
| POST | /connections/:id/test | Round-trip credential test |
| POST | /connections/:id/rotate | Atomic secret rotation |
| POST | /flows | Create flow definition |
| POST | /flows/:id/run | Manual execution with input payload |
| POST | /flows/:id/steps/:n/test | Run a single step in isolation |
| GET | /flow_runs?status=&flow_id=&q= | Query run history with full-text search |
| POST | /flow_runs/:id/retry | Replay original input through the flow |
| GET | /analytics/runs | Roll-up metrics for dashboards |
For tinkering and small projects.
Per workspace · production-grade defaults.
SSO, SCIM, BYO cloud, audit, SLA.
In Postgres, AES-256-GCM ciphertext only. The 64-char NEXUS_ENCRYPTION_KEY is a server-side env var. The browser receives masked previews — never plaintext.
The step's error_policy decides. retry uses exponential backoff (500 ms × 2ⁿ) only on 5xx/transport errors. continue writes { error } into the step's slot and proceeds. stop marks the run failed.
Yes. The hub is a TanStack Start app on Cloudflare Workers + a Postgres database. Flip execution_mode per flow to delegate runs to your own n8n instance while keeping credentials, schedules, and logs in NexusBridge.
pg_cron calls an internal scheduler route every minute. It selects flows whose next_run_at <= now(), runs them, and writes the next tick back.
Each outbound call has a 60-second timeout. The engine is sequential — slow steps don't starve fast ones because there's only one in flight per run. Bursty inbound traffic is absorbed by Workers' standard concurrency model.
rotate*Secret re-encrypts the new value and overwrites the previous ciphertext atomically. Old plaintext is unrecoverable from that point.
Yes. Every step has a "Test this step" button that runs the step against a sample payload using the real credentials — no flow_run row is written.
On Team and Enterprise. The connector schema is open: provider id, auth model, signature scheme, base URL. Add a new tab to the Connections UI and ship.
Connect a provider, draw a flow, paste a curl. Be in production by lunch.