> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcargo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Connectors

> Link Cargo to your CRM, warehouse, enrichment providers, and AI models with defineConnector — the foundation every model, tool, and agent builds on.

A **connector** is an authenticated link to an external system — a CRM, warehouse, enrichment API, or LLM provider. Creating one auto-provisions a **dataset** that data models source from, and exposes that integration's actions to your workflows and agents.

## Define a connector

```ts connectors/hubspot.ts theme={null}
import { defineConnector, secret } from "@cargo-ai/cdk";

export const hubspot = defineConnector("hubspot", {
  integration: "hubspot",
  config: { method: "privateApp", accessToken: secret("HUBSPOT_API_KEY") },
});
```

The `integration` slug selects which system to connect; `config` is a typed, per-integration shape (run [`cargo-ai cdk types`](/get-started/project-layout) to type it against your workspace). The connector handle carries deferred tokens — `hubspot` (the handle), `hubspot.datasetUuid` — that you pass into models and other resources.

## Secrets vs. config

Use `secret()` for credentials and `env()` for non-secret config you want tracked:

```ts theme={null}
config: { apiKey: secret("PROVIDER_API_KEY") }   // resolved at deploy, never hashed or stored
config: { region: env("PROVIDER_REGION") }        // tracked in the content hash
```

<Warning>
  Always use `secret()` — never `env()` — for credentials. `secret()` resolves
  at deploy time and is excluded from the content hash and from
  `cargo.state.json`. `env()` bakes the value into the hash, so rotating it
  reads as drift.
</Warning>

See [Secrets & environments](/reference/secrets-and-environments) for the full
`secret()` vs `env()` rules and the `CARGO_*` variables the CLI reads.

## OAuth and existing connectors

Some integrations authenticate via OAuth in the browser rather than a static key. Adopt an already-connected instance by slug instead of re-creating it:

```ts connectors/openai.ts theme={null}
import { defineConnector } from "@cargo-ai/cdk";

export const openai = defineConnector("open_ai", {
  integration: "openAi",
  adopt: true,
});
```

<Note>
  `adopt: true` links an existing connector (e.g. one authorized through an
  OAuth flow in the workspace) rather than creating a new one. A later
  `destroy` releases adopted connectors instead of deleting them.
</Note>

## Using a connector

Once defined, a connector powers three things:

* **Data models** source from its dataset — see [Models](/models/overview) and [Extractors](/models/extractors).
* **Workflows** call its actions via `integrations.<slug>.<action>()` — see [Workflows](/workflows/overview).
* **Agents** invoke its actions via `connectorActions` — see [Agents](/agents/overview).

Browse every available integration and its action slugs in the [Integrations](/integration/overview) section, or discover them live with `cargo-ai connection integration get <slug>` (or generate typed editor autocomplete with `cargo-ai cdk types`).

## From the CLI

```bash theme={null}
cargo-ai connection integration list          # available integrations
cargo-ai connection connector list            # your connected instances
cargo-ai connection connector create \
  --name "HubSpot - Prod" --slug hubspot_prod --integration-slug hubspot \
  --config '{ ... }'
```

## Using the UI

In the web app, go to **Settings → Integrations → Add connection**, pick the integration, and complete the auth flow (API key or OAuth). Connectors created in the UI can be adopted into code with `adopt: true`.

## Slug rules

Connector slugs are `snake_case` (`my_source`) and validated at define time, so a bad slug fails in `plan` rather than mid-deploy.
