---
name: "import_from_hubspot"
area: "imports"
title: "Import from HubSpot"
price: "$0.001 per record imported (created or updated)"
method: "POST"
url: "https://api.conecto.chat/v1/tools/import_from_hubspot"
mcp_server: "https://api.conecto.chat/mcp/imports"
auth: "Authorization: Bearer <conecto_sk_ key>"
docs_url: "https://conecto.chat/tools/imports/import_from_hubspot"
---

# Import from HubSpot (`import_from_hubspot`)

Imports a HubSpot account in the background: companies, contacts, deals and notes, linked as they were.

Import a HubSpot account: companies, contacts (linked to their company), deals (stage, amount, currency, close date, and the company and contact they belong to) and notes (on their contact's timeline, else added to their deal or company). Needs a private app access token. Make one in HubSpot under Development > Legacy apps > Create a private app, with the read scopes crm.objects.companies.read, crm.objects.contacts.read and crm.objects.deals.read; the token is on its Auth tab. Wrong credentials are refused before anything is reserved or charged; the token is kept only encrypted while the import runs, then erased. Contacts match existing ones by email, companies by domain, then name. Runs in the background for up to 15 minutes and imports up to max_records records; when more remain, the result has next_cursor: call again with the same arguments plus next_cursor to continue. Running it again never duplicates anything: changed records are updated, unchanged ones skipped. Unchanged records are free, and 1,000 imported records cost $1. max_records x $0.001 is reserved while it runs and only what was imported is charged; lower max_records if your balance is smaller.

Price: $0.001 per record imported (created or updated). A call that fails costs nothing.

## Use it when

The business moves its CRM from HubSpot.

- For contacts from a spreadsheet, use [import_csv](https://conecto.chat/tools/imports/import_csv.md).

## Say this to your agent

> We're leaving HubSpot. Bring over our contacts, companies, deals and notes. Here's the private app token.

## Inputs

| Name | Type | Required | Description | Allowed values | Default |
|---|---|---|---|---|---|
| `access_token` | string | yes | The HubSpot private app access token (starts with pat-). 10 to 500 characters. Stored encrypted and shown only as [redacted]. |  |  |
| `max_records` | integer | no | The most records this run may create or update (and reserve $0.001 each for). 1 to 100,000. |  | `10000` |
| `next_cursor` | string | no | The next_cursor a previous run of this import returned, to continue where it stopped. Up to 2,000 characters. |  |  |
| `default_currency` | string | no | The currency of deal amounts that name none (HubSpot leaves it blank when the account has a single currency). Matches ^[A-Za-z]{3}$. |  | `"USD"` |

## Example

Written for Hansen & Voss, a restaurant-equipment wholesaler in Hamburg with 60 staff.

MCP: call `import_from_hubspot` on the MCP server `https://api.conecto.chat/mcp/imports` with these arguments:

```json
{
  "access_token": "pat-eu1-00000000-0000-0000-0000-000000000000",
  "default_currency": "EUR"
}
```

REST:

```bash
curl https://api.conecto.chat/v1/tools/import_from_hubspot \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"access_token": "pat-eu1-00000000-0000-0000-0000-000000000000", "default_currency": "EUR"}'
```

## Response

This tool runs in the background. The first reply has status `202`:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "import_from_hubspot",
  "status": "running",
  "reserved_usd": "$10.00",
  "poll": "GET /v1/calls/5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93 (or the account_get_call tool) until status is succeeded or failed. You are charged only when it succeeds."
}
```

Poll `GET https://api.conecto.chat/v1/calls/<call_id>` (or call `account_get_call`) until `status` is `succeeded` or `failed`. When it succeeds, `output` holds the result:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "import_from_hubspot",
  "area": "imports",
  "status": "succeeded",
  "cost_usd": "$0.009",
  "error": null,
  "message": null,
  "latency_ms": 4210,
  "at": "2026-10-14T08:00:00+00:00",
  "bot": "Pip",
  "person": null,
  "input": {
    "access_token": "[redacted]",
    "default_currency": "EUR"
  },
  "output": {
    "source": "hubspot",
    "done": true,
    "records_imported": 9,
    "imported": {
      "companies": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      },
      "contacts": {
        "created": 3,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      },
      "deals": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      },
      "notes": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      }
    }
  }
}
```

`output`: When it finishes: source, done, records_imported, imported (per kind: created, updated, unchanged, skipped), and when more remain next_cursor, stopped_because and how to continue.

## Errors

| Code | Status | When | Fix |
|---|---|---|---|
| `credentials_refused` | 422 | HubSpot refused the token: it is wrong, revoked, or may not read contacts. | Make a private app with the read scopes the description names, and send its token. |
| `vendor_unavailable` | 502 | The other service did not answer. | Try again in a few minutes, with the same next_cursor if you passed one; nothing was charged. |
| `in_progress` | 409 | An import from the same tool is running already. | Wait for it (account_get_call), then continue with the next_cursor it returns. |
| `invalid_cursor` | 400 | next_cursor is not one this import returned. | Pass back exactly the next_cursor of the last run, or leave it out to start again (nothing is duplicated). |

The refusals every tool can give (401 key, 402 balance, 429 limits) are on the errors page: https://conecto.chat/docs/errors.md

## Related

- [import_csv](https://conecto.chat/tools/imports/import_csv.md): Imports contacts or companies from a CSV, as text or a link, matching columns by their names; importing it again updates instead of duplicating. $0.001 per record imported (created or updated).
- [import_from_pipedrive](https://conecto.chat/tools/imports/import_from_pipedrive.md): Imports a Pipedrive account in the background: organizations, persons, deals, notes and activities, linked as they were. $0.001 per record imported (created or updated).
- [import_from_zendesk](https://conecto.chat/tools/imports/import_from_zendesk.md): Imports Zendesk Support tickets in the background, with their public replies, and each requester as a contact; nobody is emailed. $0.001 per record imported (created or updated).
- [import_status](https://conecto.chat/tools/imports/import_status.md): What imports brought in so far, per source, and the last 10 import runs with their status, cost and next_cursor. Free up to 1,000,000 reads a month.
