How to get an Attio developer account and start working with Attio's API

Attio is quickly becoming a favorite among technical teams for its clean UI, real-time collaboration features, and powerful customizations. We use it ourselves at Stacksync!

But where Attio truly stands out is its extensibility. While many CRMs offer surface-level integrations, Attio’s API and flexible data model lets you deeply integrate and automate your customer relationship workflows. The potential use cases are unlimited.

If you're using a database like Postgres to manage customer information, syncing that data with Attio's CRM is a game changer. This guide walks you through the process of getting a developer account with Attio and building a simple integration to sync user data from your Postgres database to Attio.

How to get a developer account on Attio

Unlike Salesforce or Hubspot that lets you sign up for a sandbox/dev account automatically, you'll need to manually request developer access. Send Attio a message through their live chat, or email them at support@attio.com.

This typically takes a couple days, after which you'll get access to a developer account with seeded test data. Alternatively, you could also sign up for a free trial and use that workspace as a dev sandbox (though you'll need to seed it yourself).

Get started with Attio's API

Once you have your developer account, the next step is to create a new integration and set up authentication.

Create a new integration on Attio by clicking on your workspace logo > Workspace settings > Developers > "Create a new integration". Give it a name, description, and (optionally) an icon.

Screenshot 2024-10-18 at 2.06.45 PM.png


There are two ways to authenticate with Attio: access tokens, or OAuth. Access tokens are scoped to a single workspace, while OAuth is only required if you plan on publishing an integration.

By default, new access tokens don't have any scopes configured. You'll need to specify the scopes you need, which varies depending on the endpoints you're hitting - for example, reading a record requires both the "object configuration" and "record" scopes.

Screenshot 2024-10-18 at 2.07.44 PM.png

Set your scopes and copy your access token. Every API call must be authenticated, and your access token needs to be included in the Authorization header using Bearer. HTTP Basic Authentication is supported, but not recommended.

Now it's time for the fun part - developing with the API. Attio's API docs can be found here. Bookmark this - it's where you’ll find everything from authentication steps to object references like user and workspace.

Example: how to sync data from Postgres to Attio

Let’s walk through an example of syncing user data from a Postgres database to Attio using the API. We'll assume you have a table in Postgres storing user data.

First, write a function to connect to your PostgreSQL database, query the user information, and return the formatted results. For example:

import psycopg2

def fetch_postgres_users():
    try:
        # Set up your PostgreSQL connection
        conn = psycopg2.connect(
            dbname="your_dbname",
            user="your_user",
            password="your_password",
            host="your_host",
            port="your_port"
        )
        cursor = conn.cursor()

        # Query to get user data
        cursor.execute("SELECT email, first_name, last_name, job_title FROM users")
        rows = cursor.fetchall()

        # Transform rows into a list of dictionaries
        users = [
            {
                "email": row[0],
                "first_name": row[1],
                "last_name": row[2],
                "job_title": row[3]
            }
            for row in rows
        ]

        # Close connections
        cursor.close()
        conn.close()

        return users

    except Exception as e:
        print(f"Error fetching users: {e}")
        return []

users = fetch_postgres_users()
for user in users:
    print(user)

Now loop through each user and either create or update the corresponding user record in Attio using the assert endpoint. Records need to be matched with a matching_attribute query parameter. This is typically the user's email or UUID.

import requests

API_URL = "https://api.attio.com/v2/objects/users/records"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"

def sync_user_to_attio(user):
    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "Content-Type": "application/json"
    }
    
    payload = {
        "email_address": user["email"],
        "first_name": user["first_name"],
        "last_name": user["last_name"],
        "job_title": user["job_title"]
    }
    
    params = {
        "matching_attribute": "email_address"
    }
    response = requests.put(API_URL, json=payload, headers=headers, params=params)
    
    if response.status_code == 200:
        print(f"User {user['email']} synced successfully.")
    else:
        print(f"Failed to sync user {user['email']}: {response.status_code} - {response.text}")

users = fetch_postgres_users()
for user in users:
    sync_user_to_attio(user)

To associate users to a workspace, you can use the workspace attribute on user to link them.

Common roadblocks when using Attio's API

Rate limits

Like most APIs, Attio has rate limits:

  • 100 requests/second for read requests
  • 25 requests/second for write requests

Exceeding the rate limit will throw HTTP status code 429 with a special response:

HTTP/1.1 429 Too Many Requests
Retry-After: Tue, 23 May 2023 14:42:01 GMT
Content-Type: application/json

{
"status_code": 429,
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded, please try again later"
}

If you're syncing large amounts of data, batch requests and implement exponential backoff to avoid rate limit issues.

Referencing records

Attio doesn't automatically create referenced records - the record you're referencing must exist, or the request will fail. This is problematic when asserting records, because you don't know if the reference exists yet.

To resolve this, you'll need to write in reverse-order: create the workspace first, then assert the person.

Accelerate your Attio integration with Stacksync

While building a custom sync from Postgres to Attio using the API is powerful, it can get complex as you scale. That’s where Stacksync comes in.

Stacksync enables you to create no-code, bi-directional syncs between Attio and your Postgres database (or any other system, including BigQuery and Snowflake) without worrying about rate limits or API changes. This frees up your development time to focus on higher-value tasks.

  • Bi-directional syncs: Sync not only from a database to Attio but also from Attio back to your database, ensuring data consistency across systems.
  • Real-time updates: Stacksync automatically keeps Attio in sync with your latest user data, ensuring that your sales and customer success teams are always working with the freshest information.

By leveraging a tool like Stacksync, you can simplify and automate much of the integration work while ensuring that your data remains up-to-date in real-time.

Connect every tool

Create a free account, or book a demo to start building syncs and workflows.