@hs-x/hubspot
v0.4.13
Published
Thin wrap over @hubspot/sdk with install scoping, portal-schema typing, and rate-limiter integration.
Readme
@hs-x/hubspot
@hs-x/hubspot is HS-X's Worker-safe HubSpot client, a thin wrap over
@hubspot/sdk that adds the
things an HS-X app needs at runtime: install scoping, portal-schema typing, and
rate-limiter integration. It is what backend handler code talks to when it
reaches into a portal through ctx.hubspot.
You normally do not install this directly. It is a transitive dependency of
@hs-x/runtime, and the runtime
constructs install-scoped clients for you. Reach for it explicitly only if you
are building lower-level tooling against HubSpot's REST API from inside a
Worker:
bun add @hs-x/hubspotimport { createHubSpotClient } from "@hs-x/hubspot";
const hubspot = createHubSpotClient({ accessToken });What it provides
| Export | Purpose |
| --- | --- |
| createHubSpotClient(options) | A HubSpotClient (the @hubspot/sdk HubSpot surface) wired with a custom fetch, base URL, and the credentials the runtime supplies |
| createHttpClient(options) | A lower-level, host-restricted fetch wrapper; HttpHubSpotHostRejectedError guards against off-host calls |
| HubSpotApiError, isHubSpotSdkApiError, isHubSpotRateLimitError | Error classification for the runtime's rate limiter and retry logic |
| Typed request/response shapes | The operations HS-X drives directly: properties, object schemas, card-view migration, Custom Channels, and visitor identification |
An ./effect subpath exposes the Effect-flavored, batching client the runtime
composes for queue-drained workflow actions:
import { createBatchingHubSpotClient } from "@hs-x/hubspot/effect";This package is Worker-safe (no Node built-ins). The dev-time developer-account
client for project upload, deploy, and dev sessions is the separate, Node-bound
@hs-x/hubspot-cli.
Conversations: Custom Channels and visitor identification
The managed client exposes the Conversations branches present in the pinned official HubSpot SDK. That currently means Custom Channels—channel registration, channel accounts, and messages—and visitor-identification token generation. Calls use the same access token, transport, retry policy, and rate budget as the rest of the client.
import {
type HubSpotConversationMessageCreateInput,
type HubSpotVisitorIdentificationTokenInput,
createHubSpotClient,
} from "@hs-x/hubspot";
export async function bridgeConversation(accessToken: string) {
const hubspot = createHubSpotClient({ accessToken });
const inbound = {
attachments: [],
channelAccountId: "account-456",
integrationIdempotencyId: "external-message-123",
integrationThreadId: "external-thread-789",
messageDirection: "INCOMING",
recipients: [
{
deliveryIdentifier: {
type: "CHANNEL_SPECIFIC_OPAQUE_ID",
value: "support-team",
},
},
],
senders: [
{
deliveryIdentifier: {
type: "CHANNEL_SPECIFIC_OPAQUE_ID",
value: "customer-123",
},
name: "Ada Lovelace",
},
],
text: "Hello from the external channel",
timestamp: new Date().toISOString(),
} satisfies HubSpotConversationMessageCreateInput;
// Replace 42 with the registered custom-channel id.
const message = await hubspot.conversations.customChannels.messages.create(42, inbound);
const visitor = {
email: "[email protected]",
firstName: "Ada",
lastName: "Lovelace",
} satisfies HubSpotVisitorIdentificationTokenInput;
const { token } = await hubspot.conversations.visitorIdentification.generateToken(visitor);
return { message, token };
}The package re-exports SDK-derived types for each supported level:
| Surface | Exported types |
| --- | --- |
| Clients | HubSpotConversationsClient, HubSpotCustomChannelsClient |
| Channels | HubSpotCustomChannel, HubSpotCustomChannelCreateInput, HubSpotCustomChannelUpdateInput, HubSpotCustomChannelListOptions |
| Channel accounts | HubSpotCustomChannelAccount, HubSpotCustomChannelAccountCreateInput, HubSpotCustomChannelAccountUpdateInput, HubSpotCustomChannelAccountGetOptions, HubSpotCustomChannelAccountListOptions, HubSpotCustomChannelAccountStagingTokenUpdateInput |
| Messages | HubSpotConversationMessage, HubSpotConversationMessageCreateInput, HubSpotConversationMessageUpdateInput, HubSpotConversationMessageGetOptions, HubSpotConversationParticipant, HubSpotConversationMessageAttachment |
| Visitor identification | HubSpotVisitorIdentificationToken, HubSpotVisitorIdentificationTokenInput |
They are projections of the pinned SDK rather than hand-maintained wire shapes, so an SDK upgrade type-checks the surface for drift.
This is deliberately not a general Conversations client. It does not add inbox
or thread list/read/write APIs that the pinned SDK does not expose. A Custom
Channels message may carry an external integrationThreadId, but that is a
field on the message operation—not a HubSpot thread-CRUD surface.
Part of HS-X
HS-X is a leaveable, type-safe HubSpot app framework on Cloudflare Workers.
Start with the CLI (npm i -g @hs-x/cli, then hs-x init myapp). See
@hs-x/cli and the docs at
hs-x.dev/docs.
License
Apache-2.0
