Import recently funded companies from Crunchbase into HubSpot using a Claude Code skill

low complexityCost: Usage-based

Prerequisites

Compatible agents

This skill works with any agent that supports the Claude Code skills standard, including Claude Code, Claude Cowork, OpenAI Codex, and Google Antigravity.

Prerequisites
  • One of the agents listed above
  • Crunchbase Enterprise or API/Data License plan (Pro plan does not include API access)
  • HubSpot private app with crm.objects.companies.read and crm.objects.companies.write scopes
  • Custom HubSpot company properties for funding data (funding_stage, funding_amount, funding_date, investors)
Environment Variables
# Crunchbase API key (requires Enterprise or API/Data License plan)
CRUNCHBASE_API_KEY=your_value_here
# HubSpot private app token with companies read and write scopes
HUBSPOT_ACCESS_TOKEN=your_value_here
Crunchbase API requires Enterprise plan

The search endpoints used here require a Crunchbase Enterprise or API/Data License plan. The Pro plan only provides CSV exports and Zapier integration, not direct API access. Verify your plan before building this.

Why a Claude Code skill?

The other approaches in this guide are deterministic: they run the same logic every time, the same way. An Claude Code skill is different. You tell Claude what you want in plain language, and the skill gives it enough context to do it reliably.

That means you can say:

  • "Find companies that raised a Series A in the last 2 weeks and import them"
  • "Import funded companies, but only in fintech and healthtech"
  • "Show me what Crunchbase found without importing anything yet"

The skill contains workflow guidelines, API reference materials, and configuration that the agent reads on demand. When you invoke the skill, Claude reads these files, writes a script on the fly, runs it, and reports results. If you ask for something different next time — a different funding stage, a different employee range, a dry-run preview — the agent adapts without you touching any code.

How it works

The skill directory has three parts:

  1. SKILL.md — workflow guidelines telling the agent what steps to follow, which env vars to use, and what pitfalls to avoid
  2. references/ — Crunchbase and HubSpot API patterns (endpoints, request shapes, response formats) so the agent calls the right APIs with the right parameters

When invoked, the agent reads SKILL.md, consults the reference files as needed, writes a Python script, executes it, and reports what it imported. The reference files act as guardrails — the agent knows exactly which endpoints to hit and what the responses look like, so it doesn't have to guess.

What is a Claude Code skill?

An Claude Code skill is a reusable command you add to your project that Claude Code can run on demand. Skills live in a .claude/skills/ directory and are defined by a SKILL.md file that tells the agent what the skill does, when to run it, and what tools it's allowed to use.

In this skill, the agent doesn't run a pre-written script. Instead, SKILL.md provides workflow guidelines and points to reference files — API documentation for Crunchbase and HubSpot — that the agent reads to generate and execute code itself. This is the key difference from a traditional script: the agent can adapt its approach based on what you ask for while still using the right APIs and data formats.

Once installed, you can invoke a skill as a slash command (e.g., /funded-companies), or the agent will use it automatically when you give it a task where the skill is relevant. Skills are portable — anyone who clones your repo gets the same commands.

Step 1: Create the skill directory

mkdir -p .claude/skills/funded-companies/references

This creates the layout:

.claude/skills/funded-companies/
├── SKILL.md                              # workflow guidelines + config
└── references/
    ├── crunchbase-api.md                 # Crunchbase funding search patterns
    └── hubspot-companies-api.md          # HubSpot company create + dedup patterns

Step 2: Write the SKILL.md

Create .claude/skills/funded-companies/SKILL.md:

---
name: funded-companies
description: Import recently funded companies from Crunchbase into HubSpot. Searches for Series A+ funding rounds, filters by ICP, and creates company records with funding details.
disable-model-invocation: true
allowed-tools: Bash, Read
---
 
## Goal
 
Search Crunchbase for companies that raised a Series A or later in a given time window (default: 30 days). Filter results by ICP criteria (employee count, website presence). For each matching company, check if it already exists in HubSpot by domain. If not, create a new company record with funding metadata (stage, amount, date, investors). Print a summary of what was imported.
 
## Configuration
 
Read these environment variables:
 
- `CRUNCHBASE_API_KEY` — Crunchbase API key (required)
- `HUBSPOT_ACCESS_TOKEN` — HubSpot private app token (required)
 
Defaults:
- Lookback window: 30 days
- Funding stages: series_a, series_b, series_c, series_d
- Employee ranges: 51-100, 101-250, 251-500, 501-1000
 
The user may override any of these in their request.
 
## Workflow
 
1. Validate that all required env vars are set. If any are missing, print which ones and exit.
2. Search Crunchbase for funding rounds announced in the lookback window. See `references/crunchbase-api.md` for the search endpoint, request body, and response format. Paginate using `after_id` if more than 100 results.
3. For each funding round, fetch organization details from Crunchbase. See `references/crunchbase-api.md` for the entity endpoint and response format.
4. Filter organizations by ICP: skip companies without a website or outside the target employee ranges. Track ICP misses for the summary.
5. Extract and normalize the domain from the organization's website URL (strip protocol, www prefix, trailing paths).
6. Check if a company with that domain already exists in HubSpot. See `references/hubspot-companies-api.md` for the search endpoint. Skip duplicates.
7. Create a new HubSpot company record with: domain, name, description, industry, funding_stage, funding_amount, funding_date, investors. See `references/hubspot-companies-api.md` for the create endpoint and property mapping.
8. Print a summary: total funding rounds found, companies created, already in HubSpot, ICP misses.
 
## Important notes
 
- Crunchbase search endpoints require an Enterprise or API/Data License plan. The Pro plan returns 403.
- Crunchbase rate limit is 200 requests/minute. Add a 200ms delay between organization lookups.
- HubSpot rate limit for search is 5 requests/second. Add a 200ms delay between dedup checks.
- The custom HubSpot properties (`funding_stage`, `funding_amount`, `funding_date`, `investors`) must exist before creating companies. If they don't exist, the API returns a property validation error.
- `funding_amount` should be sent as a plain number string (e.g., "15000000"), not formatted with $ or commas.
- Crunchbase employee ranges use coded strings like `c_0051_0100`, `c_0101_0250`, etc.
- Use `urllib.request` for HTTP calls (no external dependencies required).
- Deduplicate within a single run by tracking seen domains in memory.

Understanding the SKILL.md

Unlike the script-based approach, this SKILL.md doesn't contain a Run: command pointing to a script. Instead, it provides:

SectionPurpose
GoalTells the agent what outcome to produce
ConfigurationWhich env vars to read and what defaults to use
WorkflowNumbered steps with pointers to reference files
Important notesNon-obvious context that prevents common mistakes

The allowed-tools: Bash, Read setting lets the agent both read reference files and execute code. The agent writes its own script based on the workflow steps and reference materials.

Step 3: Add reference files

references/crunchbase-api.md

Create .claude/skills/funded-companies/references/crunchbase-api.md:

# Crunchbase API Reference
 
## Search funding rounds
 
Find funding rounds announced after a given date, filtered by investment type.
 
**Request:**
 
```
POST https://api.crunchbase.com/api/v4/searches/funding_rounds
X-cb-user-key: <CRUNCHBASE_API_KEY>
Content-Type: application/json
```
 
**Body:**
 
```json
{
  "field_ids": [
    "identifier",
    "announced_on",
    "money_raised",
    "funded_organization_identifier",
    "investment_type",
    "investor_identifiers"
  ],
  "query": [
    {
      "type": "predicate",
      "field_id": "announced_on",
      "operator_id": "gte",
      "values": ["<YYYY-MM-DD>"]
    },
    {
      "type": "predicate",
      "field_id": "investment_type",
      "operator_id": "includes",
      "values": ["series_a", "series_b", "series_c", "series_d"]
    }
  ],
  "limit": 100
}
```
 
**Response shape:**
 
```json
{
  "entities": [
    {
      "uuid": "abc-123",
      "properties": {
        "identifier": { "value": "Series A - FutureTech" },
        "announced_on": "2026-02-15",
        "money_raised": { "value": 15000000, "currency": "USD" },
        "funded_organization_identifier": { "uuid": "org-456", "value": "FutureTech Inc" },
        "investment_type": "series_a",
        "investor_identifiers": [
          { "uuid": "inv-1", "value": "Sequoia Capital" },
          { "uuid": "inv-2", "value": "a16z" }
        ]
      }
    }
  ]
}
```
 
