Obtain a private app access token with CRM object read scopes for the object types you intend to query
POST to https://api.hubapi.com/collector/graphql with Content-Type: application/json and a GraphQL query body selecting a CRM object (e.g. contacts) with property fields and an associations block for a related object (e.g. companies)
Include 'after' cursor variables in the query for pagination of both the primary object list and the nested association list
Parse the response JSON under 'data.CRM.contact_collection' (or the relevant object collection path), iterating 'items' and their nested 'associations' collections
Implement cursor-based pagination by extracting 'paging.next.after' from the response and re-issuing the query with the updated cursor
Known gotchas
HubSpot's GraphQL endpoint is distinct from the REST API base URL and may not support all CRM object types available via REST — verify the schema with an introspection query before building production integrations
The GraphQL API enforces its own rate limits separate from the REST API; heavy use of deeply nested association queries can exhaust query complexity budgets quickly
Property names in GraphQL queries must match the internal HubSpot property name (snake_case), not the label; using display labels returns null values silently
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp