Get a weekly HubSpot pipeline report from your AI agent

Every Monday: open pipeline by stage, the deals that changed stage last week, and what was created, won and lost.

Runs
Mondays at 8:00
Uses
HubSpot
Posts
Stat tile

What lands on your board

AcmeOpen pipeline$1.28M+7% vs previous period, bettervs last report
New deals14+27% vs previous period
Closed won$118k
Closed lost$64k
6 moved forward2 slid back3 open deals with no amount
An example with made-up numbers. Your agent posts your real ones.

What it does

The Monday pipeline review usually opens with someone sharing the HubSpot deals board and scrolling column by column. This skill does that pass before the meeting: it totals open deals by stage, reads the stage history of every deal touched in the last seven days to see what actually advanced or slid back, and lists what was created, won and lost.

Sales leads and founders get one number to watch, open pipeline, and a short list of the deals that changed it. Deals that sat still stay out of the way.

How it works

  1. 1Map the pipeline stages

    Call GET /crm/v3/pipelines/deals and keep each stage's id, label, displayOrder and metadata.isClosed, so stage IDs such as appointmentscheduled or 98712345 read as names. Use the pipeline the team reviews (often default).

  2. 2Total the open pipeline

    Page through POST /crm/v3/objects/deals/search with pipeline EQ <id> and dealstage NOT_IN the closed stage IDs, requesting dealname, amount, dealstage, hubspot_owner_id and createdate with limit: 200 (the search maximum) and the after cursor. Sum amount per stage and count deals with no amount on a line of their own.

  3. 3Find what changed stage

    Search for deals with hs_lastmodifieddate GTE seven days ago (epoch milliseconds), then call POST /crm/v3/objects/deals/batch/read with propertiesWithHistory: ["dealstage"]. A deal moved if its stage history has an entry with a timestamp inside the window; compare the displayOrder of the old and new stage to call it forward or back.

  4. 4

    4Collect new, won and lost

    New deals have a createdate inside the window. Won and lost deals are those whose stage history entered the closed won or closed lost stage this week; keep closed_lost_reason for the lost ones. Map hubspot_owner_id to names with GET /crm/v3/owners.

  5. 5

    5Write the report

    Save this week's totals by stage to a small JSON file and compare with last Monday's. Then write open pipeline and its change, the table by stage, up to 8 stage moves with owner and amount, and new, won and lost, leading with the single biggest change.

  6. Post it to the board

    With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.

What you get

  • Open pipeline today and the change since last Monday.
  • By stage: deal count and amount in each open stage, with each stage's change.
  • Stage moves: deals that advanced or slid back this week, with owner and amount.
  • New, won and lost: counts and amounts, with the closed lost reason where one was recorded.
  • One line on the deal to raise first in the pipeline review.

Install and run it

Pick your agent, where the data comes from and how to schedule it; the commands below follow.

Agent
Data
Schedule
  1. Install the skill

    One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.

    shellcurl -fsSL https://briefkin.dev/skills/hubspot-weekly-pipeline-report/install | sh
  2. Run it

    Ask Claude Code:

    promptRun the hubspot-weekly-pipeline-report skill

    Or paste the prompt instead of installing:

    promptUsing the HubSpot CRM API (deals search, deal pipelines and owners), report on my deal pipeline for the last 7 days. Give me open pipeline (the sum of `amount` on open deals) by stage with deal counts, and the change from last week if you have last week's numbers. List the deals whose `dealstage` changed in the last 7 days (read it with propertiesWithHistory), marking forward and backward moves, with owner and amount. Then the deals created this week, and the deals won and lost this week with the closed lost reason. Count open deals with no amount separately. End with the one deal I should ask about in the pipeline review and why.
  3. Put it on a schedule

    Mondays at 8:00, from cron on any machine where Claude Code is signed in:

    crontab0 8 * * 1 claude -p "Run the hubspot-weekly-pipeline-report skill"

    Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.

  4. Send it to your board

    Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a stat tile. How setup works

View the SKILL.mdRaw file
SKILL.md---
name: hubspot-weekly-pipeline-report
description: "Every Monday: open pipeline by stage, the deals that changed stage last week, and what was created, won and lost. Use when the user asks for this, or when it runs on a schedule."
---

# HubSpot weekly pipeline report

Every Monday: open pipeline by stage, the deals that changed stage last week, and what was created, won and lost.

The Monday pipeline review usually opens with someone sharing the HubSpot deals board and scrolling column by column. This skill does that pass before the meeting: it totals open deals by stage, reads the stage history of every deal touched in the last seven days to see what actually advanced or slid back, and lists what was created, won and lost.