**Pagination:** If 100 results are returned, pass `"after_id": "<last entity uuid>"` in the next request body. Keep paginating until fewer than 100 entities are returned.
 
## Get organization details
 
Fetch details for a specific organization by UUID.
 
**Request:**
 
```
GET https://api.crunchbase.com/api/v4/entities/organizations/<org_uuid>
X-cb-user-key: <CRUNCHBASE_API_KEY>
```
 
**Query params:** `field_ids=short_description,categories,num_employees_enum,website_url,founded_on`
 
**Response shape:**
 
```json
{
  "properties": {
    "identifier": { "value": "FutureTech Inc" },
    "short_description": "AI-powered supply chain optimization",
    "categories": [{ "value": "Artificial Intelligence" }],
    "num_employees_enum": "c_0101_0250",
    "website_url": "https://www.futuretech.com",
    "founded_on": "2022-03-01"
  }
}
```
 
**Employee range codes:** `c_0001_0010` (1-10), `c_0011_0050` (11-50), `c_0051_0100` (51-100), `c_0101_0250` (101-250), `c_0251_0500` (251-500), `c_0501_1000` (501-1000), `c_1001_5000` (1001-5000).

references/hubspot-companies-api.md

Create .claude/skills/funded-companies/references/hubspot-companies-api.md:

# HubSpot Companies API Reference
 
## Search for existing company by domain
 
Check if a company already exists before creating a duplicate.
 
**Request:**
 
```
POST https://api.hubapi.com/crm/v3/objects/companies/search
Authorization: Bearer <HUBSPOT_ACCESS_TOKEN>
Content-Type: application/json
```
 
**Body:**
 
```json
{
  "filterGroups": [
    {
      "filters": [
        {
          "propertyName": "domain",
          "operator": "EQ",
          "value": "<domain>"
        }
      ]
    }
  ]
}
```
 
**Response shape:**
 
```json
{
  "total": 1,
  "results": [
    {
      "id": "12345",
      "properties": {
        "domain": "futuretech.com",
        "name": "FutureTech Inc"
      }
    }
  ]
}
```
 
If `total` is 0, the company does not exist and can be created.
 
## Create a company
 
**Request:**
 
```
POST https://api.hubapi.com/crm/v3/objects/companies
Authorization: Bearer <HUBSPOT_ACCESS_TOKEN>
Content-Type: application/json
```
 
**Body:**
 
```json
{
  "properties": {
    "domain": "futuretech.com",
    "name": "FutureTech Inc",
    "description": "AI-powered supply chain optimization",
    "industry": "Artificial Intelligence",
    "funding_stage": "series_a",
    "funding_amount": "15000000",
    "funding_date": "2026-02-15",
    "investors": "Sequoia Capital, a16z"
  }
}
```
 
**Response shape:**
 
```json
{
  "id": "67890",
  "properties": {
    "domain": "futuretech.com",
    "name": "FutureTech Inc",
    "createdate": "2026-02-20T10:00:00.000Z"
  }
}
```
 
## Property notes
 
- `funding_stage`, `funding_amount`, `funding_date`, and `investors` are **custom properties** that must be created in HubSpot before use. If they don't exist, the API returns a property validation error.
- `funding_amount` must be a plain number string (e.g., `"15000000"`), not formatted with `$` or commas.
- `funding_date` should be an ISO date string (`YYYY-MM-DD`).
- `investors` is a comma-separated string of investor names.
 
## Rate limits
 
- Search: 5 requests/second
- Create: 150 requests/10 seconds (shared across all HubSpot API calls)

Step 4: Test the skill

Invoke the skill conversationally:

/funded-companies

Claude will read the SKILL.md, check the reference files, write a script, run it, and report the results. A typical run looks like:

Searching Crunchbase for Series A+ rounds in the last 30 days...
  Found 87 funding rounds
  Fetching organization details...
  42 matched ICP criteria
  18 already in HubSpot
  Created 24 new companies
Done. Imported 24 companies into HubSpot.

