Agent Skills: HubSpot Hello World

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/hubspot-hello-world

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/hubspot-pack/skills/hubspot-hello-world

Skill Files

Browse the full folder contents for hubspot-hello-world.

Download Skill

Loading file tree…

plugins/saas-packs/hubspot-pack/skills/hubspot-hello-world/SKILL.md

Skill Metadata

Name
hubspot-hello-world
Description
|

HubSpot Hello World

Overview

Create, read, update, and delete CRM records using the HubSpot API. Covers contacts, companies, and deals with real endpoints and SDK methods.

Prerequisites

  • Completed hubspot-install-auth setup
  • Private app with scopes: crm.objects.contacts.read, crm.objects.contacts.write
  • @hubspot/api-client installed

Instructions

Step 1: Create a Contact

import * as hubspot from '@hubspot/api-client';

const client = new hubspot.Client({
  accessToken: process.env.HUBSPOT_ACCESS_TOKEN!,
});

// POST /crm/v3/objects/contacts
const contactResponse = await client.crm.contacts.basicApi.create({
  properties: {
    firstname: 'Jane',
    lastname: 'Doe',
    email: 'jane.doe@example.com',
    phone: '(555) 123-4567',
    company: 'Acme Corp',
    lifecyclestage: 'lead',
  },
  associations: [],
});

console.log(`Created contact: ${contactResponse.id}`);
// Output: Created contact: 12345

Step 2: Read a Contact

// GET /crm/v3/objects/contacts/{contactId}
const contact = await client.crm.contacts.basicApi.getById(
  contactResponse.id,
  ['firstname', 'lastname', 'email', 'phone', 'lifecyclestage'],
  undefined, // propertiesWithHistory
  ['companies'] // associations to include
);

console.log(`${contact.properties.firstname} ${contact.properties.lastname}`);
console.log(`Email: ${contact.properties.email}`);
console.log(`Stage: ${contact.properties.lifecyclestage}`);

Step 3: Update a Contact

// PATCH /crm/v3/objects/contacts/{contactId}
const updated = await client.crm.contacts.basicApi.update(
  contactResponse.id,
  {
    properties: {
      lifecyclestage: 'marketingqualifiedlead',
      phone: '(555) 987-6543',
    },
  }
);

console.log(`Updated at: ${updated.updatedAt}`);

Step 4: Create a Company and Associate

// POST /crm/v3/objects/companies
const company = await client.crm.companies.basicApi.create({
  properties: {
    name: 'Acme Corp',
    domain: 'acme.com',
    industry: 'TECHNOLOGY',
    numberofemployees: '150',
    annualrevenue: '5000000',
  },
  associations: [],
});

// Associate contact with company
// PUT /crm/v4/objects/contacts/{contactId}/associations/companies/{companyId}
await client.crm.associations.v4.basicApi.create(
  'contacts',
  contactResponse.id,
  'companies',
  company.id,
  [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 1 }]
);

console.log(`Associated contact ${contactResponse.id} with company ${company.id}`);

Step 5: Create a Deal

// POST /crm/v3/objects/deals
const deal = await client.crm.deals.basicApi.create({
  properties: {
    dealname: 'Acme Enterprise License',
    amount: '50000',
    dealstage: 'appointmentscheduled', // default pipeline stage ID
    pipeline: 'default',
    closedate: '2026-06-30T00:00:00.000Z',
    hubspot_owner_id: '12345', // owner user ID
  },
  associations: [
    {
      to: { id: company.id },
      types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 5 }],
    },
    {
      to: { id: contactResponse.id },
      types: [{ associationCategory: 'HUBSPOT_DEFINED', associationTypeId: 3 }],
    },
  ],
});

console.log(`Created deal: ${deal.properties.dealname} ($${deal.properties.amount})`);

Output

  • Created contact with properties and lifecycle stage
  • Read contact with specific properties and associations
  • Updated contact properties
  • Created company and associated it with the contact
  • Created deal associated with both contact and company

Error Handling

| Error | Code | Cause | Solution | |-------|------|-------|----------| | 409 Conflict | 409 | Contact with email already exists | Use crm.contacts.basicApi.getById or search first | | 400 Bad Request | 400 | Invalid property name or value | Check property names in Settings > Properties | | 404 Not Found | 404 | Record ID doesn't exist | Verify ID or check if archived | | PROPERTY_DOESNT_EXIST | 400 | Custom property not created | Create in Settings > Properties first |

Examples

Search for Existing Contacts

// POST /crm/v3/objects/contacts/search
const searchResults = await client.crm.contacts.searchApi.doSearch({
  filterGroups: [
    {
      filters: [
        {
          propertyName: 'email',
          operator: 'EQ',
          value: 'jane.doe@example.com',
        },
      ],
    },
  ],
  properties: ['firstname', 'lastname', 'email'],
  limit: 10,
  after: 0,
  sorts: [{ propertyName: 'createdate', direction: 'DESCENDING' }],
});

console.log(`Found ${searchResults.total} contact(s)`);

Delete (Archive) a Record

// DELETE /crm/v3/objects/contacts/{contactId}
await client.crm.contacts.basicApi.archive(contactResponse.id);
console.log('Contact archived');

Resources

Next Steps

Proceed to hubspot-local-dev-loop for development workflow setup.