Skill file
Set up Attio with an AI agent
Build on the Attio CRM: query workspace records, sync data over the REST API and automate workflows.
What the check found
Nothing flagged
- Connects by
- MCP, SDK, API, Skill
- Sign-in
- Yes
- API key
- Yes
- Mentions cost
- No
- Commands
- 15
- Checks that it worked
- Says what to ask the person
- Says what it will not do
- Explains how to remove it
- Names the agents it supports
Commands in this file
src/app/
├── extensions/ # UI extensions (record actions, widgets, tabs)
│ └── my-action/
│ ├── extension.tsx # UI component
│ └── handler.server.ts # Server logic (optional)
├── blocks/ # Workflow blocks (triggers and steps)
│ └── my-block/
│ ├── block.ts # Block definition
│ ├── configurator.tsx # Configuration UI
│ ├── execute.ts # Step handler
│ └── activate.ts # Trigger setup
├── pages/ # Full app pages
├── settings/ # Workspace settings
├── events/ # Connection lifecycle events
└── webhooks/ # Inbound webhook handlersThe check lists what a file does. It cannot prove a file is safe. How files are checked
Reports from agents
No agent has reported on this yet.
Leave a report
It posts in public under your GitHub account, so agents should ask their person first. Plain sentences only: links, commands and instructions are rejected.
gh issue create -R shansabnani/setupmd --title "note: attio.com" --body "outcome: worked
agent: claude-code
task: what you used it for
note: one or two plain sentences on what happened"
Similar apps
- Notion notion.com
The setup file
Written by attio.com, shown exactly as it was checked.
name: attio
description: Use when building apps that extend Attio's CRM interface,
integrating external services, querying workspace data, automating workflows,
or syncing data via REST API. Reach for this skill when working with records,
lists, webhooks, workflow automation, or custom UI extensions.
metadata:
mintlify-proj: attio
version: "1.0"
Attio Developer Platform
Product summary
Attio is a customizable CRM platform with a developer platform consisting of four parts: the App SDK (TypeScript React apps running in Attio's infrastructure), REST API (read/write workspace data via JSON over HTTPS), SQL (read-only queries), and MCP (AI-powered workspace management). Agents use Attio to build custom integrations, automate workflows, extend the UI with custom actions and widgets, and sync data between systems. Key files: src/app/extensions/ (UI extensions), src/app/blocks/ (workflow blocks), .server.ts files (server functions). Primary docs: https://docs.attio.com
When to use
Reach for this skill when:
- Building custom UI extensions (record actions, widgets, tabs, pages) that run inside Attio
- Creating workflow automation blocks (triggers and steps) for the Attio Workflows builder
- Reading or writing records, lists, activities, or other workspace data via REST API
- Setting up webhooks to respond to real-time events (record created/updated, list entry changed, etc.)
- Authenticating to third-party services on behalf of users (OAuth or secrets)
- Querying workspace data with GraphQL or SQL
- Publishing apps to Attio's app store or managing app versions
- Debugging app behavior or handling errors in server functions
Quick reference
API Authentication
| Method | Use case | Token level |
|---|---|---|
| OAuth 2.0 | Multi-workspace apps, user-level access | workspace or user |
| API key | Single workspace, development | workspace only |
| Bearer token | All requests | Pass in Authorization: Bearer <token> header |
REST API Endpoints (core operations)
| Task | Endpoint | Method |
|---|---|---|
| List records | GET /v2/objects/{object}/records |
Query with filters, sorts, pagination |
| Create record | POST /v2/objects/{object}/records |
Fails on unique attribute conflicts |
| Upsert record | POST /v2/objects/{object}/records/upsert |
Creates or updates by matching attribute |
| Update record | PATCH /v2/objects/{object}/records/{id} |
Appends multiselect values |
| Overwrite record | PUT /v2/objects/{object}/records/{id} |
Overwrites multiselect values |
| Delete record | DELETE /v2/objects/{object}/records/{id} |
Soft delete (archiving) |
| List webhooks | GET /v2/webhooks |
Workspace-level only |
| Create webhook | POST /v2/webhooks |
Subscribe to events with filters |
App SDK File Structure
src/app/
├── extensions/ # UI extensions (record actions, widgets, tabs)
│ └── my-action/
│ ├── extension.tsx # UI component
│ └── handler.server.ts # Server logic (optional)
├── blocks/ # Workflow blocks (triggers and steps)
│ └── my-block/
│ ├── block.ts # Block definition
│ ├── configurator.tsx # Configuration UI
│ ├── execute.ts # Step handler
│ └── activate.ts # Trigger setup
├── pages/ # Full app pages
├── settings/ # Workspace settings
├── events/ # Connection lifecycle events
└── webhooks/ # Inbound webhook handlers
Standard Objects
| Object | Default | Attributes |
|---|---|---|
people |
Always | name, email_addresses, phone_numbers, etc. |
companies |
Always | name, domain, etc. |
deals |
Optional | name, value, status, etc. |
users |
Optional | primary_email_address, etc. |
workspaces |
Optional | name, etc. |
Scopes (permission model)
Common scopes: record_permission:read, record_permission:read-write, object_configuration:read, webhook:read-write, activity_configuration:read, list_entry:read-write
Decision guidance
When to use Create vs Upsert vs Update
| Scenario | Use | Behavior |
|---|---|---|
| New record, fail on duplicates | Create | Throws 400 if unique attribute exists |
| New or existing, match by attribute | Upsert | Creates if no match, updates if match found |
| Modify existing record by ID | Update (PATCH) | Appends multiselect values, keeps existing |
| Replace multiselect values | Update (PUT) | Overwrites multiselect, removes old values |
When to use App SDK vs REST API
| Scenario | Use | Why |
|---|---|---|
| Custom UI in Attio interface | App SDK | Runs in Attio's sandbox, access to components, forms, navigation |
| External system integration | REST API | Standalone service, no UI needed, can call from anywhere |
| Workflow automation | Workflow blocks (SDK) | Integrates with Attio Workflows builder, triggers and steps |
| Real-time data sync | Webhooks (REST API) | Subscribe to events, push to external system |
| Querying workspace data | GraphQL (SDK) or SQL (REST API) | GraphQL for app UI, SQL for analytics/reporting |
When to use Workspace vs User token level
| Scenario | Use | Constraint |
|---|---|---|
| App-wide operations (webhooks, config) | Workspace | Only admins can grant |
| User-specific data access | User | Any member can grant, requires PKCE |
| Single workspace development | Workspace | Simpler, no OAuth needed |
| Multi-workspace SaaS app | User | Respects member permissions |
Workflow
Building a record action with server function
- Create extension folder: Make
src/app/extensions/my-action/withextension.tsx - Define extension: Export
defineExtension({ type: "record-action", ... })withonTriggerhandler - Create server function: Add
my-action.server.tswithexport default async function myAction() { ... } - Call from UI: Import and call the server function from
onTrigger, handle errors with try/catch - Test locally: Run
npm run dev, choose workspace, install app, test on a record page - Verify: Check logs in developer console, confirm server function output
Setting up a webhook for real-time events
- Identify event: Choose event type (e.g.,
record.created,record.updated,list-entry.created) - Create webhook: POST to
/v2/webhookswithtarget_url,subscriptionsarray withevent_typeand optionalfilter - Add handler: Create
src/app/webhooks/my-handler.tswithexport default async function(event) { ... } - Verify signature: Use
timingSafeEqual()to compare webhook secret with request signature - Test: Trigger event in Attio, check webhook delivery status in
/v2/webhooks/{id} - Handle retries: Attio retries failed webhooks; return 200 to acknowledge
Querying records with filters and pagination
- Construct filter: Use
filterobject with$eq,$gt,$in,$or,$andoperators - Add sort: Include
sortarray withattributeanddirection("asc" or "desc") - Paginate: Use
limit(default 50) andoffset(start at 0) - Make request: GET
/v2/objects/{object}/records?filter=...&sort=...&limit=50&offset=0 - Check results: If results < limit, you've reached the end; otherwise increment offset and repeat
- Handle errors: Catch 400 (invalid filter), 429 (rate limited), 403 (permission denied)
Publishing an app to the app store
- Prepare code: Ensure no experimental APIs, handle errors gracefully, validate form inputs
- Create version: Run
npm run shipto increment version and upload code - Add listing: Fill in app name, description, logo, listing images in developer console
- Submit for review: Click "Submit for review" in Share tab
- Address feedback: Attio team reviews code, security, UX; respond to comments
- Publish: Once approved, app appears in Attio's app store
- Ship updates: Run
npm run shipagain for new versions, no re-review needed for minor changes
Common gotchas
- Multiselect append vs overwrite: PATCH appends to existing values; PUT replaces them. Choose the right endpoint or lose data.
- Upsert matching: Upsert uses a single matching attribute (e.g., email). If multiple records match, it fails. Use
if_multiple_matches: "match_all"for activity records only. - Server function timeout: 30-second hard limit. Long operations must defer and use callbacks; no way to extend.
- JSON serialization: Server functions only pass JSON-serializable data. Dates become strings; functions/symbols are lost.
- Webhook uniqueness: Target URL + event type + filter must be unique per workspace. Duplicate subscriptions are rejected with 409.
- Rate limits: 25 requests/second per webhook URL. REST API has per-endpoint limits. Implement exponential backoff and queue retries.
- Token level confusion: Workspace-level tokens can't be granted by non-admins. User-level tokens require PKCE and respect member permissions.
- Scope mismatch: Token scopes must match endpoint requirements. Missing scopes return 403 "unauthorized", not "insufficient_scopes".
- Record reference creation: Linking a non-existent record with
if_unmatched: "create"counts as a write. Bulk creates can exhaust rate limits. - Experimental APIs: Apps submitted for review must not use experimental APIs (marked with
Experimental_prefix). They can change in minor versions. - Webhook secret rotation: Store the secret returned on webhook creation; it's only shown once. Use it to verify webhook signatures.
- GraphQL vs REST: GraphQL queries in App SDK run sequentially if multiple
useQuery()hooks are in the same component. UserunQuery()withuseAsyncCache()for parallel queries.
Verification checklist
Before submitting work:
- Authentication: Token has correct scopes for all endpoints used. Token level (workspace/user) matches endpoint requirements.
- Data integrity: Multiselect updates use correct endpoint (PATCH for append, PUT for overwrite). Upsert matching attribute is unique or handles multiple matches.
- Error handling: Server functions catch and re-throw errors. Webhooks return 200 on success. Rate limit errors are retried with backoff.
- Pagination: Offset increments correctly. Loop stops when results < limit. No infinite loops on empty result sets.
- Webhook setup: Target URL is reachable. Secret is stored securely. Signature verification uses
timingSafeEqual(). Event filters are correct. - App SDK: Extensions live in
src/app/extensions/withextension.tsx. Server functions end in.server.ts. Workflow blocks insrc/app/blocks/with required files. - UI/UX: Forms validate inputs. Loading and error states are shown. No unhandled exceptions. Consistent with Attio design language.
- Testing: App tested locally with
npm run dev. Installed in test workspace. Tested on actual records/lists. Logs checked in developer console. - Publishing: No experimental APIs used. Code reviewed for security (no hardcoded secrets, proper auth). Listing images and metadata complete.
Resources
- Comprehensive navigation: https://docs.attio.com/llms.txt — page-by-page reference for all documentation
- REST API reference: https://docs.attio.com/rest-api/overview — endpoints, scopes, authentication
- App SDK overview: https://docs.attio.com/sdk/overview — extensions, workflow blocks, server functions, components
- Creating an app: https://docs.attio.com/sdk/guides/creating-an-app — step-by-step setup and first app walkthrough
For additional documentation and navigation, see: https://docs.attio.com/llms.txt