> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ancha.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These docs describe the Ancha CLI, npm package @ancha-labs/cli version 0.1.4, and the hosted workspace at app.ancha.io. Coding agents should start at https://docs.ancha.io/coding-agents. Run the CLI as `ancha` after `npm install -g @ancha-labs/cli`, or as `npx -y @ancha-labs/cli@0.1.4` without installing. Pass --json for machine-readable output, or set ANCHA_JSON=1. Every command ends with a `next:` line naming the next command. Exit codes: 0 pass, 1 a check failed or a comparison regressed, 2 usage, config or authentication error, 3 infrastructure error, 4 unimplemented endpoint with --strict.

# HubSpot

> A stateful replica of HubSpot's CRM v3 API: companies, contacts and deals with search, batches, associations, pipelines and properties.

The HubSpot replica implements the CRM v3 REST API for companies, contacts and deals, including search with delayed indexing, batch operations, associations and read-only pipelines and properties. Its key is `hubspot`.

## Connect

| Variable | Value |
| - | - |
| `HUBSPOT_API_URL` | Base URL. Paths start with `/crm/v3/`. |
| `HUBSPOT_ACCESS_TOKEN` | Fake private-app token. Send `Authorization: Bearer <token>`. |

```js Node theme={null}
const response = await fetch(process.env.HUBSPOT_API_URL + '/crm/v3/objects/companies', { headers: { Authorization: 'Bearer ' + process.env.HUBSPOT_ACCESS_TOKEN } });
const companies = await response.json();
```

This is what `ancha connect hubspot --lang ts` prints. Existing v3 clients work when you set their base URL to `HUBSPOT_API_URL`.

## Endpoints

| Method | Path |
| - | - |
| `GET` | `/crm/v3/objects/:type` |
| `POST` | `/crm/v3/objects/:type` |
| `GET` | `/crm/v3/objects/:type/:id` |
| `PATCH` | `/crm/v3/objects/:type/:id` |
| `DELETE` | `/crm/v3/objects/:type/:id` |
| `POST` | `/crm/v3/objects/:type/search` |
| `POST` | `/crm/v3/objects/:type/batch/:operation` |
| `GET` | `/crm/v3/properties/:type` |
| `GET` | `/crm/v3/properties/:type/:property` |
| `GET` | `/crm/v3/pipelines/:type` |
| `GET` | `/crm/v3/pipelines/:type/:id` |
| `GET` | `/crm/v3/pipelines/:type/:id/stages` |
| `GET` | `/crm/v3/pipelines/:type/:id/stages/:stage` |
| `GET` | `/crm/v3/associations/:from/:to/types` |
| `POST` | `/crm/v3/associations/:from/:to/batch/:operation` |
| `GET` | `/crm/v3/objects/:type/:id/associations/:to` |
| `PUT` | `/crm/v3/objects/:type/:id/associations/:to/:toId/:associationType` |
| `DELETE` | `/crm/v3/objects/:type/:id/associations/:to/:toId/:associationType` |

`:type` is `companies`, `contacts` or `deals`, or the type IDs `0-2`, `0-1` and `0-3`. All endpoints are partial. Unsupported routes, fields, operators and options return HubSpot's error shape with an `ancha: not implemented:` message and `x-ancha-gap: 1`. HubSpot's newer date-based routes, such as `/crm/objects/2026-09/...`, are not implemented.

## Behavior

* **Search is delayed.** Direct reads and lists see writes at once. Search sees a new or changed record only after 2 simulated seconds, as HubSpot's search index lags. Archived records leave search at once.
* **Search syntax.** `filterGroups` (up to 5 groups, 6 filters each, 18 in total; filters in a group are ANDed, groups are ORed), `query`, one `sorts` entry, `properties`, `limit` (default 10, at most 200) and `after`. Operators: `EQ`, `NEQ`, `LT`, `LTE`, `GT`, `GTE`, `BETWEEN`, `IN`, `NOT_IN`, `HAS_PROPERTY`, `NOT_HAS_PROPERTY`.
* **Lists** return 10 records by default and at most 100, with an `after` cursor.
* **Batches** take 1 to 100 inputs for `read`, `create`, `update` and `archive`.
* **Properties are a fixed catalog.** Companies: `name`, `domain`, `website`, `description`, `industry`, `city`, `state`, `country`, `phone`, `numberofemployees`, `annualrevenue`, `lifecyclestage`. Contacts: `firstname`, `lastname`, `email`, `phone`, `mobilephone`, `company`, `jobtitle`, `lifecyclestage`, `hs_lead_status`. Deals: `dealname`, `amount`, `closedate`, `pipeline`, `dealstage`, `description`, `dealtype`. All three also have `external_id` and `hubspot_owner_id`. Unknown properties are rejected.
* **Associations** use HubSpot's default type IDs: contact to company `1` (primary) and `279`, deal to company `5` (primary) and `341`, deal to contact `3`, and their reverse IDs.
* **Permissions.** The token has read and write scopes for all three objects. Company `102` is outside the app's access: reading it fails and lists and searches leave it out.

