Register a CRM card by POSTing to /crm/v3/extensions/cards/{appId} specifying the objectTypes array (e.g., CONTACT), display properties to pass as context, and the dataFetchUrl where HubSpot will call your server for card data
Implement the dataFetchUrl endpoint on your server to receive a GET request containing the portalId and the values of the configured display properties for the record being viewed
Return a JSON response from your endpoint matching the CRM card response schema: results array with objectId, title, link, and properties (list of label-value pairs to display)
Optionally include actions (buttons) in the response with actionType CONFIRMATION_ACTION or IFRAME to allow reps to trigger actions directly from the card
Configure card display settings (card title, display conditions) via the cards registration payload; use displayConditions to show the card only when a contact has a specific property set
Validate the incoming webhook from HubSpot using the X-HubSpot-Signature header on your data fetch endpoint to reject unauthorized requests
Known gotchas
HubSpot calls your dataFetchUrl synchronously while loading the CRM record — your endpoint must respond within 5 seconds or HubSpot displays an error state on the card; cache external data aggressively
CRM cards are app-specific and only visible to users in portals where the app is installed — they do not appear in portals that have not authorized the app
The properties displayed in the CRM card are read-only display elements; editing data through a CRM card requires implementing an IFRAME action that opens a modal with a form backed by your own API
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