---
title: Attio | Keycard
description: Manage contacts, companies, and relationships in Attio
---

[Attio developer console](https://build.attio.com/)[OAuth setup guide](https://docs.attio.com/rest-api/tutorials/connect-an-app-through-oauth)[API docs](https://docs.attio.com/rest-api/overview)

Adding Attio provisions a resource (the upstream Attio API at `https://api.attio.com`, with default scopes pre-set) and a provider for Attio’s OAuth issuer - auto-provisioned on first install, or reused if you already connected another Attio resource.

Your application calls Keycard’s [token-exchange endpoint](/sdk/oauth/index.md) with the user’s identity, gets back a token scoped to this resource, and uses it to call Attio directly. Identity, [policy](/admin/access-policies/index.md), and audit log apply to every exchange - the OAuth client secret stays inside Keycard. Each exchange is recorded in the audit log with the user identity, the resource accessed, and the policy decision.

## Scopes

SCOPES

OAuth permissions Keycard requests on install. Override or add scopes in Console.

- record\_permission:read

  default

- list\_entry:read

  default

- user\_management:read

- user\_management:read-write

- record\_permission:read-write

- object\_configuration:read

- object\_configuration:read-write

- list\_entry:read-write

- list\_configuration:read

- list\_configuration:read-write

- public\_collection:read

- public\_collection:read-write

- private\_collection:read

- private\_collection:read-write

- comment:read

- comment:read-write

- task:read

- task:read-write

- note:read

- note:read-write

- meeting:read

- meeting:read-write

- call\_recording:read

- call\_recording:read-write

- webhook:read

- webhook:read-write

- file:read

- file:read-write

- scim\_management:read

- scim\_management:read-write

Show all 30 scopes  Show defaults only

## Use Attio from your code

USE FROM CODE

Call Attio from your application with a Keycard-issued token scoped to this resource.

After installing Attio, your application exchanges a Keycard-issued access token for a token scoped to this resource. Pass the user’s access token as the `subject_token`.

- [Python](#tab-panel-108)
- [TypeScript](#tab-panel-109)

```
from keycardai.oauth import Client, BasicAuth, TokenType
import requests


# Exchange the user's Keycard token for a Attio token.
with Client(
    "https://<zone-id>.keycard.cloud",
    auth=BasicAuth("<your-client-id>", "<your-client-secret>"),
) as client:
    response = client.exchange_token(
        subject_token=user_access_token,
        subject_token_type=TokenType.ACCESS_TOKEN,
        resource="https://api.attio.com",
    )


# Call Attio directly with the exchanged token.
r = requests.get(
    "https://api.attio.com/<endpoint>",
    headers={"Authorization": f"Bearer {response.access_token}"},
)
```

```
import { TokenExchangeClient } from "@keycardai/oauth/tokenExchange";


const client = new TokenExchangeClient("https://<zone-id>.keycard.cloud", {
  clientId: "<your-client-id>",
  clientSecret: "<your-client-secret>",
});


const response = await client.exchangeToken({
  subjectToken: userAccessToken,
  resource: "https://api.attio.com",
});


// Call Attio directly with the exchanged token.
const res = await fetch("https://api.attio.com/<endpoint>", {
  headers: { Authorization: `Bearer ${response.accessToken}` },
});
```

See the [OAuth SDK → Token Exchange](/sdk/oauth/#token-exchange/index.md) reference for the full client API.

## Setup

SETUP

Register your OAuth credentials with Keycard so the resource can issue tokens.

### Create an Attio app

1. Go to [Attio Build](https://build.attio.com/)
2. Click **New app**
3. Enter a **Name** for your app (e.g., “Keycard”) and click **Create app**

### Enable OAuth and get credentials

1. Go to the **OAuth** tab
2. Toggle **OAuth** on to enable it
3. Copy the **Client ID** and **Client Secret**
4. Under **Redirect URIs**, click **New redirect URI** and add the redirect URI provided by Keycard
5. Under **Scopes**, click **Configure scopes** and add the scopes your app needs

### Register in Keycard

1. Open [Keycard Console](https://console.keycard.ai) → your zone → **Resources**

2. Click **Explore Resources**

3. Find and click **Attio** in the catalog

4. In the configuration dialog:

   - Enter the **Client ID** and **Client Secret** from your Attio integration
   - Review the **User scopes** - the defaults (`record_permission:read`, `list_entry:read`) are pre-populated

5. Click **Add Attio CRM API**

Tip

The `/v2/self` endpoint returns information about the currently authenticated user, including their workspace. It’s what Keycard pings when you add the resource to confirm scopes and credentials are wired correctly.

## Troubleshooting

TROUBLESHOOTING

Common errors when wiring Attio into your zone.

Error 401: Unauthorized

The access token is invalid or expired. Try re-connecting the provider. If the issue persists, check that:

- The OAuth credentials match between Keycard and Attio Build
- The integration is still active in your Attio workspace

Error 403: Insufficient scope

The token doesn’t have the required scopes. Verify the scopes in your Attio integration settings match those configured in Keycard Console.

## Related

RELATED

- [Catalog overview](/admin/catalog/index.md) - browse other API and MCP servers
- [Access policies](/admin/access-policies/index.md) - control who can use Attio
- [Identity providers](/admin/identity-providers/index.md) - control who can sign in

[NextConfluence](/admin/catalog/api-servers/confluence/index.md)