## Starter data

The `hubspot-starter` dataset is the portal **Acme** (`510001`): nine companies, thirteen contacts and eight deals.

| Object | ID | Record |
| - | - | - |
| Company | `101` | Ridgeway Robotics, `ridgeway-robotics.example`, manufacturing, 850 employees, lifecycle stage `opportunity` |
| Company | `102` | Helix Manufacturing, a customer. Not accessible to the token. |
| Company | `103` | Pinecrest Health, hospital and health care, 1,900 employees, `customer` |
| Company | `104` | Bluefield Logistics, logistics, 620 employees, `opportunity` |
| Company | `105` | Kestrel Credit Union, banking, 410 employees, `customer` |
| Company | `106` | Harbor Foods, food production, 2,300 employees, `lead` |
| Company | `107` | Summit Freight, transportation, 350 employees, `customer` |
| Company | `108` | Lakeview Retail, retail, 1,200 employees, `salesqualifiedlead` |
| Company | `109` | Redwood Labs, software, 90 employees, `opportunity` |
| Contact | `201`, `202` | Erin Walsh (VP Operations) and Paul Young (Warehouse Systems Lead) at Ridgeway Robotics |
| Contact | `203`, `204` | Nora Bell (CIO) and James Ortiz (Director of Analytics) at Pinecrest Health |
| Contact | `205`, `206` | Owen Hart (VP Operations) and Grace Lin (IT Security Lead) at Bluefield Logistics |
| Contact | `207`, `208` | Carla Diaz (Head of Data) and Peter Novak (Procurement Manager) at Kestrel Credit Union |
| Contact | `209` | Lucy Grant, Operations Analyst at Harbor Foods |
| Contact | `210`, `211` | Daniel Reyes (COO) and Megan Shaw (BI Manager) at Summit Freight |
| Contact | `212`, `213` | Rob Fisher (Director of Ecommerce, Lakeview Retail) and Hannah Cole (CTO, Redwood Labs) |
| Deal | `301` | "Ridgeway Robotics — Analytics rollout", 96000, closes 2026-11-30, stage `presentationscheduled` |
| Deal | `302` | "Pinecrest Health — Enterprise plan", 144000, `closedwon` |
| Deal | `303` | "Bluefield Logistics — Pilot", 36000, closes 2026-12-12, `presentationscheduled` |
| Deal | `304` | "Kestrel Credit Union — Renewal", 48000, closes 2026-11-20, `presentationscheduled` |
| Deal | `305` | "Harbor Foods — Analytics starter", 18000, closes 2027-01-31, `appointmentscheduled` |
| Deal | `306` | "Summit Freight — Expansion", 27000, closes 2026-12-31, `qualifiedtobuy` |
| Deal | `307` | "Lakeview Retail — Ecommerce dashboards", 52000, closes 2027-02-15, `qualifiedtobuy` |
| Deal | `308` | "Redwood Labs — Platform plan", 75000, `closedlost` |
| Pipeline | `default` | "Sales Pipeline": `appointmentscheduled`, `qualifiedtobuy`, `presentationscheduled`, `contractsent`, `closedwon`, `closedlost` |

Each contact is associated with its company, and each deal with its company and its primary contact.

## Checks

HubSpot has no state checks. Use trace checks:

```yaml theme={null}
- id: moved_deal
  trace: { called: "PATCH /crm/v3/objects/deals/301" }
- id: no_deletes
  trace: { not_called: "DELETE /crm/*" }
```

## Limits

* Companies, contacts and deals only: no tickets, custom objects, engagements or owners.
* No workflows, webhooks, OAuth, merges, upserts or restores.
* No rate limits.


## Related topics

- [Worlds](https://docs.ancha.io/concepts/worlds.md)
- [Introduction](https://docs.ancha.io/index.md)
- [Changelog](https://docs.ancha.io/changelog.md)
- [Tools](https://docs.ancha.io/tools/overview.md)
- [ancha world gen](https://docs.ancha.io/cli/world-gen.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.