Skip to content
Agent Orchestration
Skill

/attio-interaction

Generic Attio CRM REST API v2 recipes for querying records, upserting companies/people/deals, writing notes/tasks/comments, managing lists, and handling webhooks.

BOOST
From plugin
agent-swarm
88016 skills5 agents11 commands
Install
$ npx -y skills add desplega-ai/agent-swarm --skill attio-interaction --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/attio-interaction

Context preview

The summary Claude sees to decide when to auto-load this skill.

Generic Attio CRM REST API v2 recipes for querying records, upserting companies/people/deals, writing notes/tasks/comments, managing lists, and handling webhooks.

SKILL.md

attio-interaction.SKILL.md
name: attio-interaction
description: Generic Attio CRM REST API v2 recipes for querying records, upserting companies/people/deals, writing notes/tasks/comments, managing lists, and handling webhooks.
user-invocable: false

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

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

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

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

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.

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

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}'

An upsert returns HTTP `200` when it updates an existing record and `201` when it creates one. The response body has the same shape in both cases.

6. Update specific attributes on an existing record

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

Notes are concise free-text entries linked to a record. Use them to preserve useful interaction context, enrichment findings, or an agent result that should remain visible in the CRM.

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

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

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_rec
Read more
Ships withagent-swarm

Your Company Agentic Operating System

Get the whole plugin

Other skills on agent-swarm.