Skip to main content
SpeakerWeave is configured entirely through environment variables. The core app needs only the database block; every other layer — AI, email delivery, Slack, Airtable, Clerk — activates when its keys are present and stays dormant otherwise. Copy the templates and fill in what you need:

Core: database and tokens

Required for everything. This implementation uses Supabase (Postgres + Storage over PostgREST), but any compatible PostgREST origin works — the API talks to SUPABASE_URL through one data layer.

URLs and CORS

Per-event branding

Each event owns one branding document, edited under Settings → Branding or through the v1, agent, and MCP branding tools. Branding is scoped to that event: it changes the public schedule, speaker directory, session dialog, embeds, and public CFP form without repainting another event or the organizer app. The self-hosted font roster is instrument-sans, instrument-serif, inter, space-grotesk, dm-sans, ibm-plex-sans, figtree, playfair-display, source-serif, lora, jetbrains-mono, and ibm-plex-mono. Public pages load only the event’s selected heading and body families; they do not request remote stylesheets or font files. For embed colors, precedence is ?accent= or data-dais-accent → stored event branding → SpeakerWeave defaults. The URL or script attribute override changes only that embed instance.

AI: the agent, triage, and every AI surface

The in-app Ask agent, the Slack agent, AI triage, and title generation all run from the same provider configuration. One key is enough — bring OpenAI or Anthropic:
OpenAI-compatible gateways (OpenRouter, LiteLLM, a self-hosted proxy): the OpenAI client honors the standard OPENAI_BASE_URL environment variable, so point it at your gateway and set ASSISTANT_OPENAI_MODEL to the gateway’s model slug. The OpenAI lane speaks the Responses API, so choose a gateway/model that supports it — otherwise use the Anthropic lane, or swap the model loop in api/agent/runtime_openai.py (the documented seam) while keeping agent/service.run_turn.
With no provider key: the Ask pane and Slack agent stay hidden/dormant, and submission triage falls back to reviewer-score heuristics. The product works fully without AI.

Email delivery

This implementation uses Resend; the seam is one send_email function in api/services/mailer.py — implement it against any provider.

Auth (organizer sign-in)

This implementation uses Clerk, but the API only ever verifies an HS256 JWT carrying an org_id claim — any issuer that signs with SUPABASE_JWT_SECRET works, and the dev-token flow needs no external auth at all.

Slack agent

Full setup in Slack agent — the manifest preconfigures the app; the API needs:

Airtable

No environment variables in normal use — credentials are per-organization in Settings → Integrations. AIRTABLE_API_KEY / AIRTABLE_BASE_ID exist only as a development fallback for the demo org.

MCP connectors

Operations

The in-process permission gate for agent approvals is designed for a single API process. Keep WORKERS=1, or move the pending-permission registry to the database before scaling out — see chat agent.