<!-- Markdown rendering of https://salesascode.com/docs/library/connect. The HTML page is canonical. -->

# Connect your tools · Docs · Sales as Code

[← All feature docs](https://salesascode.com/docs/library)

Feature docs · /settings/connect

# Connect your tools

Link your CRM, inbox, and calendar in the product. We custody the token encrypted and read it on a schedule, and the work runs on our servers. There is nothing to install. Output is draft-first: nothing is sent without your approval.

[Open Connect your tools →](https://salesascode.com/settings/connect) [All docs](https://salesascode.com/docs/library)

## Overview

Sales as Code runs the work for you on a schedule, on our servers. There is nothing to install: no desktop app, no plugin, no marketplace. You connect your tools once, we custody the token, and the scheduled runs read your book and draft the work. [Connect](https://salesascode.com/settings/connect) is where you link those tools and watch each one turn healthy.

Power users who want to drive the account from their own scripts or an MCP client can still issue a key. That path moved to **Settings, Advanced**, see [API Keys & MCP](https://salesascode.com/docs/library/api-keys). It is optional and not the main flow.

## What it shows

- **Your plan.** All-Access, a la carte, or nothing yet, plus the exact products you are licensed for and their license details (source and expiry).
- **Get connected (live).** A short checklist, licensed, tools connected, first run, that verifies itself in real time. The page watches your account and checks each step off the moment it happens, including the first scheduled run. No refresh needed; when the loop closes you get a green confirmation.
- **Product health.** Every product you own and whether it is actually working: "Healthy", "Not started yet" (bought but never run, the thing to act on), or "Last run failed".
- **Connection state.** Each connected tool with its last sync time, and a **Sync now** button to pull your book immediately. When a tool's authorization expires or you revoke it at the provider, the next scheduled read notices and flips that tool to **needs reconnect** on its own, so a dead login surfaces as a clear reconnect prompt instead of a connection that quietly stops syncing.
- **Reconnect needed is its own badge.** A dead authorization and a bad afternoon at the provider are different problems, so the panel stops drawing them the same way. A revoked or expired grant gets an amber **reconnect needed** badge and one line telling you to reconnect. A rate limit or a provider outage stays a plain error and clears itself; you do not need to touch it. The card no longer shows you the provider's raw message, which named an HTTP status and no remedy.
- **A credential we can no longer read counts as needs reconnect.** If the key your tokens are stored under is rotated, the stored credential stops decrypting. Nothing has failed yet, because nothing has tried, so there is no error to show. The panel used to read a healthy green **connected** in that state. It now says reconnect, which is what actually has to happen.

## Where to find it

**Settings, then Connections.** One tab, one page. It used to be two, "Connections" and "Advanced", and they landed you in the same place by way of a redirect. Everything is on this page now: the managed connectors below, and the power-user path (an API key, MCP, a self-hosted n8n kernel) further down.

## Connect your CRM, inbox, and calendar

The [Connect](https://salesascode.com/settings/connect) page carries a **managed connectors** panel. Link Salesforce, HubSpot, Gmail, or Google Calendar directly in the browser. We custody your OAuth token, encrypted and isolated to your tenant, poll it on a schedule, and fill your *accounts*, *opps*, and *contacts* server-side. The panel shows each provider's connection state and last sync, and **Sync now** pulls your book on demand.

This is opt-in, per account, and reversible. You can revoke a connection at any time. A security-strict team can leave it off and drive the account through the advanced API path or its own n8n instead. The same panel appears in every [persona console](https://salesascode.com/docs/library/persona-console) under Settings.

## Connecting HubSpot with a private-app token

HubSpot is the one connector with no OAuth handshake, so instead of a Connect button it takes a private-app token. Click Add token on the HubSpot card, paste the token, and save. We encrypt it at rest and read it on the schedule exactly like an OAuth token, and Replace token swaps it later.

The token is checked with HubSpot before it is saved. A wrong token, or one whose private app is missing the CRM read scope, is refused on the spot with HubSpot's own explanation, so you find out now rather than days later when nothing has synced.

If HubSpot cannot be reached at that moment (an outage, a rate limit, a timeout), the token is saved anyway and the panel says the check did not complete. Their bad day should not stop you connecting, and the next scheduled poll records a real error on the card if the token does turn out to be wrong.

## Where the output lands

Every run drafts first. Nothing goes out on your behalf. You choose where the drafts land:

- **In-app draft queue.** Drafts wait for your review in the product. Approve, edit, or skip each one.
- **Google Drive.** Turn on Drive delivery and each run also writes its report into your Drive "Accounts" folder as a Google Doc plus a raw `.md` copy, so you read it where you already work.
- **Your mailbox as a draft.** A drafted email lands in your own mailbox as a Gmail draft, ready for you to send. Writing a draft into your own mailbox is not an outbound send.

## Alerting and admin-gated connectors

Two more kinds of connector sit alongside your CRM and mailbox:

- **Alerting: Slack and Microsoft Teams.** Connect a Slack bot token or a Teams Incoming Webhook and a scheduled run can post a deal-risk flag or a run summary into your channel. Alerting only, and it posts into your own workspace, never to a customer.
- **Admin-gated: Gong.** Gong API access is enabled by a Gong administrator, so it shows a *connect your admin* badge rather than a plain Connect button. Ask your Gong admin to approve the integration and enable API access, then connect. The same holds for other admin-enabled tools as they land.

## Enterprise Salesforce access (behind SSO / Okta)

Okta gates the human login to the Salesforce UI, not the API. There are four rungs, and writes stay propose-and-apply on every one, never a silent write-back:

- **OAuth Connected App.** Per-user consent that redirects cleanly through Okta. The self-serve default, already wired.
- **Admin-approved Connected App.** An admin pre-authorizes the app and attaches a permission set, for locked orgs.
- **JWT bearer.** Server-to-server, no interactive login: the admin uploads a certificate once and the runtime exchanges a signed assertion for a token. For headless enterprise jobs.
- **CSV / report export.** The no-API fallback, and the only data-in path that needs no OAuth at all. Export your accounts or opportunities from Salesforce as CSV and upload them on the Connect page. Re-importing the same export updates in place rather than duplicating. See Importing a CRM report export below.

## Importing a CRM report export

If your org will not grant API access at all, you do not need it. Export what you need from the CRM as CSV and upload it from the **No API access? Import a CRM report export** card on the Connect page. Pick whether the file holds opportunities or accounts, choose the file, and import. The rows land in the same store the connectors fill, so every surface that reads your stored book works exactly as it would with a live connection.

This is data in only. Nothing here writes back to your CRM; a write back stays propose-and-apply on every path.

### What the file needs

- **An id column.** `Id`, `Opportunity ID`, `Account ID`, `Record ID` and the 18-character variants are all recognised. A row with no id is skipped and counted, never guessed at, and the count is reported back to you.
- **Whatever else your report carries.** Column names are matched case and space insensitively against the ones the analytics read: stage, amount, close date, owner, industry, segment, lead source, competitor, region and loss reason for opportunities; ARR, renewal date, churn risk, status and the prior, renewed and expansion ARR figures for accounts. A money column can carry a currency symbol, thousands separators, or a parenthesised negative.
- **Nothing else.** Your original column headers are stored alongside, unchanged, so a stored row still reads the way your export did.

### What you get back

The card reports how many rows were imported and how many were skipped. Those are different findings and it says which: a file where every row was skipped tells you the export is missing its id column, not that the import failed.

Importing is idempotent. Re-uploading the same export updates the same rows rather than creating duplicates, so a weekly report export is a reasonable habit.

### What it feeds

An imported book drives the stored-data side of attribution, win/loss, data quality, the Revenue Cockpit prefill, renewals, and deal inspection. Each of those tells you what it could not compute and why, so a partial export gives you the numbers it can support and a plain reason for the rest rather than a blank page.

## Role-specific connectors and honest fallbacks

Each role has its own must-have tools. Where a vendor is open, you self-connect; where it is gated or closed, the badge says so and names the fallback:

- **CSM:** a Customer Success Platform (Planhat, or Gainsight behind connect-your-admin) federates CRM plus usage in one connection.
- **Partner:** Crossbeam for account overlaps and sourced pipeline.
- **SE:** a demo tool (Consensus) and an RFP tool (Responsive). RFP tools are import/export first, so Responsive is gated with an import fallback rather than promised as live sync.
- **Data:** Apollo and Cognism are the self-serve enrichment connectors. ZoomInfo is offered only to accounts that own the seat (enterprise-gated).
- **LinkedIn Sales Navigator** is CSV import only. The SNAP partner program is closed in 2026, so live sync is never promised; import your export instead.

## Guided setup, /onboarding

Prefer to be walked through it? [Get started](https://salesascode.com/onboarding) is the guided version of this page: the same checks (Licensed, Tools connected, First run), one step at a time, verified live against your account. It carries the **Connect your tools** panel, so you can link a CRM, inbox, or calendar during onboarding. It walks you through setting up your product's schedule and picking where drafts land. The moment your first run lands, the wizard closes the loop and points you at [Activity](https://salesascode.com/rollup). Both surfaces read the same activation state, so a step checked off here is checked off there.

## How to use it

- Pick your role's product on the [pricing page](https://salesascode.com/pricing). Buying gtmcron a la carte adds Company OS Core automatically.
- Open [Connect](https://salesascode.com/settings/connect) and link your CRM, inbox, and calendar in the managed-connectors panel. We custody each token encrypted and read it on a schedule.
- Set your product up: the guided wizard interviews you, builds your company context, and proposes the scheduled runs.
- Choose where drafts land: the in-app queue, your Google Drive, or your mailbox as a draft.
- As runs happen, run telemetry and brain state fill up. Watch [Activity](https://salesascode.com/rollup) from your [Home](https://salesascode.com/home).

## When the connector panel cannot load

A network failure or an expired session used to leave the managed-connector panel on "Loading connectors…" indefinitely. It now says what went wrong, offers a retry, and states plainly that a load failure is not the same as having no connections, so nothing about your connected tools has changed.

Turning managed connectors on or off tells you if the change did not save. The toggle springs back to where it was, which on its own would look like the click never registered.

## Troubleshooting, the Diagnose panel

Both [the wizard](https://salesascode.com/onboarding) and [Connect](https://salesascode.com/settings/connect) include a **Diagnose** panel that checks the common failure modes live against your account and tells you the exact fix:

- **No tools connected**, the runtime has nothing to read. Link a CRM, inbox, or calendar in the managed-connectors panel.
- **Connection expired**, a token was revoked or rotated at the provider. The next scheduled sync detects the rejected credential and flips the tool to this reconnect state, so it surfaces here instead of stalling silently. Reconnect the affected tool; the panel names which one.
- **Connection gone stale**, a tool authenticated before but has not synced in 7 days. Reconnect it.
- **Entitlement mismatch**, your account is not licensed for a product on this email (bought under a different email, or refunded). Runs stop at the entitlement check.
- **Connected but never run**, tools are linked but no scheduled run has happened yet. Finish setup so the schedule can start.
- **Denied / errored runs**, failing runs from the last 7 days, with the most recent error message.

The panel footer shows your last scheduled run from the audit log, product, status, and how long ago, so you can tell "never connected" from "was working until Tuesday".

## Manage your plan and billing

**Settings, Account** has a "Your products" panel (the "on cron" products you own, linking to [My products](https://salesascode.com/docs/library/products-hub)) and a "gtmcron plan" panel: the products you own with their source and expiry, an upgrade to All-Access, and a "Billing & invoices" button that opens the Stripe portal to view invoices, change payment, or cancel. All-Access unlocks every gtmcron product, including ones shipped later.

## Team & seats

On a team plan, **Team, Members** lets the owner invite teammates up to the seat count. Each pending invite can be re-sent or shared as a direct copy-link if the email is missed, no need to contact support. Teammates accept with one click and their seat is covered by the team subscription.

## Advanced: drive it yourself (API + MCP)

The default flow needs no key. If you want to run the account from your own scripts, a cron, or any MCP-compatible agent, issue a Bearer token under **Settings, Advanced** and point the client at the tenant-scoped MCP endpoint. Every skill verifies your licensed session first, then reads and writes the same store the product uses. Full detail: [API Keys & MCP](https://salesascode.com/docs/library/api-keys). This is a power-user option, not a requirement.

The work runs on our servers, so we process the data you connect. It is encrypted at rest, isolated to your tenant, never sold, and never used to train models, and you can revoke a connection at any time. Run telemetry is metadata; generated drafts hold content, and they stay in your account until you send them.

## Related

- [API Keys & MCP](https://salesascode.com/docs/library/api-keys), the advanced path for power users who want to drive the account from their own client.
- [Activity](https://salesascode.com/docs/library/rollup), the rollup of what your scheduled runs produced.
- [Pricing](https://salesascode.com/pricing), the products, bundles, and All-Access membership.

---

More for agents: [llms.txt](https://salesascode.com/llms.txt), [full reference](https://salesascode.com/llms-full.txt), [OpenAPI](https://salesascode.com/openapi.json), [sitemap](https://salesascode.com/sitemap.xml).
