fastify-xhubspot
fastify-xhubspot
Full HubSpot CRM integration for Fastify v5. Decorates a single fastify.xHubspot namespace exposing five service objects (contacts, companies, deals, engagement, customObjects) plus the raw HubSpot SDK client for advanced use.
Installation
npm install @xenterprises/fastify-xhubspot fastify@5
Quick Start
import Fastify from "fastify";
import xHubspot from "@xenterprises/fastify-xhubspot";
const fastify = Fastify();
// The plugin never reads process.env — the consumer owns env access
// and passes values in via register options.
await fastify.register(xHubspot, {
apiKey: process.env.HUBSPOT_ACCESS_TOKEN,
});
fastify.post("/contacts", async (request) => {
const contact = await fastify.xHubspot.contacts.create({
email: request.body.email,
firstname: request.body.firstName,
lastname: request.body.lastName,
});
return contact;
});
await fastify.listen({ port: 3000 });
Options
| Option | Type | Default | Required | Description |
|---|---|---|---|---|
apiKey | string | — | Yes* | HubSpot Private App access token (pat-na1-...). |
logRequests | boolean | false | No | Log each HubSpot API call at debug level. |
client | Client | — | No | Pre-built @hubspot/api-client Client instance (advanced/testing). When provided, apiKey is not required and no client is constructed. |
* Required unless client is provided. The plugin never reads process.env; pass configuration in explicitly.
Decorators
The plugin decorates a single namespace, fastify.xHubspot, with these members:
| Member | Type | Description |
|---|---|---|
fastify.xHubspot.client | Client | Raw @hubspot/api-client instance for advanced/unsupported calls. |
fastify.xHubspot.contacts | object | Contact management methods. |
fastify.xHubspot.companies | object | Company management methods. |
fastify.xHubspot.deals | object | Deal management methods. |
fastify.xHubspot.engagement | object | Engagement (notes, tasks, calls, emails) methods. |
fastify.xHubspot.customObjects | object | Custom CRM object methods. |
Contacts
- contacts.create — Create a new contact
- contacts.getById / contacts.getByEmail — Fetch a contact by ID or email
- contacts.update — Update contact properties
- contacts.delete — Archive a contact
- contacts.list — Page through all contacts
- contacts.search — Filter contacts by a property value
- contacts.batchCreate / contacts.batchUpdate — Bulk create or update contacts
- contacts.getAssociations / contacts.associate — Read and create contact associations
Companies
- companies.create — Create a new company
- companies.getById / companies.getByDomain — Fetch a company by ID or domain
- companies.update — Update company properties
- companies.delete — Archive a company
- companies.list — Page through all companies
- companies.search — Filter companies by a property value
- companies.batchCreate / companies.batchUpdate — Bulk create or update companies
- companies.getAssociations — Read company associations
Deals
- deals.create — Create a new deal
- deals.getById — Fetch a deal by ID
- deals.update — Update deal properties
- deals.delete — Archive a deal
- deals.list — Page through all deals
- deals.search — Filter deals by a property value
- deals.batchCreate / deals.getAssociations — Bulk create deals and read associations
Engagement
- engagement.createNote — Log a note against a contact
- engagement.createTask — Create a task linked to a contact
- engagement.createCall — Log a call against a contact
- engagement.createEmail — Log an email against a contact
- engagement.getEngagements — List all engagement IDs and types for a contact
- engagement.getNotes — List note engagements for a contact
- engagement.getTasks — List task engagements for a contact
- engagement.getCalls — List call engagements for a contact
- engagement.getEmails — List email engagements for a contact
Custom Objects
- customObjects.create — Create a custom object record
- customObjects.getById — Fetch a custom object by ID
- customObjects.update — Update custom object properties
- customObjects.delete — Archive a custom object record
- customObjects.list — Page through custom object records
- customObjects.search — Filter custom objects by a property value
- customObjects.batchCreate — Bulk create custom object records
- customObjects.associate / customObjects.getAssociations — Create and read custom object associations
Error Reference
All methods re-throw the original HubSpot API error unchanged on failure (the message is logged via fastify.log.error first — no tokens or raw SDK error dumps). Input validation errors throw before any API call is made.
| Condition | Error Message |
|---|---|
apiKey missing (and no client provided) | xhubspot: missing required option `apiKey` (string), e.g. `app.register(xHubspot, { apiKey: 'pat-na1-...' })` |
apiKey not a non-empty string | xhubspot: option `apiKey` must be a non-empty string, e.g. `app.register(xHubspot, { apiKey: 'pat-na1-...' })` |
client provided but not an object | xhubspot: option `client` must be a @hubspot/api-client Client instance, e.g. `app.register(xHubspot, { client: new Client({ accessToken: 'pat-na1-...' }) })` |
logRequests not a boolean | xhubspot: option `logRequests` must be a boolean, e.g. `app.register(xHubspot, { apiKey: 'pat-na1-...', logRequests: true })` |
| Missing/invalid required arg on any method | [xHubspot] <service>.<method> requires a <arg> |
| Company not found by domain | [xHubspot] Company not found for domain: <domain> (error has .status = 404) |
Environment Variables
The plugin never reads process.env. The consumer sets these variables and passes the values into app.register(xHubspot, { ... }) — this table documents that consumer convention, not plugin inputs.
| Variable | Description |
|---|---|
HUBSPOT_ACCESS_TOKEN | HubSpot Private App access token (App Settings → Private Apps), passed as the apiKey option. Not needed when a pre-built client is passed instead. |
How It Works
At registration the plugin creates a single @hubspot/api-client instance using the provided apiKey (unless a pre-built client is passed in), then decorates one fastify.xHubspot namespace exposing the client plus five service objects (contacts, companies, deals, engagement, customObjects). Each service wraps the relevant HubSpot v3 CRM API calls with input validation, debug logging (when logRequests: true), and error forwarding. The raw fastify.xHubspot.client is available for any HubSpot API surface not covered by the service objects.
AI Context
package: "@xenterprises/fastify-xhubspot"
type: fastify-plugin
use-when: HubSpot CRM integration — contacts, companies, deals, engagements, and custom objects
decorators: fastify.xHubspot (single namespace: client, contacts, companies, deals, engagement, customObjects)
env: HUBSPOT_ACCESS_TOKEN (consumer-set; passed as the `apiKey` register option — the plugin never reads process.env)
services: contacts, companies, deals, engagement, customObjects — each with create/get/update/delete/list/search/batch/associations
