Claude-code-plugins attio-core-workflow-b
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/attio-pack/skills/attio-core-workflow-b" ~/.claude/skills/jeremylongshore-claude-code-plugins-attio-core-workflow-b && rm -rf "$T"
manifest:
plugins/saas-packs/attio-pack/skills/attio-core-workflow-b/SKILL.mdsource content
Attio Lists, Notes & Tasks (Core Workflow B)
Overview
Lists are Attio's pipeline/board primitive -- they contain entries (records added to the list with list-specific attributes like stage or owner). This skill also covers notes and tasks, which attach to records for activity tracking.
Prerequisites
completedattio-install-auth- Scopes:
,object_configuration:read
,record_permission:read
,list_entry:read
,list_entry:read-write
,note:read-write
,task:read-writeuser_management:read
Instructions
Step 1: List All Lists
// GET /v2/lists const lists = await client.get<{ data: Array<{ id: { list_id: string }; api_slug: string; name: string; parent_object: string[]; // Which object types can be added }>; }>("/lists"); console.log(lists.data.map((l) => `${l.api_slug}: ${l.name}`)); // Output: ["sales_pipeline: Sales Pipeline", "hiring: Hiring Pipeline"]
Step 2: Query List Entries
// POST /v2/lists/{list_slug}/entries/query const entries = await client.post<{ data: Array<{ entry_id: string; record_id: string; created_at: string; values: Record<string, any[]>; }>; }>("/lists/sales_pipeline/entries/query", { filter: { stage: { status: { $eq: "In Progress" } }, }, sorts: [ { attribute: "created_at", field: "created_at", direction: "desc" }, ], limit: 50, });
Step 3: Add a Record to a List (Create Entry)
// POST /v2/lists/{list_slug}/entries const entry = await client.post<{ data: { entry_id: string } }>( "/lists/sales_pipeline/entries", { data: { // The record to add to the list parent_record_id: companyRecordId, parent_object: "companies", // List-specific attribute values values: { stage: [{ status: "Qualified" }], deal_value: [{ currency_code: "USD", currency_value: 50000 }], owner: [{ referenced_actor_id: workspaceMemberId, referenced_actor_type: "workspace-member" }], }, }, } );
Step 4: Update an Entry
// PATCH /v2/lists/{list_slug}/entries/{entry_id} -- append multiselect await client.patch( `/lists/sales_pipeline/entries/${entryId}`, { data: { values: { stage: [{ status: "Won" }], }, }, } ); // PUT /v2/lists/{list_slug}/entries/{entry_id} -- overwrite multiselect await client.put( `/lists/sales_pipeline/entries/${entryId}`, { data: { values: { stage: [{ status: "Lost" }], }, }, } );
Step 5: Delete an Entry (Remove from List)
// DELETE /v2/lists/{list_slug}/entries/{entry_id} await client.delete(`/lists/sales_pipeline/entries/${entryId}`); // Note: This removes from the list only. The underlying record is not deleted.
Step 6: Create a Note on a Record
// POST /v2/notes const note = await client.post<{ data: { id: { note_id: string } }; }>("/notes", { data: { // Link to a parent record parent_object: "companies", parent_record_id: companyRecordId, // Note content title: "Q1 Review Meeting", format: "plaintext", // or "markdown" content: "Discussed renewal timeline. Budget approved for next quarter.", }, });
Step 7: List Notes on a Record
// GET /v2/notes?parent_object=companies&parent_record_id={id} const notes = await client.get<{ data: Array<{ id: { note_id: string }; title: string; content: string; created_at: string; created_by_actor: { type: string; id: string }; }>; }>(`/notes?parent_object=companies&parent_record_id=${companyRecordId}`);
Step 8: Create and Manage Tasks
// POST /v2/tasks const task = await client.post<{ data: { id: { task_id: string } }; }>("/tasks", { data: { content: "Send renewal proposal to Acme Corp", deadline: "2025-07-15T17:00:00.000Z", is_completed: false, // Link to records linked_records: [ { target_object: "companies", target_record_id: companyRecordId }, ], // Assign to workspace members assignees: [ { referenced_actor_id: memberId, referenced_actor_type: "workspace-member" }, ], }, }); // Complete a task await client.patch(`/tasks/${taskId}`, { data: { is_completed: true }, }); // List tasks (sorted oldest to newest by default) const tasks = await client.get<{ data: Array<{ id: { task_id: string }; content: string; deadline: string | null; is_completed: boolean; }>; }>("/tasks");
Attio Lists vs Records Mental Model
Objects (people, companies, deals) └── Records ← individual CRM entries (Step 1-7 of core-workflow-a) └── Notes, Tasks ← activity attached to records Lists (pipelines, boards) └── Entries ← a record placed in a list context └── List-specific values (stage, owner, custom columns)
Error Handling
| Error | Status | Cause | Solution |
|---|---|---|---|
| 404 | Invalid list slug or entry ID | Verify with |
| 403 | Missing | Update token scopes |
| 422 | Wrong parent_object for list | Check list's array |
| 403 | Missing for notes | Add note scope to token |
| 403 | Missing + | Tasks need both scopes |
Resources
Next Steps
For error diagnosis, see
attio-common-errors. For webhooks on list/record changes, see attio-webhooks-events.