Ashish Saraf · AWS Alliance Lead at Clazar

I replaced 40 hours of manual work with 13 AI automations

Every partner profile, every co-sell email, every CRM update, every pipeline review — automated end-to-end with Claude Code, direct API calls, and 8 MCP integrations. No manual data entry. No copy-paste. No context switching.

13
Custom Skills
8+
Integrations
~2min
Per Partner Profile
0
Manual Data Entry
Built with Claude Code · Running on macOS via LaunchAgent scheduling · Every skill is a .md command file
Claude Code (Opus) HubSpot CRM API HubSpot Custom Objects Gmail MCP Slack MCP Notion MCP Fireflies MCP Clay MCP HeyReach MCP Apify (LinkedIn) macOS LaunchAgent Node.js Python 3
The Problem
What partnerships work looked like
Before — Manual
  • 45+ minutes per partner profile: open 6 tabs, copy-paste across HubSpot, Slack, Fireflies, Notion
  • Co-sell emails: read HubSpot task, find Slack message, look up AM history, compose email, CC the right people
  • Partner data goes stale: people change jobs, titles change, emails bounce — nobody notices for months
  • Pipeline review: manually check each deal for meeting status, flag stale ones, ping owners individually
  • Call notes: listen to recordings, figure out which companies were discussed, update the right HubSpot records
  • Account mapping: CSV uploads, manual association labeling, conflict resolution — error-prone at scale
After — Automated
  • Partner Intelligence builds a full 360° Notion page in ~2 minutes from 6 sources in parallel
  • Co-sell drafts created end-to-end: tasks pulled, Slack content fetched, emails personalized, Gmail drafts ready
  • Partner cleanup validates every contact against LinkedIn, updates titles, re-maps company associations
  • Deal notifier classifies every deal daily, sends Slack threads grouped by owner with specific actions
  • Call notes processed automatically: companies extracted, matched to HubSpot, AM verified, notes written
  • Account mapper handles CSV parsing, domain resolution, 3-phase association management — zero manual CRM work
System Architecture
How it all connects

Every skill is a .md file in ~/.claude/commands/. Claude Code reads the skill file, plans its approach, then orchestrates API calls across multiple systems. Two HubSpot tokens handle different API scopes. macOS LaunchAgents schedule recurring skills.

Data Flow
Sources
HubSpot CRM
Custom Objects
Fireflies
Slack
LinkedIn/Apify
Web Search
↓   parallel fetch   ↓
Processing
Claude Code (Opus)
Merge & Classify
Synthesize
↓   write   ↓
Outputs
Gmail Drafts
Notion Pages
HubSpot Notes
Slack Messages
HubSpot Updates
Scheduling
LaunchAgent Plist
Launcher Script
claude -p "/skill-name"
Dual token architecture: standard HubSpot token for contacts/deals/tasks + custom object token for Partner Contact (2-40826561) associations
The Skills
13 automations, built to compound

Each skill is purpose-built for a specific partnerships workflow. They share patterns — parallel fetching, graceful failure, human-in-the-loop drafts — but each solves a distinct problem. Grouped by function: Intelligence, Email, CRM, and Infrastructure.

