attio-interaction
The attio-interaction skill enables reading and writing Attio CRM data through the REST API v2. Use it to query or filter records, upsert companies, people, and deals with matching attributes, write notes and tasks, manage list entries, and handle webhooks. Authentication uses ATTIO_API_KEY as a Bearer token. Access this skill whenever your agent swarm needs to interact with Attio CRM data directly without maintaining a separate sync.
git clone --depth 1 https://github.com/desplega-ai/agent-swarm /tmp/attio-interaction && cp -r /tmp/attio-interaction/templates/skills/attio-interaction ~/.claude/skills/attio-interactionSKILL.md
# Attio Interaction (Read + Write)
Use this skill to read and write your Attio CRM through the REST API v2. Every read or write is a direct API call; agent-swarm does not maintain a separate Attio sync.
## TL;DR
1. Resolve `ATTIO_API_KEY` from swarm config before making calls.
2. Base URL: `https://api.attio.com/v2/`
3. Use `Authorization: Bearer $ATTIO_API_KEY`, `Content-Type: application/json`, and `Accept: application/json`.
4. Prefer upsert over create for People, Companies, and Deals: `PUT /v2/objects/{slug}/records` with `matching_attribute`.
5. Rate limits: 100 reads/sec, 25 writes/sec. Pace write bursts to roughly 15-20/sec.
6. Attribute values are arrays, even for scalar values: `[{ "value": 42 }]`, never `42`.
## Authentication
```bash
ATTIO_API_KEY=$(get-config key="ATTIO_API_KEY" includeSecrets=true)
curl -sS "https://api.attio.com/v2/objects" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Accept: application/json"
```
If calls return `401`, re-fetch the key from config. If it still fails, notify the Lead; the key may need rotation. Do not retry silently.
## Core object slugs
| Object | API slug | Primary matching attribute |
|---|---|---|
| Companies | `companies` | `domains` |
| People | `people` | `email_addresses` |
| Deals | `deals` | Usually no global dedupe key; link to company/person records |
Custom objects use their configured API slug. Discover them with `GET /v2/objects`.
## Common operations
### 1. Discover objects and slugs
```bash
curl -sS "https://api.attio.com/v2/objects" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Accept: application/json" \
| jq '.data[] | {slug: .api_slug, name: .title}'
```
### 2. Query records with filters and pagination
```bash
curl -sS -X POST "https://api.attio.com/v2/objects/companies/records/query" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"stage": { "$not_equal": "Won" }
},
"limit": 100,
"offset": 0
}' | jq '.data[] | {record_id: .id.record_id, name: .values.name[0].value}'
```
Paginate by increasing `offset` until `data` is empty. For no filter, omit the `filter` key.
### 3. Get a single record
```bash
curl -sS "https://api.attio.com/v2/objects/companies/records/{RECORD_ID}" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Accept: application/json" \
| jq '.data.values'
```
### 4. Upsert a company by domain
Use `PUT` with `matching_attribute`. It creates if not found and updates if found, so it is safe to call repeatedly.
```bash
curl -sS -X PUT "https://api.attio.com/v2/objects/companies/records" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"values": {
"name": [{ "value": "Acme Corp" }],
"domains": [{ "domain": "acme.com" }],
"employee_count": [{ "value": 150 }]
}
},
"matching_attribute": "domains"
}' | jq '{record_id: .data.id.record_id}'
```
### 5. Upsert a person by email
```bash
curl -sS -X PUT "https://api.attio.com/v2/objects/people/records" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"values": {
"name": [{ "first_name": "Jane", "last_name": "Doe" }],
"email_addresses": [{ "email_address": "jane@acme.com" }],
"job_title": [{ "value": "CTO" }]
}
},
"matching_attribute": "email_addresses"
}' | jq '{record_id: .data.id.record_id}'
```
### 6. Update specific attributes on an existing record
```bash
curl -sS -X PATCH "https://api.attio.com/v2/objects/companies/records/{RECORD_ID}" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"values": {
"icp_score": [{ "value": 85 }],
"icp_tier": [{ "value": "Tier 1" }]
}
}
}'
```
### 7. Write a note to a record
```bash
curl -sS -X POST "https://api.attio.com/v2/notes" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"parent_object": "companies",
"parent_record_id": "{RECORD_ID}",
"title": "Enrichment - 2026-06-02",
"content": "Employee count: 150. Funding stage: Series A. Tech stack: Node.js, React."
}
}' | jq '{note_id: .data.id.note_id}'
```
### 8. Create a task linked to a record
```bash
curl -sS "https://api.attio.com/v2/workspace_members" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Accept: application/json" \
| jq '.data[] | {member_id: .id.workspace_member_id, name: .name, email: .email_address}'
curl -sS -X POST "https://api.attio.com/v2/tasks" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"content": "Follow up - no contact in 21 days",
"is_completed": false,
"assignees": [
{ "referenced_actor_type": "workspace-member", "referenced_actor_id": "{MEMBER_ID}" }
],
"linked_records": [
{ "target_object": "deals", "target_record_id": "{DEAL_RECORD_ID}" }
]
}
}' | jq '{task_id: .data.id.task_id}'
```
### 9. Post a comment on a record
```bash
curl -sS -X POST "https://api.attio.com/v2/comments" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"record": { "target_object": "companies", "target_record_id": "{RECORD_ID}" },
"content": [
{ "type": "text", "text": "Possible duplicate of acme-corp-old - please review and merge." }
]
}
}' | jq '{comment_id: .data.id.comment_id}'
```
### 10. Query a list or pipeline view
```bash
curl -sS "https://api.attio.com/v2/lists" \
-H "Authorization: Bearer $ATTIO_API_KEY" \
-H "Accept: application/json" \
| jq '.data[] | {list_id: .id.list_id, name: .title}'
curl -sS -X POST "https://api.attio.com/v2/lists/{LIST_ID}/entries/query" \
-H "Authorization: Bearer $ATTIO_API_KEY" \Code search agent for exploring any codebase. Use for finding code by intent, locating implementations, understanding how something works, or discovering related code. Prefer over Grep/Glob/Read for any semantic or exploratory question.
Guide for running local E2E tests with API server, Docker lead/worker containers, task creation, log verification, UI dashboard, and cleanup
Close a GitHub or GitLab issue with a summary comment
Create a pull request (GitHub) or merge request (GitLab) from the current branch
Implement a GitHub issue or GitLab issue and create a PR/MR
Investigate and triage a Sentry error issue
Respond to a GitHub issue/PR or GitLab issue/MR
Review a task that has been offered to you and decide whether to accept or reject it