Worlds / Sales and crm
HubSpot API
A local HubSpot CRM with contacts, companies, deals, pipelines, tasks and sequences. Test the agent that moves deals through stages, updates lifecycle stages and logs activity.
- Base path
/crm/v3- Auth
- Private app bearer token, the world key
- Endpoints
- 19
- Status
- Active today
This reference previews the surface the HubSpot world serves in the closed beta. Paths mirror the public HubSpot API; the exact subset is confirmed when your workflow is scoped.
Connect
The run gives your agent these bindings. Keep your SDK; change only where it sends requests.
| binding | meaning |
|---|---|
WORLDS_HUBSPOT_URL | This world's origin followed by /crm/v3 |
WORLDS_API_KEY | The world key, accepted wherever HubSpot expects a credential |
WORLDS_WORLD_ID | The isolated world's identity |
import { Client } from "@hubspot/api-client";
const hubspot = new Client({
accessToken: process.env.WORLDS_API_KEY,
basePath: process.env.WORLDS_HUBSPOT_URL,
});
const page = await hubspot.crm.deals.basicApi.getPage(10);API reference
Contacts
People in your CRM.
- GET
/crm/v3/objects/contactsList contacts - POST
/crm/v3/objects/contactsCreate a contact - GET
/crm/v3/objects/contacts/{contactId}Read a contact - PATCH
/crm/v3/objects/contacts/{contactId}Update a contact - POST
/crm/v3/objects/contacts/searchSearch contacts
Fields · 5
id | string | Contact id |
properties.email | string | Email address |
properties.firstname | string | First name |
properties.lastname | string | Last name |
properties.lifecyclestage | string | Lifecycle stage |
Companies
Organizations you work with.
- GET
/crm/v3/objects/companiesList companies - POST
/crm/v3/objects/companiesCreate a company - GET
/crm/v3/objects/companies/{companyId}Read a company - PATCH
/crm/v3/objects/companies/{companyId}Update a company
Fields · 5
id | string | Company id |
properties.name | string | Company name |
properties.domain | string | Website domain |
properties.industry | string | Industry |
properties.numberofemployees | string | Headcount |
Deals
Sales opportunities in a pipeline.
- GET
/crm/v3/objects/dealsList deals - POST
/crm/v3/objects/dealsCreate a deal - GET
/crm/v3/objects/deals/{dealId}Read a deal - PATCH
/crm/v3/objects/deals/{dealId}Update a deal - POST
/crm/v3/objects/deals/searchSearch deals
Fields · 6
id | string | Deal id |
properties.dealname | string | Deal name |
properties.amount | string | Deal amount |
properties.dealstage | string | Pipeline stage |
properties.pipeline | string | Pipeline |
properties.closedate | string | Close date |
Tickets
Service requests tracked in a pipeline.
- GET
/crm/v3/objects/ticketsList tickets - POST
/crm/v3/objects/ticketsCreate a ticket - PATCH
/crm/v3/objects/tickets/{ticketId}Update a ticket
Fields · 5
id | string | Ticket id |
properties.subject | string | Subject |
properties.content | string | Description |
properties.hs_pipeline_stage | string | Pipeline stage |
properties.hs_ticket_priority | string | Priority |
Associations
Links between CRM records.
- GET
/crm/v3/objects/{objectType}/{objectId}/associations/{toObjectType}List associations - PUT
/crm/v3/objects/{objectType}/{objectId}/associations/{toObjectType}/{toObjectId}/{associationType}Create an association
Fields · 3
fromObjectId | string | Source record |
toObjectId | string | Target record |
associationTypes | array | Type and category of the link |
Test workflow
- Prepare. Select the HubSpot setup for your workflow and review its starting records, including contacts, companies, deals.
- Connect. Configure your agent with this world's URL and key using the SDK example. Check that it reaches the intended API before running a test.
- Define. Describe the task, expected final changes and records that must stay untouched. Keep expected outcomes separate from the agent's instructions.
- Run and inspect. Use the dashboard or your workflow's generated CLI setup. Review final records and changes, then rerun from the same starting setup with the relevant failure conditions. Use Deployment and CI to automate the same workflow.
What to verify
- D-3104 in Closed Won with closedate today
- D-3105 still in Contract Sent
- D-3101 in Presentation Scheduled
- Ortiz Labs contacts have lifecyclestage customer
- No new contact created with an existing email
Test file
A task file names the jobs, the policy your agent is given and what the grader reads back from the world's final state. The agent never sees the expected outcomes.
# worlds/tasks.yaml · HubSpot
version: 2
connector: hubspot
seed: hubspot-starter
mode: isolated
policy: >
Update the pipeline from this week's notes. Ortiz Labs returned the
contract, close it won. Moss & Co booked a demo. Lee Holdings is still in
legal review. Contacts on Closed Won deals become Customers.
tasks:
- id: move-a-deal-to-the-next-stage-and-set-the-amount
prompt: Move a deal to the next stage and set the amount
- id: create-or-update-a-contact-without-duplicating-it
prompt: Create or update a contact without duplicating it
- id: enroll-a-contact-in-a-sequence-and-create-a-follow-up-task
prompt: Enroll a contact in a sequence and create a follow up task
expected:
- D-3104 in Closed Won with closedate today
- D-3105 still in Contract Sent
- D-3101 in Presentation Scheduled
- Ortiz Labs contacts have lifecyclestage customer
- No new contact created with an existing email
scenarios:
- rate-limited
- contact-exists
- property-invalidSee Tasks and outcomes for every field, and Deployment and CI to run the file on every pull request.
Failure conditions
Each one fires before the handler, at the same step on every run.
| condition | what the agent sees |
|---|---|
rate-limited | 429 with policyName TEN_SECONDLY_ROLLING |
contact-exists | 409 Conflict when creating a contact whose email exists |
property-invalid | 400 VALIDATION_ERROR on an unknown dealstage id |
token-expired | The OAuth access token expires after 30 minutes and returns 401 |
webhook-twice | deal.propertyChange is delivered two times |
Starting data
Start each run from the same records and relationships. The overview below describes the HubSpot starter; use the setup supplied for your workflow when preparing your own snapshot.
| Records | Starting setup |
|---|---|
| contacts | 80 across Lead, MQL, SQL and Customer lifecycle stages |
| companies | 20 with associated contacts |
| deals | 25 in the Sales Pipeline |
| sequences | 3, one already enrolling 12 contacts |
| tasks | 15 open, assigned to 4 owners |
The record shapes below reuse this world's API field definitions. They show illustrative values and placeholders, not an importable seed. API responses and seed input can differ; include all required records and references in the accepted import format for your workflow.
Contacts records
Contacts
People in your CRM.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Contact id |
properties.email | string | Email address |
properties.firstname | string | First name |
properties.lastname | string | Last name |
properties.lifecyclestage | string | Lifecycle stage |
{
"id": "<Contact id>",
"properties.email": "person@example.test",
"properties.firstname": "<First name>",
"properties.lastname": "<Last name>",
"properties.lifecyclestage": "<Lifecycle stage>"
}Companies records
Companies
Organizations you work with.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Company id |
properties.name | string | Company name |
properties.domain | string | Website domain |
properties.industry | string | Industry |
properties.numberofemployees | string | Headcount |
{
"id": "<Company id>",
"properties.name": "<Company name>",
"properties.domain": "<Website domain>",
"properties.industry": "<Industry>",
"properties.numberofemployees": "<Headcount>"
}Deals records
Deals
Sales opportunities in a pipeline.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Deal id |
properties.dealname | string | Deal name |
properties.amount | string | Deal amount |
properties.dealstage | string | Pipeline stage |
properties.pipeline | string | Pipeline |
properties.closedate | string | Close date |
{
"id": "<Deal id>",
"properties.dealname": "<Deal name>",
"properties.amount": "<Deal amount>",
"properties.dealstage": "<Pipeline stage>",
"properties.pipeline": "<Pipeline>",
"properties.closedate": "<Close date>"
}Tickets records
Tickets
Service requests tracked in a pipeline.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Ticket id |
properties.subject | string | Subject |
properties.content | string | Description |
properties.hs_pipeline_stage | string | Pipeline stage |
properties.hs_ticket_priority | string | Priority |
{
"id": "<Ticket id>",
"properties.subject": "<Subject>",
"properties.content": "<Description>",
"properties.hs_pipeline_stage": "<Pipeline stage>",
"properties.hs_ticket_priority": "<Priority>"
}Associations records
Associations
Links between CRM records.
| Field | Type | Meaning / relationship |
|---|---|---|
fromObjectId | string | Source record |
toObjectId | string | Target record |
associationTypes | array | Type and category of the link |
{
"fromObjectId": "<Source record>",
"toObjectId": "<Target record>",
"associationTypes": []
}