Intelligence & Profiles3 skills
Build and maintain deep knowledge about every partner
Partner Intelligence
Flagship
Builds a complete 360° partner profile in ~2 minutes from 6 data sources — the work that used to take 45+ minutes of tab-switching and copy-paste.
Resolves the partner across HubSpot standard contacts AND the custom Partner Contact object, then fetches everything in parallel: patch companies, co-sell deals, team hierarchy, notes, emails, Fireflies transcripts, Slack mentions, and web signals. Synthesizes it all into a structured Notion page with an action queue, activity log, co-sell intelligence, patch territory map, and team peer links.
Before Open HubSpot, Slack, Fireflies, Notion in separate tabs. Copy data. Format manually. 45+ min per profile.
After One command: /partner-intelligence build partner@aws.com → full Notion page in ~2 min.
1Resolve partner across custom object (primary) + standard contact (secondary)
2Parallel fetch: companies, deals, team, notes, emails, transcripts, Slack, web
3Batch-read details for all entities (single API call per type)
4Merge with field authority rules (custom object wins for 21 fields)
5Classify engagement: Hot (<14d) / Warm (14-60d) / Cold (60d+)
6Write structured Notion page with metadata for incremental updates
// Step 1: Dual-source identity resolution parallel { custom_obj = curl("custom-objects/2-40826561?email={input}") std_contact = hubspot.search("contacts", email) notion_page = notion.search(email, "collection://27e9...") } // Step 2: Parallel data fetch (all in one message block) parallel { companies = curl("associations/patch-companies") deals = curl("associations/co-sell-deals") team = curl("associations/manager-reportees") notes = hubspot.get("notes", last_10) emails = hubspot.get("emails", last_10) transcripts= fireflies.search(partner_name, last_5) slack_hits = slack.search(partner_name, last_10) web_intel = web.search(partner_name + company) } // Step 4: Field authority — custom object wins for field in [name, email, title, linkedin, phone, city, country, region, segment, lifecycle...]: merged[field] = custom_obj[field] ?? std_contact[field] // Step 5: Engagement classification days_since = daysBetween(last_activity, today) engagement = days_since < 14 ? "Hot" : days_since < 60 ? "Warm" : "Cold" // Step 6: Write with incremental metadata notion.write(page, { action_queue, activity_log, cosell_intel, patch_territory, team_peer_map, profile, metadata: { last_full_build: today, update_count: 0 } })
HubSpot MCP Custom Object API Fireflies Slack Notion Web Search
Prospect → AM Bridge Intel
Intel
When a prospect responds, instantly builds the context package your AWS AM needs — social proof, engagement history, and a draft message — so the intro feels warm, not cold.
Extracts the prospect signal, finds their company in HubSpot, retrieves the mapped AWS Account Manager (from aws_account_manager_email), builds social proof from similar Clazar customers, fetches the AM's last 3 notes and emails, and synthesizes a ready-to-send reachout plan with multiple angles.
Before Prospect responds → scramble to find AM, look up history, figure out what to say. 20+ min.
After One command → full AM context package with social proof, draft message, engagement status. 2 min.
1Find prospect + company in HubSpot, retrieve aws_account_manager_email
2Build social proof: match Clazar customers by ecosystem (voice AI → meeting intelligence)
3Fetch AM's last 3 notes + 3 emails, classify engagement (Hot/Warm/Cold thresholds)
4Synthesize: prospect signal + AM status + social proof + multi-angle draft message
HubSpot MCP Custom Object API
Partner Team Lookup
Intel
Given any partner contact, instantly maps their full team: manager, all peer reportees, lifecycle stages, account counts, and latest meeting dates.
Traverses HubSpot's custom Partner Contact object to resolve the manager/reportee hierarchy in both directions. If you give it an AM, it finds their SM and all peers. If you give it an SM, it returns all their reportees. Outputs a clean table with lifecycle, deal counts, and meeting freshness.
Before Navigate custom objects manually, click through each association, cross-reference contacts. 15+ min.
After One command → formatted team table with full context. 30 seconds.
1Fetch partner record + partner-to-partner associations (Manager/Reportee labels)
2Resolve direction: AM has Manager, SM has Reportees
3Batch-read all team member details in single API call
4Cross-reference HubSpot contacts for latest_meeting_date
Custom Object API HubSpot MCP Keychain
Email Automation5 skills
Turn CRM tasks and signals into personalized Gmail drafts — humans approve, never robots
AWS Co-Sell Email Drafter
Email
Fully automated end-to-end: pulls HubSpot co-sell tasks, fetches Slack email templates, groups by AWS AM, personalizes with engagement history, and creates Gmail drafts. No approval step between AMs.
Processes Simran's "Co-sell Initiation" tasks: resolves her owner ID, pulls NOT_STARTED tasks, fetches associated deals (filtering out Channel Partnership), parses Slack message links (converting p1773854406648669 to API timestamp format), researches the last 3 months of engagement per AM, composes personalized drafts with the Slack content as the email body, and marks every task COMPLETED.
Before Open each task, find the Slack message, look up AM history, compose email, CC the right people. 10+ min per AM.
After One command processes all pending tasks → Gmail drafts ready, tasks marked complete. ~1 min per AM.
1Pull NOT_STARTED "Co-sell Initiation" tasks assigned to Simran
2Fetch associated deals, filter out Channel Partnership deals
3Parse Slack link from task body → fetch message content via Slack MCP
4Group deals by aws_account_manager_email (multi-deal = single email with bullets)
5Check for active Gmail threads (last 7 days), research personalization (3 months lookback)
6Compose draft with personalization opener + Slack content + booking link → CC partnerships@ + PSM
7Create Gmail draft, mark tasks COMPLETED
// Slack timestamp conversion (critical detail) raw = "p1773854406648669" ts = raw[1:10] + "." + raw[10:] // → "1773854406.648669" // Group deals by AM for combined emails groups = groupBy(deals, d => d.aws_account_manager_email) for [am_email, am_deals] of groups: recent_thread = gmail.search(am_email, last_7_days) intel = parallel { hubspot.notes(am_email, 3_months) fireflies.search(am_email) slack.search(am_email) } draft = compose({ personalization: intel, body: slack_content, // preserved from Slack message booking: "clazar.chilipiper.com/me/caleb-mills/...", cc: ["partnerships@clazar.io", psm_if_available] }) gmail.createDraft(draft) for task of am_deals: hubspot.updateTask(task, "COMPLETED")
HubSpot MCP Slack MCP Gmail MCP Fireflies
Deal Lost Notify
Email
Processes "Co-sell Lost" tasks and creates empathetic Gmail drafts that acknowledge the loss, preserve the relationship, and keep the door open — with a 5-point tone checklist on every draft.
Handles two task formats: Slack link tasks (standard) and inline HTML content tasks (revival motions). Groups by AM, personalizes with engagement history, appends cached Gmail signature, and runs a tone checklist: collegial not vendor-y, acknowledges loss without negativity, soft CTA, "we" language, signature included. Includes closed_lost_reason and notes in composition context.
Before Carefully compose each lost deal email to maintain the relationship. 15+ min per AM (emotionally draining work).
After Tone-checked drafts that sound human, not automated. Review and send. 1 min per AM.
1Load Gmail signature from cached HTML file
2Pull NOT_STARTED "Lost" tasks, fetch associated deals with closed_lost_reason
3Fetch Slack content (link or inline HTML), group by AM
4Research personalization, compose with tone checklist, append signature
5Create Gmail draft, mark tasks COMPLETED
HubSpot MCP Slack MCP Gmail MCP Fireflies
AWS AM Outreach
Email
Intelligently selects from 5 proven email templates based on engagement tier, deal activity, and territory data — each template modeled on actual emails that received replies.
For each AWS AM: builds an intelligence profile (engagement tier, Not Greenfield accounts, active deals, region/segment), then uses a decision tree to pick the right scenario. Active deal? → Co-sell Alignment. Can name specific companies? → Account Followup. International? → Funding/Territory. Prior engagement? → Planning Sync. Cold? → PPA Propensity Report. Every email positions Clazar as a partnerships colleague, not a vendor.
Before Research each AM, figure out the right angle, write a personalized email from scratch. 20+ min per AM.
After AI selects the proven template, personalizes with real data, drafts with correct tone. 2 min per AM.
1Fetch AM contacts from HubSpot, build intelligence profile per AM
2Score engagement tier: Hot (<30d) / Warm (30-90d) / Cold (90d+)
3Decision tree selects scenario: PPA_PROPENSITY | ACCOUNT_FOLLOWUP | FUNDING | COSELL | PLANNING
4Apply template with real data: companies, deals, territory signals
5Run tone philosophy check, create Gmail draft with booking link
// Decision tree for scenario selection function selectScenario(am) { if (am.active_deals.length > 0) return "COSELL_ALIGNMENT" if (am.not_greenfield_accounts.length >= 2) return "ACCOUNT_FOLLOWUP" // name specific companies if (am.region === "international") return "FUNDING_TERRITORY" // $20K AWS funding angle if (am.engagement_tier !== "Cold") return "PLANNING_SYNC" // warm contact, request account list return "PPA_PROPENSITY" // highest cold conversion rate } // Tone philosophy (enforced on every draft) // - Position as partnerships colleague, not vendor // - "We're seeing X on your patch" not "Clazar helps ISVs" // - Every email offers concrete deliverable // - Meeting day awareness: Mon→"Tue/Wed?", Thu→"Fri/Mon?"
HubSpot MCP Gmail MCP Fireflies Slack
Email Responder
Email
Scans an incoming email, optionally pulls context from Gmail threads, HubSpot deals, and Slack — then drafts a reply that matches the sender's exact tone and addresses every point.
Parses the email for key points, tone, and action items. Only pulls additional context when it would add value — self-contained emails skip research entirely. Supports iterative refinement (shorter, longer, more formal, custom edits) without re-explaining the full context. Creates a Gmail draft or copies text, user's choice.
Before Read email, look up context in 3 systems, draft reply matching the right tone. 10+ min for complex threads.
After Paste the email → contextual draft with tone matching. Iterate until perfect. 2 min.
1Parse incoming email: sender, subject, key points, tone, action items
2Optionally pull context: Gmail thread history, HubSpot contact/deal, Slack
3Draft reply matching tone, addressing all points
4Present for review → iterate or create Gmail draft
Gmail MCP HubSpot MCP Slack MCP
Cleanup Pending Emails
Auto
Resolves Clay email enrichment tasks that didn't complete during partner cleanup — polls for completions, shows a diff table for confirmation, then updates HubSpot contacts.
Reads the pending tasks file, checks each Clay task's status, extracts completed email addresses, shows before/after changes for user confirmation, and updates HubSpot. Automatically expires tasks older than 24 hours and rewrites the pending file with only in-progress tasks.
Before Manually check each Clay task, copy emails back to HubSpot. Easy to forget pending tasks entirely.
After One command polls all pending tasks, shows diff, updates HubSpot. Expired tasks auto-cleaned.
1Read pending-clay-tasks.json, poll each task via Clay MCP
2Extract completed emails, expire tasks >24h old
3Show diff table for confirmation, update HubSpot contacts
4Rewrite pending file with only in-progress tasks
Clay MCP HubSpot MCP File I/O
CRM & Data Operations4 skills
Keep the CRM clean, the pipeline visible, and the data fresh
Partner Account Mapper
CRM
Maps companies to partner contacts with association labels via a 3-phase process: clear stale associations, clean conflicts, then create new ones — preventing the duplicate and orphan associations that plague manual CRM work.
Supports two CSV formats: full (with company IDs and partner record IDs) or minimal (just company names — auto-enriches domains via HubSpot search + DNS probing across .com/.ai/.io/.co, resolves partner by name). Always runs a dry-run preview first. Groups by partner+label for independent processing. Auto-creates missing companies when domain is resolved.
Before Manual HubSpot associations: find company, find partner, set label, check for conflicts. Error-prone at scale.
After CSV in → dry-run preview → confirm → 3-phase execution with conflict resolution. Minutes for hundreds.
1Parse CSV (detect full vs. minimal format), resolve partner by name if needed
2For minimal CSV: search HubSpot + probe DNS to resolve company domains
3Dry-run preview: show planned changes grouped by partner+label
4Phase 1: Clear stale associations → Phase 2: Clean conflicts → Phase 3: Create new
// Minimal CSV enrichment pipeline for company_name of csv_rows: // Try HubSpot search first match = hubspot.search("companies", company_name) if (!match) { // DNS probe: try common TLDs for tld of [".com", ".ai", ".io", ".co"]: domain = slugify(company_name) + tld if (dnsResolves(domain)) match = hubspot.create("company", { domain }) } // 3-phase execution (prevents duplicates) for [partner, label, companies] of groups: phase1_clear(partner, label) // remove old phase2_clean(partner, label) // resolve conflicts phase3_create(partner, label, companies) // add new
Node.js Script HubSpot REST API DNS Probing Keychain
Partner Contact Cleanup
CRM
Validates every partner contact against their LinkedIn profile, detects job changes and title updates, re-maps company associations, and clears lifecycle stages — keeping the partner database trustworthy.
Runs as a Python script for efficiency. For each contact (processed one-by-one, never batched): scrapes LinkedIn via Apify, compares title and company to HubSpot, applies company equivalences (AWS = Amazon = Amazon Web Services), updates fields, re-maps associations for company movers, and logs company-changed contacts for downstream Clay email enrichment. Fully resumable via progress file after interruptions.
Before Partner data silently goes stale. People change jobs, emails bounce, associations point to wrong companies.
After Every contact validated against LinkedIn. Stale data detected and fixed. ~$6 for 1,500 contacts.
1Pull partner contacts (lifecycle = partner, has high-fit accounts)
2For each: scrape LinkedIn via Apify, compare title + company
3Same company, different title → update. Different company → full re-mapping workflow
4Save progress after each contact (resume with --resume)
Python 3 Apify (LinkedIn) HubSpot REST API Custom Object API
Deal Stage Slack Notifier
Auto
Daily pipeline hygiene: classifies every deal by meeting status, flags stale deals, surfaces upcoming meetings, and sends a consolidated Slack thread grouped by deal owner with specific actions.
Fetches deals in a pipeline stage, classifies each into PAST_MEETING (needs SQL reason update), UPCOMING_MEETING, STALE_NO_MEETING, MISSING_SQL, or CUSTOMER_DELAY. Deduplicates so each deal appears once in its most relevant section. Groups by owner with Slack @mentions for accountability. Skips deals where latest_meeting_date is today (only flags strictly past meetings).
Before Weekly pipeline review: open each deal, check meeting history, ping owners individually. Hours of work.
After Daily automated Slack thread: every deal classified, owners tagged, actions clear. Zero manual review.
1Fetch deals in pipeline stage with latest_meeting_date and partnership__sql_reason
2Classify: PAST_MEETING | UPCOMING | STALE | MISSING_SQL | CUSTOMER_DELAY
3Deduplicate (one deal = one flag, most relevant wins)
4Group by owner, send parent Slack message + threaded sections
HubSpot MCP Slack MCP
Daily AWS Call Notes
Auto
Automatically processes today's partner calls: extracts every company mentioned, matches to HubSpot, verifies AM associations via direct API, and writes structured notes — so nothing from a call is ever lost.
Fetches today's transcripts from Fireflies, extracts company names from attendees, title, and content (with equivalences: AWS/Amazon/Google Cloud/Azure treated as same). Cross-references to HubSpot companies, verifies Account Manager partner contact associations via custom object API (associationTypeId 580), and creates formatted notes with AM name, attendees, duration, summary bullets, and action items. Always reports unmatched companies so nothing falls through the cracks.
Before Listen to call recordings, identify companies, find them in HubSpot, write up notes manually. 30+ min per call.
After Runs automatically. Notes appear on HubSpot company records. Unmatched companies flagged. 0 manual work.
1Fetch today's transcripts from Fireflies
2Extract company names (attendees, title, content), apply equivalences
3Match to HubSpot, verify AM partner contact associations via direct API
4Write structured notes (check for existing today's note first), report summary
Fireflies MCP HubSpot MCP Custom Object API Keychain
Infrastructure1 skill
The meta-skill that makes all other skills run on schedule
Skill Scheduler
Infra
Generates macOS LaunchAgent plists + launcher scripts for any Claude Code skill, turning one-off commands into scheduled automations that run daily, hourly, or at specific times — with lock files, weekday checks, and binary caching.
Given a skill name and schedule expression, generates two files: a bash launcher script (with lock file deduplication, weekday enforcement, Claude Code binary resolution + caching, and Terminal.app launch via AppleScript) and a LaunchAgent plist for macOS daemon scheduling. Supports "daily at 9am", "every 4 hours", or specific time formats. All skills run via claude -p "/skill" with --allowedTools '*' for headless execution.
Before Remember to run each skill manually. Miss a day? Pipeline review doesn't happen. Call notes aren't captured.
After /scheduler deal-notify "daily at 9am" → runs forever, skips weekends, never overlaps.
1Parse skill name + schedule format (daily / every Xh / at HH:MM)
2Generate launcher script with lock file, weekday check, binary caching
3Generate LaunchAgent plist (~/Library/LaunchAgents/)
4Output launchctl load command for activation
// Generated launcher script (simplified) #!/bin/bash LOCK="/tmp/claude-skill-{name}.lock" # Skip weekends [[ $(date +%u) -gt 5 ]] && exit 0 # Lock file prevents overlapping runs [[ -f "$LOCK" ]] && exit 0 touch "$LOCK" # Resolve + cache Claude Code binary CLAUDE=$(which claude || find /usr/local -name claude) echo "$CLAUDE" > /tmp/.claude-bin-cache # Launch in Terminal.app via AppleScript osascript -e "tell app \"Terminal\" to do script \"$CLAUDE -p '/{name}' --allowedTools '*'\"" rm "$LOCK"
Bash LaunchAgent AppleScript Terminal.app
Compound Workflows
Skills that chain together

Individual skills are useful. But the real power comes from how they compose — the output of one skill becomes the input context for another.

Partner Onboarding Pipeline
New partner assigned → account mapper creates associations → partner intelligence builds their Notion profile → team lookup maps their org → AM outreach drafts the first email.
Account Mapper Partner Intel Team Lookup AM Outreach
Daily Operations Loop
Scheduled daily: call notes capture today's meetings, deal notifier flags pipeline issues, co-sell drafter processes pending tasks, cleanup resolves pending enrichments.
Call Notes Deal Notify Co-Sell Drafter Cleanup Emails
Data Hygiene Cycle
Partner cleanup validates contacts against LinkedIn → company movers get re-mapped → pending email enrichments are resolved by cleanup skill → intelligence pages refresh.
Contact Cleanup Account Mapper Cleanup Emails Partner Intel
Prospect Response Workflow
Prospect replies → bridge intel builds AM context package with social proof → email responder drafts the reply → AM outreach updates the partner engagement.
Bridge Intel Email Responder AM Outreach
Engineering Principles
Patterns that make it reliable

Every skill follows the same core patterns. These aren't theoretical — each was learned from a production failure or a workflow bottleneck.

Parallel Execution
Independent data fetches launch in a single Claude message block. Partner Intelligence fetches from 6 sources simultaneously — HubSpot, Fireflies, Slack, Notion, Web, Custom Objects — in one round trip. Cuts latency from sequential minutes to a single parallel batch.
USED IN: Partner Intel, Co-Sell Drafter, Bridge Intel
🔄
Resumable Processing
Long-running skills save progress after each item. Partner Contact Cleanup writes cursor position to a JSON file after every contact. If context exhausts or connection drops, --resume picks up exactly where it left off. No duplicate work, no missed contacts.
USED IN: Contact Cleanup, Cleanup Pending Emails
🔗
Dual Token Architecture
HubSpot's MCP connector doesn't support custom objects. So the system uses two tokens: standard HubSpot token for contacts/deals/tasks via MCP, and a custom object token for Partner Contact (2-40826561) associations via direct REST API. Both stored in macOS Keychain.
USED IN: Partner Intel, Team Lookup, Call Notes, Contact Cleanup
🛡️
Never Fabricate, Never Block
If a data source is empty, the skill marks it as "—" and continues. Missing Fireflies transcripts don't block partner intelligence from writing the other 5 sections. Missing AM email gets flagged for manual review. Partial intel always beats complete failure.
USED IN: All 13 skills
📧
Human-in-the-Loop Drafts
Email skills create Gmail drafts, never send directly. Co-sell emails, lost deal notifications, AM outreach — all land in your drafts folder for review. The AI handles research, personalization, and composition. The human handles the send button.
USED IN: Co-Sell Drafter, Deal Lost, AM Outreach, Email Responder
🔍
Company Equivalences
"Amazon", "AWS", and "Amazon Web Services" are the same company. Same for Google/Google Cloud, Microsoft/Azure. Every skill that matches company names applies equivalence rules to prevent false negatives. Critical for call notes, contact cleanup, and partner intelligence.
USED IN: Call Notes, Contact Cleanup, Partner Intel
📊
Deduplication at Every Layer
Deal Notifier: each deal appears once in its most relevant section. Account Mapper: 3-phase process prevents duplicate associations. Co-Sell Drafter: multi-deal emails combine into one per AM. Contact Cleanup: progress file prevents re-processing. Every output is deduplicated.
USED IN: Deal Notify, Account Mapper, Co-Sell Drafter, Cleanup
Meeting Day Awareness
Email skills adjust CTA language based on the current day of the week. Monday → "perhaps Tuesday or Wednesday?" Thursday → "perhaps Friday or Monday?" A small detail that makes automated emails feel human-written.
USED IN: Co-Sell Drafter, AM Outreach, Deal Lost
Impact
What this adds up to
Partner Profile Build
~2 min
was 45+ minutes per profile
Co-Sell Email Turnaround
Task → Draft
end-to-end, no manual steps
Daily Call Notes
Automated
extracted, matched, verified, written
Pipeline Review
Daily
classified + Slack thread by owner
Contact Validation
~$6 / 1,500
LinkedIn-verified, resumable
Manual Data Entry
Zero
CSV in, associations out