New

Now in Claude, ChatGPT, Cursor & more with our MCP server

Back to docs
API Reference

Sync Koji Customer Interviews to HubSpot: Live Insights on Every Contact

Push Koji interview transcripts, themes, and quality scores onto HubSpot contact and company records in real time using webhooks and the HubSpot API.

HubSpot 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.

This 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.

What You Will Build

By the end of this guide, your stack will look like this:

  1. A participant completes a Koji interview (voice or text).
  2. Koji runs analysis, scores quality, extracts themes and a structured summary.
  3. A interview.analysis_ready webhook fires from Koji to your endpoint.
  4. 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).
  5. 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.

The whole pattern works with the Koji webhooks documented in Webhook Setup and the standard HubSpot CRM API.

Why This Beats the Default

Most teams collect feedback in a survey tool, paste a CSV into HubSpot once a quarter, and call it integrated. That has three failure modes:

  • Latency. A churn signal from a Tuesday interview lands in HubSpot the following month — far too late to save the account.
  • Loss of context. A 5-point CSAT score is dumped onto the contact, but the verbatim explanation never makes it across.
  • No structured signal. Free-text feedback cannot be filtered, segmented, or used as a workflow trigger.

Koji 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 for a primer on how those become first-class HubSpot fields you can filter on.

Prerequisites

  • A Koji workspace with webhooks enabled (every plan, including Free).
  • 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.
  • 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.
  • 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.

Step 1: Create Custom Properties in HubSpot

Before any data flows in, create a home for it. In Settings → Properties → Contact properties, add the following four custom properties:

Property nameInternal nameTypeNotes
Latest Interview Quotekoji_latest_quoteMulti-line textThe most representative verbatim
Latest Interview Themeskoji_latest_themesMulti-line textComma-separated tags
Interview Quality Scorekoji_quality_scoreNumber1.0 – 5.0
Latest Transcript URLkoji_transcript_urlSingle-line textDeep link into Koji

You can mirror the same four properties at the company level if you want account-wide rollups.

Step 2: Build the Forwarder

The 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:

// /api/koji-to-hubspot.js
import crypto from 'node:crypto'

const KOJI_WEBHOOK_SECRET = process.env.KOJI_WEBHOOK_SECRET
const HUBSPOT_TOKEN = process.env.HUBSPOT_PRIVATE_APP_TOKEN

export default async function handler(req, res) {
  const raw = await readRaw(req)

  // 1. Verify the Koji signature (HMAC-SHA256)
  const sig = req.headers['x-koji-signature']
  const expected = crypto
    .createHmac('sha256', KOJI_WEBHOOK_SECRET)
    .update(raw)
    .digest('hex')
  if (sig !== expected) return res.status(401).end()

  const payload = JSON.parse(raw)
  if (payload.event !== 'interview.analysis_ready') return res.status(200).end()

  const { respondent_email, summary, themes, quality_score, transcript_url, quotes } = payload.data

  if (!respondent_email) return res.status(200).end()

  // 2. Look up the HubSpot contact by email
  const lookup = await fetch(
    `https://api.hubapi.com/crm/v3/objects/contacts/${encodeURIComponent(respondent_email)}?idProperty=email`,
    { headers: { Authorization: `Bearer ${HUBSPOT_TOKEN}` } }
  )
  if (lookup.status === 404) return res.status(200).end() // Skip unknown contacts
  const contact = await lookup.json()

  // 3. Patch custom properties
  await fetch(`https://api.hubapi.com/crm/v3/objects/contacts/${contact.id}`, {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${HUBSPOT_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      properties: {
        koji_latest_quote: quotes?.[0] ?? summary,
        koji_latest_themes: (themes ?? []).join(', '),
        koji_quality_score: quality_score,
        koji_transcript_url: transcript_url,
      },
    }),
  })

  return res.status(200).json({ ok: true })
}

Deploy the function and copy its public URL.

Step 3: Register the Webhook in Koji

In 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.

When 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.

Step 4: Trigger HubSpot Workflows on the New Data

This is where the integration earns its keep. A few patterns to copy:

  • 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 for the upstream interview design.
  • 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 for inspiration on which questions to ask.
  • Onboarding intervention. Filter new customers whose first-week interview surfaced "confused" or "stuck". Action: enroll into a high-touch onboarding sequence.
  • 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.

No-Code Alternative: Zapier or Make

If you prefer not to maintain a serverless function, the same flow works through Zapier:

  1. Trigger: Webhook by Zapier — paste the URL into Koji.
  2. Filter: Only continue if event = interview.analysis_ready.
  3. Search: HubSpot — Find Contact (search by email).
  4. Action: HubSpot — Update Contact, mapping the four properties above.

Make.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 means you can fork the same Zap and point it at HubSpot.

Anonymous Mode and PII

If 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.

Verifying Signatures

Always 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.

What Competitors Cannot Match

Survey 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."

The 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.

Related Resources

Related Articles

Real-Time Research Insights: How to See Themes, Quotes, and Quality Scores as Interviews Complete

Stop waiting weeks for analysis — modern AI research platforms surface themes, structured-question distributions, sentiment, and quality-scored quotes the moment each interview ends. Here is how real-time research insights work in Koji and how to design studies that take advantage of them.

Send Research Insights to Slack: Real-Time Customer Interview Notifications via Webhooks

Pipe customer interview insights from Koji into your Slack workspace in real time. Use Koji webhooks to notify a #research channel the moment an interview completes, post quote highlights to #product-feedback, or alert #cs-alerts when a churn signal is detected. Step-by-step setup with a working Slack incoming webhook recipe.

API Authentication

Learn how to authenticate with the Koji API using API keys and Bearer tokens.

Research Automation: How to Build Real-Time Research Pipelines with Webhooks

Koji webhooks push interview and report data to your systems the instant something happens — enabling Slack alerts, CRM sync, automated tagging, and fully automated research pipelines that operate without manual intervention.

Webhook Setup

Receive real-time notifications when interviews complete and analysis finishes using webhooks.

How to Use Your CRM Data for Targeted AI Research: Import Participants and Personalize Every Interview

Your CRM already contains your best research sample. Learn how to export customer segments, import them into Koji, send personalized interview links, and get 3–5x higher response rates than generic research recruitment.

Headless API Overview

Manage interviews programmatically with the Koji REST API — start, message, and complete interviews from your own code.

Structured Questions in AI Interviews

Mix quantitative data collection — scales, ratings, multiple choice, ranking — with AI-powered conversational follow-up in a single interview.

Churned Customer Interviews: How to Talk to Users Who Left (and Win Them Back)

Learn how to conduct churned customer interviews that reveal why users really left — and how AI-moderated interviews make it scalable. Includes questions, structure, and templates.

Pricing Research Interviews: How to Understand What Customers Will Pay

Discover how to run qualitative pricing research interviews that reveal willingness to pay, price anchors, and the emotional logic behind buying decisions — beyond what surveys can surface.

How to Automate User Research: Build a Pipeline That Runs 24/7

A step-by-step guide to automating user research — from setting up AI-moderated interviews to continuous discovery pipelines that generate insights every week without manual effort.