agentsclimarketplace

Attio upgrade migration

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/attio-pack/skills/attio-upgrade-migration

'Migrate between Attio API versions, handle breaking changes in theFrom its SKILL.md

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill attio-upgrade-migration

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

6.7 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

Attio Upgrade & Migration

Overview

Attio has two API generations: v1 (legacy, deprecated) and v2 (current). This skill covers the v1-to-v2 migration, community SDK upgrade paths, and how to detect and adapt to API changes since Attio does not publish a traditional SDK changelog.

V1 to V2 Migration Reference

Endpoint Changes

OperationV1 EndpointV2 Endpoint
List objectsGET /v1/objectsGET /v2/objects
Query recordsGET /v1/objects/{id}/recordsPOST /v2/objects/{slug}/records/query
Create recordPOST /v1/objects/{id}/recordsPOST /v2/objects/{slug}/records
Get recordGET /v1/objects/{id}/records/{rid}GET /v2/objects/{slug}/records/{rid}
List entriesGET /v1/lists/{id}/entriesPOST /v2/lists/{slug}/entries/query
Create webhookPOST /v1/webhooksPOST /v2/webhooks
SearchN/APOST /v2/records/search

Key Differences

AspectV1V2
IdentifiersUUIDs onlySlugs (preferred) or UUIDs
Record queryGET with query paramsPOST with JSON body (filters, sorts)
FilteringBasic query paramsRich operators ($eq, $contains, $gt, $and, $or)
Paginationpage + per_pagelimit + offset or cursor-based
Webhook payloadsCustom formatConsistent with v2 response shapes
Webhook filteringNoneEvent-type and attribute-level filters

Step 1: Update Base URL

// Before
const BASE = "https://api.attio.com/v1";

// After
const BASE = "https://api.attio.com/v2";

Step 2: Migrate Record Queries

// V1: GET with query params
const v1 = await fetch(
  `${BASE}/objects/${objectId}/records?page=1&per_page=50`,
  { headers: { Authorization: `Bearer ${token}` } }
);

// V2: POST with filter body, using slug instead of UUID
const v2 = await fetch(
  `${BASE}/objects/people/records/query`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      filter: {
        email_addresses: { email_address: { $contains: "@example.com" } },
      },
      sorts: [{ attribute: "created_at", field: "created_at", direction: "desc" }],
      limit: 50,
      offset: 0,
    }),
  }
);

Step 3: Update Record Creation

// V1: values as flat key-value pairs
const v1Body = {
  name: "Ada Lovelace",
  email: "[email protected]",
};

// V2: values nested under data.values, always arrays
const v2Body = {
  data: {
    values: {
      name: [{ first_name: "Ada", last_name: "Lovelace", full_name: "Ada Lovelace" }],
      email_addresses: ["[email protected]"],
    },
  },
};

Step 4: Migrate Webhooks from V1 to V2

// V1 webhook event types
"object.record.created"

// V2 webhook event types
"record.created"
"record.updated"
"record.deleted"
"record.merged"
"list-entry.created"
"note.created"
"task.created"
// ... plus filtering support

V2 webhooks support event filtering to reduce volume:

await client.post("/webhooks", {
  target_url: "https://yourapp.com/webhooks/attio",
  subscriptions: [
    {
      event_type: "record.updated",
      filter: {
        // Only trigger for updates to the "stage" attribute on deals
        $and: [
          { object: { $eq: "deals" } },
          { attribute: { $eq: "stage" } },
        ],
      },
    },
  ],
});

Community SDK Migration

Since there is no official Attio SDK, you may be using community packages:

attio-js (most popular community SDK)

# Check current version
npm list attio-js

# Upgrade
npm install attio-js@latest
// attio-js uses the v2 API natively
import { AttioClient } from "attio-js";

const client = new AttioClient({ accessToken: process.env.ATTIO_API_KEY });
const people = await client.records.query("people", { limit: 10 });

Direct fetch (recommended for control)

No upgrade risk -- you control the endpoint URLs directly. See attio-sdk-patterns for a typed wrapper.

Detecting API Changes

Attio does not publish a traditional changelog for the REST API. Monitor for changes:

// Save the OpenAPI spec hash and check periodically
import crypto from "crypto";

async function checkForApiChanges(): Promise<boolean> {
  const spec = await fetch("https://docs.attio.com/openapi.json").then(r => r.text());
  const hash = crypto.createHash("sha256").update(spec).digest("hex");

  const previousHash = await readStoredHash(); // From file or DB
  if (previousHash && hash !== previousHash) {
    console.warn("Attio OpenAPI spec changed! Review for breaking changes.");
    await storeHash(hash);
    return true;
  }
  await storeHash(hash);
  return false;
}

Migration Checklist

[ ] Base URL updated to /v2
[ ] Object references use slugs instead of UUIDs where possible
[ ] Record queries migrated from GET to POST with filter body
[ ] Record creation uses data.values wrapper with arrays
[ ] Webhook subscriptions recreated with v2 event types
[ ] Webhook handlers updated for v2 payload format
[ ] Pagination migrated from page/per_page to limit/offset
[ ] Error handling updated for v2 error response format
[ ] Tests updated and passing against v2 endpoints
[ ] OpenAPI spec monitoring configured for future changes

Error Handling

Migration issueSymptomFix
Old v1 URL404 on all callsUpdate base URL to /v2
UUID instead of slug404 on object endpointsUse api_slug from GET /v2/objects
Flat values (v1 format)422 validation errorWrap in { data: { values: { ... } } }
Old webhook event typesWebhook never firesRecreate with v2 event types
Old pagination paramsIgnored, only first page returnedSwitch to limit + offset

Resources

Next Steps

For CI integration during upgrades, see attio-ci-integration.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.