{"site":{"name":"Koji","description":"AI-native customer research platform that helps teams conduct, analyze, and synthesize customer interviews at scale.","url":"https://www.koji.so","contentTypes":["blog","documentation"],"lastUpdated":"2026-05-10T22:44:13.818Z"},"content":[{"type":"documentation","id":"efcdc938-acff-447c-b6d5-a4a6770dfe4b","slug":"hubspot-research-integration","title":"Sync Koji Customer Interviews to HubSpot: Live Insights on Every Contact","url":"https://www.koji.so/docs/hubspot-research-integration","summary":"Pipe Koji AI-moderated interview output into HubSpot in three steps: (1) create four custom contact properties (latest quote, themes, quality score, transcript URL), (2) deploy a small forwarder that verifies the Koji webhook signature and PATCHes those properties via the HubSpot CRM API, and (3) subscribe to the interview.analysis_ready event in Koji webhook settings. End-to-end latency is under 5 seconds. The integration unlocks real-time HubSpot workflows like churn alerts, save-the-deal Slack pings, and onboarding interventions driven by interview themes — patterns that traditional survey tools cannot deliver because they lack AI moderation, theme extraction, and quality scoring. Works with HubSpot Private Apps on free CRM tier or Operations Hub for native workflow actions; a Zapier no-code path is also covered. Anonymous Mode interviews are handled correctly (no email present, so no write).","content":"\nHubSpot is where most go-to-market teams already live. Sales reps work deals there, CS managers track health scores there, marketers route nurture sequences there. The problem: the qualitative customer evidence that should inform every one of those workflows usually sits in a separate research tool — or a long-forgotten Notion doc.\n\nThis guide shows you how to bridge that gap by piping Koji's AI-moderated interview output directly into HubSpot. Within an hour you can have every CSAT call, churn interview, and onboarding feedback session land on the matching HubSpot contact, complete with the verbatim quote, the AI-extracted theme, and a transcript link.\n\n## What You Will Build\n\nBy the end of this guide, your stack will look like this:\n\n1. A participant completes a Koji interview (voice or text).\n2. Koji runs analysis, scores quality, extracts themes and a structured summary.\n3. A `interview.analysis_ready` webhook fires from Koji to your endpoint.\n4. Your endpoint matches the participant email to a HubSpot contact and writes the insight to custom properties on the contact (and optionally the associated company).\n5. HubSpot workflows can now route, alert, or filter on those properties — for example, auto-paging the CSM when a high-value account drops a churn signal.\n\nThe whole pattern works with the Koji webhooks documented in [Webhook Setup](/docs/webhook-setup) and the standard HubSpot CRM API.\n\n## Why This Beats the Default\n\nMost teams collect feedback in a survey tool, paste a CSV into HubSpot once a quarter, and call it integrated. That has three failure modes:\n\n- **Latency.** A churn signal from a Tuesday interview lands in HubSpot the following month — far too late to save the account.\n- **Loss of context.** A 5-point CSAT score is dumped onto the contact, but the verbatim explanation never makes it across.\n- **No structured signal.** Free-text feedback cannot be filtered, segmented, or used as a workflow trigger.\n\nKoji solves all three. The webhook arrives within seconds of interview completion. The payload includes the verbatim quote, the theme tags, and the structured answers from all six question types — `open_ended`, `scale`, `single_choice`, `multiple_choice`, `ranking`, and `yes_no`. See [Structured Questions in AI Interviews](/docs/structured-questions-guide) for a primer on how those become first-class HubSpot fields you can filter on.\n\n## Prerequisites\n\n- A Koji workspace with webhooks enabled (every plan, including Free).\n- A HubSpot account with API access — Operations Hub Starter is the cheapest tier that supports custom-coded workflow actions, but the integration also works with a Private App on the free CRM tier.\n- A HubSpot Private App access token. Create one in **Settings → Integrations → Private Apps** with the `crm.objects.contacts.write`, `crm.schemas.contacts.write`, and `crm.objects.companies.write` scopes.\n- A small forwarder. You can use a serverless function (Vercel, Cloudflare Workers, AWS Lambda), an existing backend route, or a no-code tool like Zapier or Make. Examples below use Node 20 on Vercel.\n\n## Step 1: Create Custom Properties in HubSpot\n\nBefore any data flows in, create a home for it. In **Settings → Properties → Contact properties**, add the following four custom properties:\n\n| Property name | Internal name | Type | Notes |\n| --- | --- | --- | --- |\n| Latest Interview Quote | `koji_latest_quote` | Multi-line text | The most representative verbatim |\n| Latest Interview Themes | `koji_latest_themes` | Multi-line text | Comma-separated tags |\n| Interview Quality Score | `koji_quality_score` | Number | 1.0 – 5.0 |\n| Latest Transcript URL | `koji_transcript_url` | Single-line text | Deep link into Koji |\n\nYou can mirror the same four properties at the company level if you want account-wide rollups.\n\n## Step 2: Build the Forwarder\n\nThe forwarder receives Koji webhook payloads, looks up the matching HubSpot contact by email, and PATCHes the four custom properties. Here is a Vercel-style handler:\n\n```js\n// /api/koji-to-hubspot.js\nimport crypto from 'node:crypto'\n\nconst KOJI_WEBHOOK_SECRET = process.env.KOJI_WEBHOOK_SECRET\nconst HUBSPOT_TOKEN = process.env.HUBSPOT_PRIVATE_APP_TOKEN\n\nexport default async function handler(req, res) {\n  const raw = await readRaw(req)\n\n  // 1. Verify the Koji signature (HMAC-SHA256)\n  const sig = req.headers['x-koji-signature']\n  const expected = crypto\n    .createHmac('sha256', KOJI_WEBHOOK_SECRET)\n    .update(raw)\n    .digest('hex')\n  if (sig !== expected) return res.status(401).end()\n\n  const payload = JSON.parse(raw)\n  if (payload.event !== 'interview.analysis_ready') return res.status(200).end()\n\n  const { respondent_email, summary, themes, quality_score, transcript_url, quotes } = payload.data\n\n  if (!respondent_email) return res.status(200).end()\n\n  // 2. Look up the HubSpot contact by email\n  const lookup = await fetch(\n    `https://api.hubapi.com/crm/v3/objects/contacts/${encodeURIComponent(respondent_email)}?idProperty=email`,\n    { headers: { Authorization: `Bearer ${HUBSPOT_TOKEN}` } }\n  )\n  if (lookup.status === 404) return res.status(200).end() // Skip unknown contacts\n  const contact = await lookup.json()\n\n  // 3. Patch custom properties\n  await fetch(`https://api.hubapi.com/crm/v3/objects/contacts/${contact.id}`, {\n    method: 'PATCH',\n    headers: {\n      Authorization: `Bearer ${HUBSPOT_TOKEN}`,\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify({\n      properties: {\n        koji_latest_quote: quotes?.[0] ?? summary,\n        koji_latest_themes: (themes ?? []).join(', '),\n        koji_quality_score: quality_score,\n        koji_transcript_url: transcript_url,\n      },\n    }),\n  })\n\n  return res.status(200).json({ ok: true })\n}\n```\n\nDeploy the function and copy its public URL.\n\n## Step 3: Register the Webhook in Koji\n\nIn Koji, open **Settings → Integrations → Webhooks → Add Webhook Endpoint** and paste the forwarder URL. Subscribe to `interview.analysis_ready` — that is the event with the analysis already attached.\n\nWhen you click save, Koji fires a verification request. The forwarder returns 200 and the endpoint goes live. Run a quick end-to-end test with one real interview and check that the contact's custom properties update inside HubSpot. Latency from interview completion to HubSpot write is typically under 5 seconds.\n\n## Step 4: Trigger HubSpot Workflows on the New Data\n\nThis is where the integration earns its keep. A few patterns to copy:\n\n- **Churn alert.** Create a workflow filtered on `koji_latest_themes contains \"cancel\"` and `Lifecycle stage = Customer`. Action: notify the CSM and create a high-priority task. Pair with [Churned Customer Interviews](/docs/churned-customer-interviews) for the upstream interview design.\n- **Save-the-deal hand-off.** Filter on `koji_quality_score >= 4` and `themes contains \"pricing\"`. Action: create a Slack message to the AE owning the deal. Combine with [Pricing Research Interviews](/docs/pricing-research-interviews) for inspiration on which questions to ask.\n- **Onboarding intervention.** Filter new customers whose first-week interview surfaced \"confused\" or \"stuck\". Action: enroll into a high-touch onboarding sequence.\n- **Account-level rollups.** Use a HubSpot Custom Coded Workflow Action to aggregate the most common themes across all contacts in the same company, then write the result to a company property like `koji_account_top_theme`.\n\n## No-Code Alternative: Zapier or Make\n\nIf you prefer not to maintain a serverless function, the same flow works through Zapier:\n\n1. **Trigger:** Webhook by Zapier — paste the URL into Koji.\n2. **Filter:** Only continue if `event = interview.analysis_ready`.\n3. **Search:** HubSpot — Find Contact (search by email).\n4. **Action:** HubSpot — Update Contact, mapping the four properties above.\n\nMake.com and n8n follow the same pattern. Latency rises slightly (10–30 seconds depending on plan) but the integration takes 10 minutes to assemble end-to-end. The shared design language with [Send Research Insights to Slack](/docs/slack-research-insights-integration) means you can fork the same Zap and point it at HubSpot.\n\n## Anonymous Mode and PII\n\nIf your study runs in Anonymous Mode, Koji webhook payloads strip the `respondent_email`. The forwarder above will skip those interviews silently, which is the correct behaviour: there is no contact to enrich, so no HubSpot write happens. For mixed studies (some respondents identified, some anonymous), the integration handles both cases without configuration.\n\n## Verifying Signatures\n\nAlways verify the `x-koji-signature` HMAC header before processing the payload. The Vercel example above shows the canonical pattern. Without verification, anyone who guesses your endpoint URL could write fake interview data into your HubSpot CRM. The same signing scheme is used in [Research Automation: Building Real-Time Pipelines with Webhooks](/docs/research-automation-webhooks).\n\n## What Competitors Cannot Match\n\nSurvey tools like SurveyMonkey or Typeform can push raw answers into HubSpot — but they push raw text. Without the AI moderator that Koji runs on every interview, you do not get themes, you do not get quality scores, and you do not get an extracted verbatim. The HubSpot field becomes \"the user typed `idk`\" instead of \"the user's #1 reason for cancelling was `unclear pricing on annual plans`.\"\n\nThe combination of Koji's AI-moderated probing and HubSpot's workflow engine turns research from a quarterly readout into a real-time GTM signal. That is the integration RevOps teams have been building manually for years; with Koji it is an evening of work.\n\n## Related Resources\n\n- [Webhook Setup](/docs/webhook-setup)\n- [Send Research Insights to Slack](/docs/slack-research-insights-integration)\n- [Research Automation with Webhooks](/docs/research-automation-webhooks)\n- [How to Use Your CRM Data for Targeted AI Research](/docs/crm-research-integration-guide)\n- [API Authentication](/docs/api-authentication)\n- [Headless API Overview](/docs/headless-api-overview)\n- [Structured Questions in AI Interviews](/docs/structured-questions-guide)\n","category":"API Reference","lastModified":"2026-05-10T03:24:42.019941+00:00","metaTitle":"HubSpot + Koji: Sync Customer Interview Insights to Every Contact","metaDescription":"Use Koji webhooks plus the HubSpot API to push interview transcripts, AI themes, and quality scores onto HubSpot contact and company records in real time.","keywords":["hubspot customer research integration","sync interview data to hubspot","hubspot voice of customer","koji hubspot webhook","customer insight crm sync","qualitative data in hubspot","hubspot research integration"],"aiSummary":"Pipe Koji AI-moderated interview output into HubSpot in three steps: (1) create four custom contact properties (latest quote, themes, quality score, transcript URL), (2) deploy a small forwarder that verifies the Koji webhook signature and PATCHes those properties via the HubSpot CRM API, and (3) subscribe to the interview.analysis_ready event in Koji webhook settings. End-to-end latency is under 5 seconds. The integration unlocks real-time HubSpot workflows like churn alerts, save-the-deal Slack pings, and onboarding interventions driven by interview themes — patterns that traditional survey tools cannot deliver because they lack AI moderation, theme extraction, and quality scoring. Works with HubSpot Private Apps on free CRM tier or Operations Hub for native workflow actions; a Zapier no-code path is also covered. Anonymous Mode interviews are handled correctly (no email present, so no write).","aiPrerequisites":["Koji workspace with webhooks enabled","HubSpot account with API access (free CRM tier or higher)","Ability to deploy a small webhook forwarder (serverless function or Zapier)"],"aiLearningOutcomes":["Create the four required HubSpot custom contact properties","Deploy a webhook forwarder that verifies Koji HMAC signatures","Map Koji interview.analysis_ready payloads to HubSpot CRM PATCH calls","Configure HubSpot workflows to act on theme, quality_score, and quote properties","Set up the same flow with no-code (Zapier, Make, n8n)","Handle Anonymous Mode interviews correctly without leaking PII"],"aiDifficulty":"intermediate","aiEstimatedTime":"12 min read"}],"pagination":{"total":1,"returned":1,"offset":0}}