Because the agent generates code on the fly, you can also make ad hoc requests:

  • "Find Series A companies in fintech from the last 2 weeks" — the agent adjusts the funding stage filter and lookback window
  • "Dry run — show me what would be imported without creating anything" — the agent skips the HubSpot create step and just prints matches
  • "Import funded companies with 250+ employees only" — the agent narrows the employee range filter
Test with a dry run first

Ask Claude to "show me what Crunchbase found without importing" to verify the search results and ICP filtering before creating records in HubSpot.

Step 5: Schedule it (optional)

Option A: Cron + Claude CLI

# Run every Monday at 8 AM
0 8 * * 1 cd /path/to/your/project && claude -p "Run /funded-companies with a 7-day lookback" --allowedTools 'Bash(*)' 'Read(*)'

Option B: GitHub Actions + Claude

name: Import Funded Companies
on:
  schedule:
    - cron: '0 13 * * 1'  # Monday 8 AM ET
  workflow_dispatch: {}       # Manual trigger for testing
jobs:
  import:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-action@v1
        with:
          prompt: "Run /funded-companies with a 7-day lookback"
          allowed_tools: "Bash(*),Read(*)"
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          CRUNCHBASE_API_KEY: ${{ secrets.CRUNCHBASE_API_KEY }}
          HUBSPOT_ACCESS_TOKEN: ${{ secrets.HUBSPOT_ACCESS_TOKEN }}
GitHub Actions cron uses UTC

0 13 * * 1 runs at 1 PM UTC, which is 8 AM ET. GitHub Actions cron may also have up to 15 minutes of delay. For time-sensitive workflows, use cron on your own server.

Option C: Cowork Scheduled Tasks

Claude Desktop's Cowork supports built-in scheduled tasks. Open a Cowork session, type /schedule, and configure the cadence — hourly, daily, weekly, or weekdays only. Each scheduled run has full access to your connected tools, plugins, and MCP servers.

Scheduled tasks only run while your computer is awake and Claude Desktop is open. If a run is missed, Cowork executes it automatically when the app reopens. For always-on scheduling, use GitHub Actions (Option B) instead. Available on all paid plans (Pro, Max, Team, Enterprise).

Troubleshooting

When to use this approach

  • You want on-demand account sourcing — "find me funded companies in healthtech from the last week" — during pipeline reviews or planning sessions
  • You want conversational flexibility — different funding stages, employee ranges, or industry filters without editing code
  • You're already using Claude Code and want skills that integrate with your workflow
  • You want to run tasks in the background via Claude Cowork while focusing on other work
  • You prefer guided references over rigid scripts — the agent adapts while staying reliable

When to switch approaches

  • You need a fully automated weekly import with no LLM cost — use n8n (free self-hosted) or the Code + Cron approach
  • You want a no-code setup with a visual builder — use Make
  • You need the import to run identically every time with no variation — use the Code approach

Common questions

Why not just use a script?

A script runs the same way every time. The Claude Code skill adapts to what you ask — different funding stages, employee ranges, industry filters, dry-run previews. The reference files ensure it calls the right APIs even when improvising, so you get flexibility without sacrificing reliability.

Does this use Claude API credits?

Yes. The agent reads skill files and generates code each time. Typical cost is $0.01-0.05 per invocation depending on how many funding rounds are returned and how much the agent needs to read. The Crunchbase and HubSpot APIs themselves have their own costs (Crunchbase Enterprise plan required).

Can I customize ICP criteria without editing files?

Yes. Just tell Claude: "Run /funded-companies but only companies with 250+ employees in fintech." The SKILL.md defines defaults, but the agent overrides them based on your request. For permanent changes, edit the defaults in SKILL.md.

Can I use this skill with other agents besides Claude Code?

Yes. Any agent that supports the Claude Code skills standard can use this skill. The SKILL.md, references, and directory structure are agent-agnostic. The agent just needs to support allowed-tools: Bash, Read and be able to execute Python scripts.

Cost

  • Claude API — $0.01-0.05 per invocation (the agent reads files and generates code)
  • Crunchbase API — Enterprise plan required, pricing varies (starts ~$49/mo for basic API access)
  • HubSpot API — included in all plans, no per-call cost
  • GitHub Actions (if scheduled) — free tier includes 2,000 minutes/month

Looking to scale your AI operations?

We build and optimize automation systems for mid-market businesses. Let's discuss the right approach for your team.