Skip to content

AGENTS.md

138 lines · 4.8 KB · Markdown
Raw

@kody/hubspot — agent notes

Human setup and intent live in README.md. This file is for agents: imports, smoke/dryRun execute snippets, and edge cases. Secrets and OAuth by name only — never paste tokens. Do not disable live webhooks or jobs.

Auth

CallResolves to
omithubspot / hubspotPrivateAppToken
account: 'work'hubspot-work / hubspotPrivateAppToken-work
integrationName: 'hubspot-work'that exact OAuth name
secretName: 'hubspotPrivateAppToken-work'that exact private-app secret
auth: 'oauth' | 'privateApp'force lane when both exist

Hosts: api.hubapi.com, api.hubspot.com. REST base: https://api.hubapi.com.

Do not hard-code a personal portal id or alias.

Import paths

ExportImport
overview / connect URLs / export mapkody:@kody/hubspot
accountskody:@kody/hubspot/accounts
accountkody:@kody/hubspot/account
smoke-testkody:@kody/hubspot/smoke-test
objectskody:@kody/hubspot/objects
list-objectskody:@kody/hubspot/list-objects
get-objectkody:@kody/hubspot/get-object
search-objectskody:@kody/hubspot/search-objects
list-contactskody:@kody/hubspot/list-contacts
get-contactkody:@kody/hubspot/get-contact
search-contactskody:@kody/hubspot/search-contacts
create-contactkody:@kody/hubspot/create-contact
update-contactkody:@kody/hubspot/update-contact
list-companieskody:@kody/hubspot/list-companies
get-companykody:@kody/hubspot/get-company
search-companieskody:@kody/hubspot/search-companies
create-companykody:@kody/hubspot/create-company
update-companykody:@kody/hubspot/update-company
list-dealskody:@kody/hubspot/list-deals
get-dealkody:@kody/hubspot/get-deal
search-dealskody:@kody/hubspot/search-deals
create-dealkody:@kody/hubspot/create-deal
update-dealkody:@kody/hubspot/update-deal
list-ticketskody:@kody/hubspot/list-tickets
get-ticketkody:@kody/hubspot/get-ticket
search-ticketskody:@kody/hubspot/search-tickets
create-ticketkody:@kody/hubspot/create-ticket
update-ticketkody:@kody/hubspot/update-ticket
requestkody:@kody/hubspot/request
typeskody:@kody/hubspot/types

Prefer static kody:@kody/hubspot/... imports from execute. Do not lead with packages.invoke.

Smoke test (read-only)

import smokeTest from 'kody:@kody/hubspot/smoke-test'

export default async function main() {
	return await smokeTest()
	// Without credentials: { ok: true, live: false } + connect / private-app URLs
	// With credentials: { live: true, hasPortalId } (no email)
}

Do not write live CRM records from a smoke test.

dryRun / confirm

Mutating helpers require confirm: true. Pass dryRun: true to inspect the REST payload without calling HubSpot. ./request treats GET and CRM search POST as read-only; other POST / PUT / PATCH / DELETE need confirmation.

import createContact from 'kody:@kody/hubspot/create-contact'

export default async function main() {
	const preview = await createContact({
		properties: { email: 'pat@example.com', firstname: 'Pat' },
		dryRun: true,
	})
	// After the user confirms the exact properties:
	return await createContact({
		properties: { email: 'pat@example.com', firstname: 'Pat' },
		confirm: true,
	})
}

Read helpers:

import listContacts from 'kody:@kody/hubspot/list-contacts'
import listDeals from 'kody:@kody/hubspot/list-deals'

export default async function main() {
	const contacts = await listContacts({ limit: 10 })
	const deals = await listDeals({ limit: 10 })
	return { contactCount: contacts.items.length, dealCount: deals.items.length }
}

Generic objects / unwrapped REST:

import getObject from 'kody:@kody/hubspot/get-object'
import searchObjects from 'kody:@kody/hubspot/search-objects'
import request from 'kody:@kody/hubspot/request'

export default async function main() {
	const listing = await getObject({ objectType: 'p_listings', id: '123' })
	const matches = await searchObjects({
		objectType: 'contacts',
		query: 'acme',
		limit: 10,
	})
	const raw = await request({
		path: '/crm/v3/objects/contacts',
		query: { limit: 5, properties: 'email,firstname' },
	})
	return { listingId: listing.id, matches: matches.items.length, raw }
}

Edge cases

  • Look up a contact by email with idProperty: 'email'.
  • Helpers project slim CRM records (id, selected properties, timestamps). Use ./request when you need extra fields or associations payloads.
  • Generic writes stay on ./request. Typed create/update helpers cover only contacts, companies, deals, and tickets.
  • Prefer dedicated helpers over assembling ./request when one exists.