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

# Connections

> Connected third-party accounts for a persona — auth configs, the Connect Link, and revocation.

> [!NOTE]
>
> A connection lets an [identity](https://vetta.sh/docs/api/identities.md) act in a third-party account the organization has authorized. There is **no fixed list of supported apps** — search the catalogue.

Three calls, in this order:

1. **Find the app.** `GET /v1/connections/apps?search=…` searches the catalogue — over a thousand apps — and answers with the `slug` every later call takes as `connector`.
2. An **auth config** is org-level and says *how* that app authenticates. Created once, shared by every identity that connects it.
3. A **connection** is identity-level: the connected account itself, minted against an auth config.

A connected account is the **provider's** object, not a row held here — a read reconciles state against the provider before answering.

## Apps

### The app object

**object** `string`

Always `connection_app`.

**slug** `string`

The app's id. This is what `connector` takes.

**name** `string`

The app's display name.

**description** `string`

One line about what the app is.

**categories** `string[]`

What the app is used for — e.g. `customer-support`, `crm`.

**auth** `string[]`

Which setup paths work for this app. `managed_oauth` means one call and no credentials of your own; `oauth` means registering an app with the vendor first; `api_key` means the person authorizing types a key on the hosted page.

**tool\_count** `number`

How many operations the app publishes in total.

### Search apps

`GET /v1/connections/apps` — scope `agents:read`

**search** `string`

Matches an app's name, id or description. Omit it to list the most-used apps.

**limit** `number`

Page size, 1–100.

**after** `string`

The `next_cursor` of the previous page. Opaque — it is not a row id.

```bash cURL theme={"system"}
curl -fsSL "https://api.vetta.sh/v1/connections/apps?search=helpdesk" \
  -H "authorization: Bearer sk_live_..."
```

```json Response theme={"system"}
{
  "object": "list",
  "data": [
    {
      "object": "connection_app",
      "slug": "zendesk",
      "name": "Zendesk",
      "description": "Customer support software with ticketing, live chat and a knowledge base.",
      "categories": ["crm", "customer-support"],
      "auth": ["managed_oauth", "oauth"],
      "tool_count": 12
    }
  ],
  "has_more": true,
  "next_cursor": "Mi0z"
}
```

### Retrieve an app

`GET /v1/connections/apps/{slug}` — scope `agents:read`

Everything the two setup calls need before either is made. `not_found` (404) for an id the catalogue does not know — this is what replaced the old connector enum.

**default\_tools** `string[]`

The operations an auth config pins when `tools` is not given.

**connect\_fields** `object[]`

What the person authorizing must still supply — an account subdomain, a region, a workspace. Each has `name`, `label`, `description` and `required`. Pass them to `POST /v1/connections` as `fields`, or leave them and the hosted page asks.

```json Response theme={"system"}
{
  "object": "connection_app",
  "slug": "zendesk",
  "name": "Zendesk",
  "auth": ["managed_oauth", "oauth"],
  "tool_count": 12,
  "default_tools": ["ZENDESK_LIST_ZENDESK_TICKETS", "ZENDESK_REPLY_ZENDESK_TICKET"],
  "connect_fields": [
    { "name": "subdomain", "label": "Subdomain", "description": "the part before .zendesk.com", "required": true }
  ]
}
```

### Retrieve an app's logo

`GET /v1/connections/apps/{slug}/logo` — scope `agents:read`

The app's logo as image bytes, not JSON: the response carries the image's own `content-type` and `cache-control: public, max-age=86400`, so it can sit directly in an `<img>` tag. The app object itself carries no logo URL. `not_found` (404) when the catalogue has no image for the app.

## Auth configs

### The auth config object

**id** `string`

Unique id (e.g. `ac_01H...`).

**object** `string`

Always `auth_config`.

**connector** `string`

The app this config authenticates — an app `slug`.

**auth** `string`

`managed_oauth`, `oauth`, or `api_key`.

**scopes** `string[]`

The scopes the config actually carries, read back after creation — not the ones requested.

**tools** `string[]`

The operations a connection made from this config may call. Everything else is refused.

**connect\_fields** `object[]`

What `POST /v1/connections` will still be asked for. Same shape as on the app.

**created\_at** `string`

Creation timestamp.

### Create an auth config

`POST /v1/connections/auth_configs` — scope `agents:write`

**connector** `string` *required*

An app `slug` from the catalogue.

**auth** `string`

`managed_oauth` (default), `oauth`, or `api_key`. Check the app's `auth` first — not every app offers every path.

**scopes** `string[]`

Scopes to request. Ignored where the app's managed OAuth app is registered with a fixed set.

**tools** `string[]`

Pin the callable operations. Omitted, the app's `default_tools` are pinned. This is a hard boundary — anything not pinned does not exist to the agent.

**client\_id** `string`

Your own OAuth client id. Required when `auth` is `oauth`.

```bash cURL theme={"system"}
curl -fsSL https://api.vetta.sh/v1/connections/auth_configs \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{ "connector": "zendesk", "auth": "managed_oauth" }'
```

```json Response theme={"system"}
{
  "id": "ac_01H9CN...",
  "object": "auth_config",
  "connector": "zendesk",
  "auth": "managed_oauth",
  "scopes": ["tickets:read", "tickets:write"],
  "tools": ["ZENDESK_LIST_ZENDESK_TICKETS", "ZENDESK_REPLY_ZENDESK_TICKET"],
  "connect_fields": [
    { "name": "subdomain", "label": "Subdomain", "description": "the part before .zendesk.com", "required": true }
  ],
  "created_at": "2026-08-20T17:10:00Z"
}
```

### List auth configs

`GET /v1/connections/auth_configs` — scope `agents:read`. Returns a [paginated list](https://vetta.sh/docs/api/pagination.md).

### Delete an auth config

`DELETE /v1/connections/auth_configs/{id}` — scope `agents:write`. Connections already minted against it stop refreshing.

## Connections

### The connection object

**id** `string`

Unique id (e.g. `ca_01H...`).

**object** `string`

Always `connection`.

**auth\_config\_id** `string`

The auth config it was minted against.

**identity\_id** `string`

The persona that acts in the account.

**connector** `string`

The app the account is in — an app `slug`.

**status** `string`

`initiated` — minted, waiting for someone to complete the Connect Link.
`active` — authorized and usable.
`failed` — authorization did not complete.
`disconnected` — the stored credential was dropped.

**status\_reason** `string | null`

Why a `failed` or `disconnected` account got there.

**connect\_link** `string | null`

The hosted authorization URL. Present only while `initiated`.

> [!WARNING]
>
> **This URL is not on a Naive Managed Agents domain.** The authorization page is served by the connection provider, on the provider's own host, carrying the provider's name and a "Secured by" badge. Hand it to an end user; do not treat it as part of your product's surface. See [Connections](https://vetta.sh/docs/identity/connections.md) for what the provider's own white-labelling does and does not cover.

**connect\_link\_expires\_at** `string | null`

When that link stops working.

**last\_refreshed\_at** `string | null`

Last successful credential refresh.

**created\_at** `string`

Creation timestamp.

### Connect an account

`POST /v1/connections` — scope `billing:write`

Mints the connected account and its Connect Link; the account starts `initiated`. This is `billing:write` on the wire and not `agents:write` because a managed account is a per-account charge at the provider.

**auth\_config\_id** `string` *required*

The `ac_` config to mint against.

**identity** `string` *required*

The `idn_` identity that will act in the account.

**fields** `object`

Values for the config's `connect_fields`, e.g. `{ "subdomain": "acme" }`. Omitted, the hosted page asks the person instead — so this is a convenience, never a gate.

```bash cURL theme={"system"}
curl -fsSL https://api.vetta.sh/v1/connections \
  -H "authorization: Bearer sk_live_..." \
  -H "content-type: application/json" \
  -d '{ "auth_config_id": "ac_01H9CN...", "identity": "idn_01H...", "fields": { "subdomain": "acme" } }'
```

```json Response theme={"system"}
{
  "id": "ca_01H9CQ...",
  "object": "connection",
  "auth_config_id": "ac_01H9CN...",
  "identity_id": "idn_01H...",
  "connector": "zendesk",
  "status": "initiated",
  "status_reason": null,
  "connect_link": "https://<provider-host>/link/...",
  "connect_link_expires_at": "2026-08-20T18:10:00Z",
  "last_refreshed_at": null,
  "created_at": "2026-08-20T17:10:00Z"
}
```

**Errors** — `validation_failed` (400) when `identity` is not an `idn_` id or `auth_config_id` is not an `ac_` id; `not_found` (404) for an unknown auth config or identity; `insufficient_scope` (403) without `billing:write`; `insufficient_credits` (402).

### List connections

`GET /v1/connections` — scope `agents:read`

**identity** `string`

Filter to one persona.

Returns a [paginated list](https://vetta.sh/docs/api/pagination.md) of connection objects.

### Retrieve a connection

`GET /v1/connections/{id}` — scope `agents:read`

Reconciles status against the provider before answering — **this read is the refresh**. Poll it to watch an `initiated` account become `active`, rather than assuming the Connect Link was completed. There is no `connection.*` webhook yet, so polling this route is the only way to learn that a person finished authorizing.

### Disconnect

`DELETE /v1/connections/{id}` — scope `agents:write`

Revoke. The provider drops the stored credential and every later call through the connection is refused. Returns the standard deleted envelope.

```json Response theme={"system"}
{ "id": "ca_01H9CQ...", "object": "connection", "deleted": true }
```

> [card] [Identities](https://vetta.sh/docs/api/identities.md)
>
> The persona a connection is bound to.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.