> For the complete documentation index, see [llms.txt](https://v2.dataos.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v2.dataos.info/concepts/resources/nilus/batch/batch-sources/hubspot.md).

# HubSpot

[HubSpot](https://www.hubspot.com/) is a CRM platform covering marketing, sales, customer service, and operations. Nilus uses HubSpot as a batch source to extract CRM objects, companies, contacts, deals, tickets, products, custom objects, into a downstream warehouse for revenue and support analytics.

Under the hood, Nilus calls the [HubSpot CRM API](https://developers.hubspot.com/docs/api/overview) using a Private App access token. CRM objects are fetched as a full snapshot per run; HubSpot does not support incremental loading via this connector.

## Requirements

Connectivity and credentials must both be in place before the pipeline can run.

### Connectivity

* The Nilus runtime must be able to reach `https://api.hubapi.com` over HTTPS.
* The Private App must hold the relevant `crm.objects.<object>.read` and `crm.schemas.read` scopes for every object in `source_table`.
* Missing scopes cause `403 Forbidden` errors at runtime.

{% hint style="info" %}
Private App tokens give CRM-wide read access. Store the token via Nilus secrets/projections rather than embedding the literal value in YAML.
{% endhint %}

### Required parameters

| Parameter | Required | Default | Description                                                                                                |
| --------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| `api_key` | Yes      | -       | HubSpot Private App access token (`pat-...`). Created in HubSpot → Settings → Integrations → Private Apps. |

### URI format

```
hubspot://?api_key=<hubspot-private-app-access-token>
```

## Supported objects

| Object                                 | Merge key | Strategy | Description                                                                                     |
| -------------------------------------- | --------- | -------- | ----------------------------------------------------------------------------------------------- |
| `companies`                            | -         | replace  | Organization records.                                                                           |
| `contacts`                             | -         | replace  | Leads and customers.                                                                            |
| `deals`                                | -         | replace  | Sales deals.                                                                                    |
| `tickets`                              | -         | replace  | Support tickets.                                                                                |
| `products`                             | -         | replace  | Product catalog.                                                                                |
| `quotes`                               | -         | replace  | Sales quotes.                                                                                   |
| `schemas`                              | `name`    | merge    | CRM schema definitions for all objects.                                                         |
| `custom:<object_name>`                 | -         | replace  | Custom CRM object.                                                                              |
| `custom:<object_name>:<assoc1,assoc2>` | -         | replace  | Custom object with associations expanded inline (passed to HubSpot's `associations` parameter). |

### Custom object examples

Ingest a custom object:

```yaml
source:
  address: hubspot://?api_key={HUBSPOT_API_KEY}
  options:
    source_table: custom:invoices
```

Include associations (comma-separated, passed straight to HubSpot's `associations` parameter):

```yaml
source:
  address: hubspot://?api_key={HUBSPOT_API_KEY}
  options:
    source_table: custom:invoices:contacts,deals
```

### Behavior

* The full dataset is retrieved on every run (HubSpot pagination handled internally).
* Schemas are inferred from the API response.
* Nested JSON fields are preserved as structured data.
* Associations are returned as nested arrays when requested.

{% hint style="warning" %}
HubSpot CRM ingestion is full-refresh. **Do not** set `incremental_key`. For very large accounts, prefer separate pipelines per object and stagger schedules to stay under the API rate limit.
{% endhint %}

## Source options

| Option            | Required      | Description                                                                |
| ----------------- | ------------- | -------------------------------------------------------------------------- |
| `source_table`    | Yes           | One of the resources in the [supported objects](#supported-objects) table. |
| `incremental_key` | Not supported | HubSpot ingestion is full-refresh; do not set an incremental cursor.       |

## Sink options

| Option                 | Required | Description                                                                                               |
| ---------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| `dest_table`           | Yes      | Destination table name. Use one stable target per source resource so re-runs merge cleanly.               |
| `incremental_strategy` | Yes      | Destination write behavior. Use `merge` for time-aware resources, `replace` for snapshot-style resources. |

## Sample Nilus config

```yaml
name: hubspot-companies-batch
version: v1alpha
type: nilus
spec:
  type: batch
  compute: universe-compute
  source:
    address: hubspot://?api_key={HUBSPOT_API_KEY}
    options:
      source_table: companies
  sink:
    address: dataos://warehouse?purpose=rw
    options:
      dest_table: crm.hubspot_companies
      incremental_strategy: replace
```

## Behavior and capabilities

* **Pipeline mode**: HubSpot runs as a `batch` source.
* **Object selection**: set `source.options.source_table` to one CRM object, `schemas`, or `custom:<object_name>` form from the supported objects table.
* **Fetch semantics**: HubSpot ingestion is full-refresh for CRM objects; use `replace` unless the object explicitly documents a merge key.
* **Associations**: custom object associations can be expanded by appending comma-separated association names to `source_table`.
* **API limits**: HubSpot enforces account-level API limits. For large accounts, split high-volume objects into separate pipelines and stagger schedules.

## Troubleshooting

| Symptom                 | Likely cause                                                                                                 | Resolution                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `401 Unauthorized`      | Invalid or expired Private App token.                                                                        | Issue a new Private App in HubSpot → Settings → Integrations → Private Apps and re-supply via Nilus secrets. |
| `403 Forbidden`         | Private App is missing scopes for the requested object.                                                      | Add the `crm.objects.<object>.read` and `crm.schemas.read` scopes and reissue the token.                     |
| `429 Too Many Requests` | HubSpot account-level rate limit exceeded by frequent or parallel pipelines.                                 | Reduce pipeline frequency, stagger parallel pipelines, or upgrade the HubSpot plan.                          |
| Custom object not found | Wrong API name in `custom:<name>` (HubSpot custom objects use the developer-facing API name, not the label). | Find the API name in HubSpot → Settings → Objects → Custom Objects.                                          |

## Related docs

* [Batch sample configs](/concepts/resources/nilus/batch/sample-configs.md)
* [Understanding Batch Pipeline Config](/concepts/resources/nilus/batch/pipeline-config.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://v2.dataos.info/concepts/resources/nilus/batch/batch-sources/hubspot.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