Sales leads and founders get one number to watch, open pipeline, and a short list of the deals that changed it. Deals that sat still stay out of the way.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- A HubSpot private app token in `HUBSPOT_ACCESS_TOKEN` with `crm.objects.deals.read` and `crm.objects.owners.read`, or a HubSpot connector with the same read access.
- Which deal pipeline to report on, if the account has more than one.

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **Map the pipeline stages** (HubSpot): Call `GET /crm/v3/pipelines/deals` and keep each stage's `id`, `label`, `displayOrder` and `metadata.isClosed`, so stage IDs such as `appointmentscheduled` or `98712345` read as names. Use the pipeline the team reviews (often `default`).
2. **Total the open pipeline** (HubSpot): Page through `POST /crm/v3/objects/deals/search` with `pipeline EQ <id>` and `dealstage NOT_IN` the closed stage IDs, requesting `dealname`, `amount`, `dealstage`, `hubspot_owner_id` and `createdate` with `limit: 200` (the search maximum) and the `after` cursor. Sum `amount` per stage and count deals with no amount on a line of their own.
3. **Find what changed stage** (HubSpot): Search for deals with `hs_lastmodifieddate GTE` seven days ago (epoch milliseconds), then call `POST /crm/v3/objects/deals/batch/read` with `propertiesWithHistory: ["dealstage"]`. A deal moved if its stage history has an entry with a `timestamp` inside the window; compare the `displayOrder` of the old and new stage to call it forward or back.
4. **Collect new, won and lost**: New deals have a `createdate` inside the window. Won and lost deals are those whose stage history entered the closed won or closed lost stage this week; keep `closed_lost_reason` for the lost ones. Map `hubspot_owner_id` to names with `GET /crm/v3/owners`.
5. **Write the report**: Save this week's totals by stage to a small JSON file and compare with last Monday's. Then write open pipeline and its change, the table by stage, up to 8 stage moves with owner and amount, and new, won and lost, leading with the single biggest change.

## Route B: the browser

### What you need

- Signed in to HubSpot as a user who can view all deals in the pipeline, not only their own.
- Know which deal pipeline to report on if the account has more than one.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://app.hubspot.com/contacts/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Open the deals board**: HubSpot opens your default account on the Contacts page; switch accounts in the top right if you have several. Go to **CRM > Deals** and pick the pipeline the team reviews from the pipeline dropdown above the board.
2. **Read the open stages**: In the board view, every stage column shows its deal count and total amount in the header. Write them down for each open stage, and count the cards whose amount is blank on a separate line. Last Monday's numbers come from your previous report.
3. **Find the deals that moved**: Switch to the list view (the table icon), add the filter **Last modified date** is **Last 7 days** and sort by it. Open each deal, hover **Deal stage** in the About section and open its property history (the clock icon): a stage set inside the last 7 days is a move, forward or back by the pipeline order.
4. **Collect new, won and lost**: Change the filter to **Create date** is **Last 7 days** for new deals. Then filter **Deal stage** is **Closed won** with **Close date** is **Last 7 days**, and the same for **Closed lost**, adding the **Closed lost reason** column with **Edit columns**.
5. **Write the report**: Open pipeline and its change since last Monday, the table by stage, up to 8 stage moves with owner and amount, and new, won and lost, leading with the biggest change.

Note: Reading the column headers is quick. Opening deals one by one for stage history gets slow past 30 or so modified deals; with more, build a custom Deals report under Reports that uses the Deal stage property history with a 7-day date filter, which lists every stage change in one table. The board totals and the API sum match as long as the same pipeline is selected.

## The report

