PPactDocs
Getting started

Connect your CRM

Bring your existing accounts and contacts into Pact via Salesforce OAuth, HubSpot, Pipedrive, or a CSV upload — all tenant-scoped and deduplicated on ingest.

Pact reads your existing accounts and contacts through the Integrations surface (GET /v1/integrations), which lists a card per connector with its live connection status. Three CRM connectors are wired today — Salesforce, HubSpot, and Pipedrive — plus a CSV import wizard for everything else. Every path is tenant-scoped: a connection id only ever resolves within your own tenant, so a leaked id can't be read cross-tenant.

Import direction

These connectors are read-into-Pact (one-way) import today — they pull your CRM's accounts and contacts into Pact and dedup on ingest. Treat Pact as the destination during setup. Writing changes back out to Salesforce is a narrower, separate capability, not part of the initial connect flow.

Salesforce (OAuth)

Salesforce connects through a standard OAuth authorization-code flow.

  1. 1

    Start the connection

    From the Salesforce card, Pact calls POST /v1/integrations/salesforce/start, which returns a Salesforce authorize_url and a single-use, tenant-scoped state. You're redirected to Salesforce to grant access (scopes: api refresh_token offline_access). Toggle sandbox if you're connecting a sandbox org.

  2. 2

    Approve in Salesforce

    After you approve, Salesforce redirects to GET /v1/integrations/salesforce/callback. This endpoint is reachable without your Pact auth header (a browser redirect), but the state parameter is single-use and bound to your tenant, so it can't be replayed.

  3. 3

    Sync

    Tokens are stored encrypted. Use Sync now (POST /v1/integrations/salesforce/sync) to pull records. GET /v1/integrations/salesforce/status shows connection state, sync stats, recent runs, and how close the connected org is to its daily Salesforce API-call cap.

Disconnect any time with DELETE /v1/integrations/salesforce, which clears the stored tokens.

Encryption must be configured

Salesforce credentials are stored with envelope encryption. If the tenant's encryption key isn't configured, connecting fails closed rather than storing tokens in the clear.

HubSpot and Pipedrive

HubSpot and Pipedrive follow the same card-based model with read-only sync:

  • Connect from the card, then trigger a pull with POST /v1/integrations/hubspot/sync or POST /v1/integrations/pipedrive/sync.
  • Check state and recent run history with the matching /status endpoint.
  • Remove with the matching DELETE endpoint.

CSV import wizard

No connector? Upload a CSV through the admin import wizard (/v1/admin/imports). It's a guided, resumable flow:

  1. Upload your file and Pact sniffs the entity (contacts, accounts, etc.) from the headers.
  2. Auto-map columns to Pact fields (heuristic + AI-assisted), and optionally auto-create custom fields for columns that don't match anything.
  3. Preview the first rows, confirm the mapping and dedup rules, then start the import.
  4. Watch live progress (SSE), download an errors CSV for any failures, and roll back the whole import (soft-delete of created rows) if it wasn't what you wanted.

Download a starter template per entity from GET /v1/admin/imports/template/{entity_type}.csv. Import mutations are owner/admin only.

Leaving is as easy as arriving

Pact also supports plan-independent data portability: POST /v1/imports replays a tar.gz bundle produced by /v1/exports, idempotent on the archive's SHA-256. You can export from one tenant and re-import into a fresh free tenant — the round-trip is a deliberate freedom-to-leave guarantee.

Imported contacts do not become messageable just because the import succeeded. Each record lands with a consent status derived from your tenant's default privacy policy. Gate outbound email, SMS, and voice on that consent record — for un-opted-in contacts, use a re-engagement step before any marketing send.