• Use Cases
  • Pricing
  • Security
  • Docs
Sign InStart free

The outbound integration layer for SaaS products: emit once, then let Meshes handle routing, retries, fan-out, and delivery history.

© Copyright 2026 Meshes, Inc. All Rights Reserved.

About
  • About
  • Security
  • Blog
  • Contact
  • FAQ
Product
  • Pricing
  • Demo
  • Integrations
  • Guides
  • Changelog
  • Status
Compare
  • All comparisons
  • Build vs buy
  • vs Paragon
  • vs Merge
  • vs n8n
  • vs Zapier
  • vs Make
Use Cases
  • All use cases
  • Embedded CRM sync
  • Per-tenant Slack
  • HMAC webhooks
  • Multi-env workspaces
  • Payment failed
  • User signup fan-out
  • Churn prevention
  • Trial expired events
Developers
  • Documentation
  • Agents
  • Tools
  • API Reference
  • MCP Server
  • llms.txt
Legal
  • Terms of Service
  • Privacy Policy
  • Acceptable Use Policy
  • Cookie Policy

Use CasePer-environment isolation

Multi-Environment Workspaces - Keep Dev, Staging, and Production From Colliding

Workspaces are not only for external customers. Every SaaS has internal tenants that need the same isolation: dev, staging, and production. Meshes lets you run a workspace per environment so test events never accidentally update a production CRM, staging never posts to the real #alerts channel, and every environment has its own connections, rules, and delivery history.

Start freeView documentation

Event:user.created· Destinations:Slack (per-env channel)HubSpot (sandbox vs prod)Webhook (test harness)

The problem

Why this workflow breaks down without a delivery layer

Integration code and test data do not mix well. The moment you wire up a production CRM or a shared Slack channel, every feature branch, integration test, and staging deploy becomes a chance to fire off a real side effect by accident.

Teams usually work around this with feature flags, env-specific configs, or "only run this in prod" branches. Something eventually slips through — a worker fires from staging, a developer on a dev box hits HubSpot, a load test floods a shared channel, and someone has to go clean up the CRM.

The cleaner pattern is to treat environments the same way you treat customers: separate workspaces. Each environment has its own publishable key, its own connections (usually pointing at sandbox accounts), and its own event history — so there is nothing to leak even when the code behaves identically.

The event flow

One event in. Every downstream system stays in sync.

Meshes receives the source event once, maps it to the right destinations per workspace, and keeps delivery visible when downstream APIs fail.

Event payload

user.created
{
  "user_id": "usr_homer",
  "email": "homer@springfield-npp.dev",
  "account_id": "acc_springfield",
  "environment": "staging",
  "created_at": "2026-04-17T12:00:00Z"
}
Slack (per-env channel)

Each environment workspace points at its own Slack channel — #dev-alerts, #staging-alerts, #alerts — with its own OAuth token.

Noisy test data stays in the channel built to absorb it; production alerts stay trustworthy because only real events reach them.

HubSpot (sandbox vs prod)

Dev and staging workspaces connect to a HubSpot sandbox; the production workspace connects to your real HubSpot account.

Test contacts and failed-delivery replays stay inside the sandbox environment with no chance of polluting the real CRM.

Webhook (test harness)

Non-production workspaces can route the same event to a local test harness or QA environment via webhook without affecting any other destination.

Engineers can capture, diff, and verify outgoing events against real production rules without mocking the entire delivery layer.

How Meshes handles it

What Meshes takes off your team's plate

Instead of maintaining separate workers, retry logic, and visibility per destination, Meshes gives you one event path, destination-aware routing, and built-in delivery guarantees.

From your product

user.createdenters Meshes once

import MeshesEventsClient from '@mesheshq/events';

// WORKSPACE_PUBLISHABLE_KEY is set per environment:
//   dev    → pk_dev_...    → HubSpot sandbox + #dev-alerts
//   stage  → pk_stage_...  → Salesforce sandbox + #staging-alerts
//   prod   → pk_prod_...   → HubSpot prod + #alerts
const meshes = new MeshesEventsClient(
  process.env.WORKSPACE_PUBLISHABLE_KEY!,
);

await meshes.emit({
  event: 'user.created',
  resource: 'membership_level',
  resource_id: 'starter',
  payload: {
    user_id: 'usr_homer',
    email: 'homer@springfield-npp.dev',
    account_id: 'acc_springfield',
    environment: process.env.APP_ENV,
    created_at: new Date().toISOString(),
  },
});

Across destinations

Each downstream tool gets the context it needs

  • • Each environment workspace owns the same rule shape, but the connections it points at are environment-specific.
  • • A missing or misconfigured connection in dev/staging never fails over to the production workspace — nothing crosses the boundary.
  • • Event schemas and mappings can be kept in sync via the management API when you want every environment to stay aligned with prod.

On every delivery

Retries, replay, and delivery history stay built in

  • • Publishable keys are scoped per workspace, so a leaked dev key cannot trigger production deliveries.
  • • Retries, dead letters, and replay history live inside each environment workspace — nothing from staging ever shows up in production logs.
  • • Because workspaces are the same primitive you use for customers, onboarding a new environment is the same operation you already automate for tenants.

Why this matters

Business impact, not just API plumbing

Test data never reaches real customer integrations

Even when code behaves identically across environments, the connections behind a dev or staging workspace point at sandbox accounts — there is nothing to hit in prod.

Every environment stays audit-clean

Production delivery logs only contain production events. Staging replays and load tests stay confined to their own workspace history.

One primitive, two problems

The same workspace model that isolates your customers also isolates your environments. You do not learn two different patterns to ship customer-facing integrations and keep your own stack safe.

Related

Docs, integrations, and deeper architecture reading

Docs

Quickstart

See how to spin up per-environment workspaces with their own connections and publishable keys.

Open link

Docs

Send Events

See the publishable-key pattern that lets you point the same client at dev, staging, or production.

Open link

Docs

Integrations & Rules

Keep rules in sync across environments while letting each workspace own its connections.

Open link

Use Case

Embedded Customer CRM Sync

See the same workspace primitive applied to external customer tenancy.

Open link

Blog

Design Multi-Tenant Integrations

Why the workspace boundary solves both customer isolation and environment isolation.

Open link

Compare

Meshes vs. DIY

Compare per-workspace environment isolation to rolling env flags and branch logic in your own integration code.

Open link

Next stepStart free or view the documentation

Give every environment its own workspace

Run separate Meshes workspaces for dev, staging, and production so test events never reach the real CRM, real Slack, or real customer endpoints.

Start freeView documentation