Get started
Core concepts
A handful of ideas you'll see on every page. If you only read one documentation page, make it this one.
Workspace
Every piece of data in Pitchbar belongs to exactly one workspace. Users can be members of multiple workspaces and switch between them; agents, conversations, leads, sources, and analytics never cross the boundary.
Multi-tenancy is enforced by the BelongsToWorkspace Eloquent
trait, which adds a global scope filtering every query by the current
workspace. There's a regression test (MultiTenancyTest) that
fails the build if a tenant-scoped model is queried without it.
Agent
An agent is the unit you embed. It owns a persona, system prompt, theme, starter prompts, allowed origins, behavior rules, and โ importantly โ its own knowledge sources. One workspace can have many agents (e.g. one for your marketing site, one for your help center).
Agents have a draft and a published state.
The widget runtime always reads the published version, so you can edit
freely without affecting live visitors. Each publish creates an immutable
agent_version row you can roll back to.
Knowledge source
A source is anything you want the agent to learn from: a URL, a sitemap, a feed, pasted text, a Notion page, a Google Doc, or โ when the auto-index toggle is on โ pages visitors land on. Each source produces one or more documents; documents get chunked into ~500-token pieces, embedded, and upserted into the vector store.
See Knowledge sources for the ingestion flow and RAG pipeline for how retrieval works.
Conversation
A conversation is a thread between one visitor and one agent. It survives
page reloads โ when the widget re-inits within 24 hours, we resume the
most recent conversation instead of starting a new one. Messages have
roles: user, assistant, and human-agent
(when an operator takes over from the inbox).
Lead
A lead is a visitor whose contact info you've captured (name, email, phone, plus any custom fields you defined). The widget asks for these inline when the conversation reaches a threshold of intent โ see Voice, leads & persistence. Leads dedupe on email per agent so the same person filling out the form twice doesn't create two rows.
Plan
Plans are platform-admin-managed subscription tiers (Free, Pro, etc.).
Each plan defines a monthly conversation quota and a
features blob โ currently features.remove_branding
is the only flag, but it's an open shape. Plans automatically sync to
Stripe as Products + Prices, so admins never touch the Stripe dashboard.
Hot path
"Hot path" means the visitor-message โ first-token path. It has a hard 1-second p95 latency target โ no DB writes, no synchronous webhooks, no retries. The pipeline streams tokens out, then dispatches persistence and analytics work asynchronously after the stream completes. See Hot path & latency.
Origin allow-list
The widget script is public โ anyone who finds your data-agent-id
can paste it on their own site. The /v1/widget/init endpoint
enforces a strict origin allow-list per agent: empty list denies
everywhere, otherwise exact scheme://host matching with no
subdomain inference. Allowed origins
has the rules.
Super admin vs. workspace member
A workspace member sees the customer surface (/dashboard,
/app/agents, /app/inbox, /app/billing). A super-admin
additionally sees the platform console at /admin for managing
plans, watching usage, retrying failed jobs, and impersonating customers
for support. The flag is users.role = SuperAdmin and is gated
by the EnsureSuperAdmin middleware (which returns 404, not 403,
so the panel doesn't reveal its existence).