Skip to content

Integrations & scope

Integrations are connected third-party accounts — a Slack workspace, a Telegram bot, a Gmail OAuth grant, a Teller bank enrollment, an Email/SMTP credential, a Webhook URL. They’re stored encrypted at rest in user_integrations, scoped to the user.

When an agent runs, the orchestrator looks up the user’s integrations and injects the corresponding MCP servers / wires up the corresponding notification channels. Scope decides which integrations the running profile can see.

User
├── Integration: Slack (Vox Gateway) scope=all
├── Integration: Telegram bot @VonzioBot scope=all bound_profile_id=null
├── Integration: Telegram bot @VZFinance_bot scope=agents bound_profile_id=prof_vzfin
├── Integration: Gmail (amouzou@gmail.com) scope=all
├── Integration: Teller (PNC enrollment) scope=agents profile_ids=[prof_vzfin]
├── Integration: Teller (Chase enrollment) scope=agents profile_ids=[prof_vzfin]
├── Integration: Email (alerts@app.vonz.io) scope=all
└── Integration: Webhook (zapier hook) scope=all

The scope field controls which agent profiles can use each integration.

ValueMeans
all (default)Every agent owned by the user can use this integration.
agentsOnly profiles whose ids are in profile_ids can use it.

The check happens in two places:

  1. MCP injection (orchestrator): for gmail / teller, the corresponding MCP server is only injected when the integration is granted to the running profile.
  2. Per-call (teller-mcp specifically): within an injected MCP server, it re-filters enrollments to those granted to the running profile, so a stale token can’t read out-of-scope rows.

Slack, Telegram, Email, Webhook integrations also honor scope when delivering platform-side notifications (e.g. playbook notify_on) — only granted integrations are eligible.

  • Privacy isolation: your VZFinance profile sees your bank, your coding profile doesn’t.
  • Bot routing: a Telegram bot bound to one profile shouldn’t suddenly answer in another agent’s voice.
  • Scope-down for shared accounts: if you share an account with someone, scope sensitive integrations away from their profiles.

Via the dashboard: Settings → Integrations → click “Scope: …” on any row. Choose “All agents” or “Specific agents” + the profiles.

Via API:

PATCH /v1/integrations/:id
Content-Type: application/json
{
"scope": "agents",
"profile_ids": ["prof_vzfin"]
}

If profile_ids contains a profile id that doesn’t belong to you, the server rejects with 400. Same check applies on /v1/secrets.

Some integration types allow multiple rows per (user, type):

  • Teller — one row per bank enrollment. PNC, Chase, NFCU = three rows.
  • Telegram — one row per bot. You can pair the shared platform bot + one or more BotFather bots (each bound to a specific profile via bound_profile_id).

Others are one-per-user: Slack (one workspace), Gmail (one OAuth grant), Email (one SMTP credential), Webhook (one URL).

Integration secrets (bot tokens, OAuth refresh tokens, signing secrets) are AES-GCM-encrypted at rest. Vonzio decrypts them server-side only when needed — they never reach your browser, and the API redacts them whenever an integration row is read.

EndpointPurpose
GET /v1/integrationsList your integrations (config sensitive fields redacted).
POST /v1/integrationsCreate an email or webhook integration (Slack/Gmail/Telegram use OAuth flows).
PATCH /v1/integrations/:idUpdate config / enabled / scope / profile_ids / is_default.
DELETE /v1/integrations/:idDisconnect.
POST /v1/integrations/:id/testFire a test notification through this integration.

Per-provider OAuth flows live at /v1/integrations/slack/authorize, /v1/integrations/gmail/authorize, /v1/integrations/teller/callback, /v1/integrations/telegram/connect, etc. — see each integration’s docs.