Skip to content
API Reference
Attio logo

Attio

CRM

Manage contacts, companies, and relationships in Attio

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 with the user’s identity, gets back a token scoped to this resource, and uses it to call Attio directly. Identity, policy, 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.

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

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.

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}"},
)

See the OAuth SDK → Token Exchange reference for the full client API.

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

  1. Go to Attio Build
  2. Click New app
  3. Enter a Name for your app (e.g., “Keycard”) and click Create app
  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
  1. Open Keycard Console → 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

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.