- **Open pipeline** today and the change since last Monday.
- **By stage**: deal count and amount in each open stage, with each stage's change.
- **Stage moves**: deals that advanced or slid back this week, with owner and amount.
- **New, won and lost**: counts and amounts, with the closed lost reason where one was recorded.
- One line on the deal to raise first in the pipeline review.

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "hubspot-weekly-pipeline-report/<date of this run, e.g. 2026-10-16>",
  "item_key": "hubspot-weekly-pipeline-report",
  "project": "Acme",
  "source": "HubSpot weekly pipeline report skill",
  "kind": "metric",
  "title": "Open pipeline up $86k this week",
  "metric": {
    "label": "Open pipeline",
    "value": 1284000,
    "prefix": "$",
    "better": "higher",
    "period_start": "<start of the period, ISO 8601>",
    "period_end": "<end of the period, ISO 8601>"
  },
  "glance": [
    {
      "type": "Grid",
      "props": {
        "columns": 3
      },
      "children": [
        {
          "type": "Stat",
          "props": {
            "label": "New deals",
            "value": 14,
            "delta": 27
          }
        },
        {
          "type": "Stat",
          "props": {
            "label": "Closed won",
            "value": "$118k",
            "tone": "ok"
          }
        },
        {
          "type": "Stat",
          "props": {
            "label": "Closed lost",
            "value": "$64k"
          }
        }
      ]
    },
    {
      "type": "Badges",
      "props": {
        "items": [
          {
            "label": "6 moved forward",
            "tone": "ok"
          },
          {
            "label": "2 slid back",
            "tone": "warn"
          },
          {
            "label": "3 open deals with no amount"
          }
        ]
      }
    }
  ],
  "widget": [
    {
      "type": "Table",
      "props": {
        "columns": [
          "Stage",
          "Deals",
          "Amount",
          "vs last week"
        ],
        "align": [
          "left",
          "right",
          "right",
          "right"
        ],
        "rows": [
          [
            "Appointment scheduled",
            18,
            "$212,000",
            "+$24,000"
          ],
          [
            "Qualified to buy",
            15,
            "$286,000",
            "+$41,000"
          ],
          [
            "Presentation scheduled",
            11,
            "$248,000",
            "-$18,000"
          ],
          [
            "Decision maker bought-in",
            9,
            "$301,000",
            "+$52,000"
          ],
          [
            "Contract sent",
            5,
            "$237,000",
            "-$13,000"
          ]
        ]
      }
    },
    {
      "type": "Table",
      "props": {
        "columns": [
          "Deal",
          "Owner",
          "Stage move",
          "Amount"
        ],
        "align": [
          "left",
          "left",
          "left",
          "right"
        ],
        "rows": [
          [
            "Northwind renewal",
            "Dana",
            "Presentation → Decision maker",
            "$64,000"
          ],
          [
            "Contoso data platform",
            "Sam",
            "Qualified → Presentation",
            "$38,000"
          ],
          [
            "Fabrikam pilot",
            "Priya",
            "Decision maker → Contract sent",
            "$27,000"
          ],
          [
            "Tailspin annual plan",
            "Lena",
            "Appointment → Qualified",
            "$22,000"
          ],
          [
            "Wingtip seats",
            "Theo",
            "Qualified → Presentation",
            "$18,000"
          ],
          [
            "Adatum add-on",
            "Sam",
            "Appointment → Qualified",
            "$12,000"
          ],
          [
            "Proseware expansion",
            "Marco",
            "Contract sent → Presentation (back)",
            "$45,000"
          ],
          [
            "Litware renewal",
            "Dana",
            "Decision maker → Qualified (back)",
            "$31,000"
          ]
        ]
      }
    },
    {
      "type": "Callout",
      "props": {
        "text": "Raise first: Proseware ($45,000) went back from Contract sent to Presentation scheduled.",
        "tone": "warn"
      }
    }
  ],
  "size": "md"
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

Set `period_start` and `period_end` to the window the number covers: the tile names it from them ("Last 7 days", "Today", "This month"). For a count right now (open items, a balance), send `"period_label": ""` so no period shows; for another name, send it as `period_label` (at most 24 characters).

## Run it on a schedule

Suggested: Mondays at 8:00 (`0 8 * * 1`). From cron, with the agent signed in on that machine:

```bash
0 8 * * 1 claude -p "Run the hubspot-weekly-pipeline-report skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/hubspot-weekly-pipeline-report#schedule

Source: https://briefkin.dev/skills/hubspot-weekly-pipeline-report

What your agent needs

  • A HubSpot private app token in HUBSPOT_ACCESS_TOKEN with crm.objects.deals.read and crm.objects.owners.read, or a HubSpot connector with the same read access.

  • Which deal pipeline to report on, if the account has more than one.

Connecting HubSpot

  1. HubSpot MCP server, HubSpot's remote server at https://mcp.hubspot.com. HubSpot also offers a Claude connector built on the same server; you sign in with your HubSpot user and it sees what that user can see (docs).
  2. API with a private app token. Create a private app in your HubSpot account settings, give it only the scopes the report reads (crm.objects.deals.read, crm.objects.contacts.read, crm.objects.companies.read, crm.objects.owners.read), and store its token in HUBSPOT_ACCESS_TOKEN.

The MCP server and connector can create and update records, so for unattended reports a private app with only .read scopes is the safer credential.

Questions

Why are some deals missing from the total?

Deals with an empty amount add nothing to a sum. The report counts them on their own line so a rep can fill them in; it never guesses an amount.

How does it tell a stage move from an ordinary edit?

It reads the dealstage property history, which records every stage change with a timestamp. Changing an amount or a close date bumps hs_lastmodifieddate but adds nothing to the stage history, so those deals are not counted as moves.

Do I need Briefkin to use the HubSpot weekly pipeline report skill?

No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a stat tile, so you can glance at it instead of asking again.

Which agents can run it?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.

Can it work without an API or MCP server, from my browser?

Yes. Switch the data source to "Your browser" and the steps change to the HubSpot pages themselves: the agent opens app.hubspot.com/contacts in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.

Watch open pipeline on your board, run after run

Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.

Free during the open beta. No card.