PPactDocs
Reference

FAQ

Straight answers about what Pact is, how tenancy and consent work, where your data lives, bring-your-own-key AI, billing, and migration.

Honest, specific answers to the questions we get most. Where a capability is partial or still landing, we say so rather than rounding up.

What is Pact?

A consent-native, multi-tenant CRM that also covers marketing, ETL/data centralization, tracking, and voice. The backend is FastAPI with strict tenant isolation and RBAC; the web app is Next.js 14. It's positioned as production-grade competition for Salesforce, HubSpot, Marketo, and Adobe — with consent treated as a first-class property of every contact and channel rather than a bolted-on checkbox.

How does multi-tenancy work? Can one tenant see another's data?

No. Every request derives its tenant_id from the authenticated session, never from a request body or URL, and every query is tenant-scoped. User-facing identifiers are UUID public_id values, not the internal integer primary keys — so even a leaked identifier can't be walked or probed across tenants. Auth runs on its own isolated database pool because it's a critical path.

Consent is stored per contact per channel and is enforced on the send path, not just displayed. A contact who hasn't consented to email won't be mailed by a sequence even if they're in the audience; blocked sends are recorded rather than silently dropped. Consent state travels with the record, including on import — see the migration guide.

Where does my data live?

Postgres (Neon in production) for structured data; object storage for blobs like recordings, voicemails, and export bundles. The current platform blob backend is Tigris, with Cloudflare R2 still supported for existing configs. Which database and storage a deployment uses is set by the operator through environment variables (DATABASE_URL, the TIGRIS_* / R2_* families) — see Environment variables.

Can I bring my own AI keys (BYOK)?

Yes. AI providers can be configured per tenant through the settings UI, and those keys are stored encrypted in the database — not in shared environment variables. Where a tenant hasn't supplied a key, platform fallback behavior is governed by explicit switches (for example ANTHROPIC_FALLBACK_TO_ENV) rather than silently billing you against a shared key. Embeddings default to a no-op backend until a provider (e.g. Voyage) is configured.

Credentials go through the UI, never the docs

The correct place to enter any provider key — AI, email, telephony — is the in-app settings/BYOK flow, which encrypts and scopes it to your tenant. Don't paste secrets into config files or share them; the platform is designed so you never have to.

How does email sending work — will it send for real out of the box?

No, and that's deliberate. The sequence send path defaults to sandbox (SEQUENCE_PROVIDER=sandbox): messages are rendered, recorded, and visible, but not delivered. Real delivery requires an operator to select a provider (resend or sendgrid), configure its credentials, and clear the global kill switch. This keeps a fresh environment from accidentally mailing real people.

How is billing handled?

Billing is provider-pluggable and off by default (BILLING_PROVIDER=noop). When Stripe is enabled, usage is metered against configured price IDs, with trial credits and AI/enrichment budget caps enforced server-side (e.g. TRIAL_FREE_CREDIT_CENTS, TRIAL_AI_CAP_CENTS, per-tenant enrichment budgets). Metering failures return a clear 402 rather than silently overspending.

Can I import from Salesforce or HubSpot?

Yes — two ways. A CSV import wizard (accounts, contacts, deals, and more) with Claude-assisted column mapping and dedup, and native connectors for Salesforce, HubSpot, and Pipedrive. Salesforce uses a three-legged OAuth flow with a 30-minute background sync; HubSpot and Pipedrive connect with an API token (HubSpot Private App token, Pipedrive API token) and sync on demand. Full walkthrough in the Migration guide.

Is there a voice / phone feature?

Yes, and it's substantial — inbound and outbound calling, an autonomous voice MCP agent, recording with consent, transcription, and analytics. It's also the most flag-gated surface in the product (VOICE_ENABLED and a family of VOICE_* switches), because different pieces roll out on different timelines. If a specific voice capability isn't visible in your environment, it's likely gated off rather than absent.

Not everything is live everywhere

Pact is under active build. Some admin, data-pipeline, and social surfaces are intentionally staged — where a screen is a preview of intended capability rather than an enforced backend, the relevant doc page labels it as roadmap. If you need to confirm a capability is enforced end-to-end for a purchasing decision, ask support directly.

Is there an API and SDK?

Yes. The REST API is the product's contract; the OpenAPI spec (api/openapi.json) is the source of truth, and typed clients are generated from it rather than hand-written. See the API and SDK docs.

Can I self-host?

The stack is built to run on Azure/Fly with Postgres, Redis, object storage, and a secrets backend, all driven by environment variables — so a self-managed deployment is mechanically possible. It isn't a one-click, officially supported distribution today; treat self-hosting as an operator project, and read Environment variables first.