Browse documentation

The Integrations tab is a static catalogue (apps/server/config/integrations-registry.ts) built entirely on primitives you already have: edge-function secrets plus prebuilt edge functions. There is no hidden runtime — connecting an integration saves its secrets and, optionally, installs its function templates.

Catalogue

KeyCategoryWhat it gives you
stripepaymentsQuery customers, receive Stripe webhooks
shopifypaymentsRead orders from a store
calendlyschedulingList scheduled events, receive booking webhooks
airtabledataRead records from a base
notiondataQuery a Notion database
posthogdataSend product analytics events from the backend
algoliadataSearch and index records
hubspotdataRead and create CRM contacts
slackmessagingPost messages to a channel via incoming webhook
discordmessagingPost messages to a channel via webhook
twiliomessagingSend SMS
telegrammessagingSend messages from a bot, receive updates
resendemailTransactional email through Resend
sendgridemailTransactional email through SendGrid
postmarkemailTransactional email through Postmark
openaiaiCall chat completions from an edge function
anthropicaiCall Claude from an edge function
githubdevtoolsList repo issues, receive repo webhooks
lineardevtoolsQuery and create Linear issues
sentrydevtoolsRead unresolved issues from a project
cloudflaredevtoolsPurge the CDN cache for a zone

Shape of an integration

interface Integration {
  key: string
  name: string
  description: string
  category: 'payments'|'scheduling'|'data'|'messaging'|'email'|'ai'|'devtools'
  docsUrl: string
  secrets: { name: string; label: string; placeholder: string; optional?: boolean }[]
  functions: {
    name: string; route: string; description: string
    schedule?: string
    readiness?: 'production' | 'example'
    code: string
  }[]
}

Secrets are stored as edge-function secrets, so inside the sandbox they are read as env.NAME — e.g. env.STRIPE_SECRET_KEY. See Edge Functions.

Warning

A function template marked readiness: 'example' is a starting point, not a finished endpoint. It needs provider verification (signature checks) and your own business logic before it is safe in production. Templates marked production are complete as shipped.

Connected state

IntegrationsService.list() returns, per integration:

  • each secret with set: boolean — is it stored?
  • each function with installed: boolean and its edge-function id when installed, matched by route
  • connected: true when every non-optional secret is set

Optional secrets never block the connected state.

Endpoints

MethodPathAction
GET/api/admin/integrationsCatalogue with status
POST/api/admin/integrations/:key/connectStore secrets, optionally install functions
DELETE/api/admin/integrations/:keyDisconnect

All three require adminOnly (apps/server/controllers/integrations.controller.ts).

Adding your own

There is no plugin loader: the catalogue is a TypeScript array. Adding an entry to INTEGRATIONS — with its secrets and its function templates — is the whole extension mechanism. Anything more custom is just an edge function you write yourself, with secrets you set directly.