HubSpot + AI summary: GPT call summaries in the contact record
GPT summaries of calls and emails get written into the HubSpot contact record not by some native “AI”, but by a combination of three elements: a trigger on a completed activity via a workflow webhook, an OpenAI call on the transcript, and writing the result into a custom property or onto the timeline via the CRM API. HubSpot has no native mechanism that reads a call transcript and puts a structured summary into the right contact field by itself - and that is exactly why this is solved with code, not with settings.
At Exceltic.dev we build these setups for teams where reps have physically stopped writing call wrap-ups. The pattern is always the same: the more calls per day, the shorter or more often empty the note in the record. By the end of the quarter, half the pipeline is contacts where nobody remembers what was agreed. AI summaries do not “improve” the process, they close it: the wrap-up appears in the record automatically the moment the call ends, with no rep involved.
Why native AI summaries in HubSpot are not enough
HubSpot does have AI features around calls: transcription, highlighting of key moments in the recording interface. The problem is where this lives and in what form. Native insights are tied to the call recording screen and to conversation intelligence, not to a contact or deal property. You cannot reliably pull them into a specific field, filter lists by them, use them as a condition in a workflow, or show them to a rep at the very top of the record in a single line.
The second limitation is the format. A native summary answers the question “what was said”, but a sales team needs the answer to “what to do next”: the agreement, the next step, the objection, the budget, the date. That is not a transcript and not a retelling, it is field extraction. A language model with a defined prompt and schema produces exactly that structure; the native engine does not.
The third is language and tone. Teams that work across several markets want summaries in their own language, even if the call was in English, and in their own format. Native features do not give that level of control.
The same applies to emails. A long thread of ten messages is context that a new rep on the deal will not read. A summary of the thread in a single contact field solves the problem of handing work over between people. This is close in nature to what we covered in our piece on meeting transcripts in the lead record, only here the source is HubSpot itself.
What gets built
The setup consists of four parts: a trigger on a completed activity, retrieving the transcript or email text, the OpenAI call, and writing the result back into HubSpot. Let’s go through the technical details of each.
Trigger: workflow webhook, not the Webhooks API
Here is the first trap that homemade builds stumble on. The HubSpot Webhooks API does not support subscribing to engagements - calls, notes, emails, meetings and tasks. You cannot subscribe directly to the “call completed” event through a standard webhook subscription.
The working path is a workflow with a webhook action. In a contact-based or deal-based workflow you set a trigger on an activity (for example, “logged call” with a filled-in transcript), and the output is a webhook to your service with the call and contact ID. The webhook action in a workflow requires Operations Hub Professional or Enterprise. That is a budget constraint you need to know before you start, not after.
The alternative without Operations Hub is polling: your service periodically queries recent calls through the CRM API and processes the new ones. Cheaper on licensing, more expensive on latency, and harder on idempotency.
Retrieving the transcript
For calls the transcript is taken through the Recordings & Transcripts API. Recordings and transcripts in HubSpot are served via authenticated URLs, and there is a separate endpoint the integration uses to mark a recording as ready for transcription. If the telephony is external (Aircall, RingCentral and the like), the transcript may come from there - then OpenAI gets the text directly, bypassing HubSpot transcription.
For emails the thread text is read through the CRM API via the email engagement linked to the contact.
The OpenAI call
The transcript goes to Chat Completions with a system prompt that asks not for a retelling but for field extraction. The default model is gpt-4o-mini: it handles summarization, and it costs incomparably less than the higher-tier models. Billing is per token: roughly $0.15 per 1M input tokens and $0.60 per 1M output (always verify current numbers in OpenAI’s pricing).
To get a sense of scale: an average 20-minute call is around 3-4 thousand tokens of transcript. The summary on output is 200-400 tokens. One call costs a fraction of a cent. Even a hundred calls a day is single-digit dollars per month on the model.
The key is structured output. The prompt asks to return JSON with fixed fields: short summary, next step, objections, mentioned budget, date of next contact. Free model text cannot be written into a typed HubSpot property without losing meaning - so the JSON is parsed, and each field goes into its own place.
Writing back into HubSpot
In advance, once, a custom property is created via POST /crm/v3/properties/contacts with Bearer <private-app-token> authorization. The type is string with fieldType: textarea for the summary itself, with separate properties for “next step” and “date”. After each call the result is written via PATCH /crm/v3/objects/contacts/{id} into these fields.
If the summary should be visible in the activity feed and not only in the properties, it is additionally written onto the timeline as a note engagement, linked to the contact and the deal. The two options are not mutually exclusive: a property for filtering and workflows, a note on the timeline for reading in the context of the history.
Privacy and idempotency
Two questions that decide everything in production.
Privacy: the call transcript goes to a third-party service (OpenAI). For EU teams this is a matter of GDPR and a data processing agreement. OpenAI has terms under which API data is not used for training, and data residency options - but this has to be closed at the contract level and fixed in policy, not assumed. If the data cannot leave at all, the option is a self-hosted model, but that is a different budget.
Idempotency: one call must not produce two summaries on a webhook retry or a repeated poll. This is solved with a deduplication key - the call ID is written into a utility property or a local database, and reprocessing of the same ID is skipped. Without it, any network failure will leave a duplicate in the record.
How it works step by step
- A rep completes a call in HubSpot, the transcript appears on the recording.
- The workflow catches the “logged call” event and sends a webhook to your service with the call and contact ID.
- The service checks the ID against the deduplication key - if already processed, it exits.
- The service pulls the transcript through the Recordings & Transcripts API.
- The transcript goes to OpenAI Chat Completions with a structure-extraction prompt.
- The model returns JSON: summary, next step, objections, budget, date.
- The service parses the JSON and writes the fields via
PATCHinto the contact’s custom properties. - Optionally - it creates a note engagement on the timeline for reading in the feed.
- The call ID is marked as processed.
The whole chain from call completion to the summary appearing in the record is seconds. The rep opens the contact a minute later and sees the finished wrap-up.
A real case with numbers
A B2B team on HubSpot, 6 sales reps, around 70 outbound and inbound calls per day combined. Before the rollout the post-call note was filled in roughly 35% of the time, and even then in a single line. Handing a contact over between reps meant listening to recordings manually - 15-20 minutes per contact.
After rolling out AI summaries:
- Call wrap-up coverage is 100%, because it does not depend on a person.
- The “next step” field is filled in for every contact - a reminder workflow was built on top of it.
- Time to hand a contact over between reps dropped from 15-20 minutes to 1-2 minutes of reading.
- Model cost is about $9 per month at 70 calls a day on
gpt-4o-mini.
The main effect turned out to be not the saved minutes, but the fact that the head of sales could, for the first time, filter the pipeline by the content of calls - find every deal where a specific objection or competitor was mentioned, through a standard property filter. Previously that information existed only in the reps’ heads.
Who it fits
This solution is justified if:
- The team makes dozens of calls a day and notes are the first thing to suffer.
- Contacts are handed over between reps and context gets lost.
- You need filtering and automation based on the content of conversations, not just on the fact of a call.
- You have Operations Hub Pro/Enterprise (for the workflow webhook) or are willing to go with the polling option.
It is overkill if there are a handful of calls per week, or if the team disciplinedly writes wrap-ups itself. The technology does not fix a process that has no problem.
If you are still choosing which CRM to build these setups on and comparing approaches, our Kommo CRM review will be useful - the data model and API access there are arranged differently, and for some teams that simplifies exactly this kind of AI integration. And if HubSpot is already in place and the topic is other AI scenarios around calls, we covered a related subject in our piece on what HubSpot’s native Gong integration loses.
Term: engagement. In HubSpot this is an activity object - a call, note, email, meeting or task, linked to a contact, company or deal. The summary is written either into a property of the contact itself, or as a separate note engagement on its timeline.
Term: property. A field of an object in HubSpot. A custom property is created once via the Properties API and then filled in via the object update. Unlike text on the timeline, you can filter lists by a property and build conditions in a workflow.
Term: structured output. A mode in which a language model returns not free text but data following a defined schema (JSON with fixed fields). Without it, the extracted summary cannot be reliably distributed across typed CRM fields.
Frequently asked questions
Can you manage without Operations Hub Pro?
Yes, via polling: the service periodically queries recent calls through the CRM API itself and processes the new ones. The downside is latency between the call and the summary (depends on the polling interval) and more complex idempotency logic. The workflow webhook is faster and more reliable, but requires a paid Operations Hub plan.
Which OpenAI model is optimal?
For summarizing calls, gpt-4o-mini is a sensible baseline: quality is sufficient, cost is tens of times lower than the higher-tier models. It makes sense to bring in a higher-tier model only if the summary feeds into complex scenarios where nuances of intonation and subtext matter. For extracting “summary - next step - objection” there is almost no difference.
Is it safe to send call transcripts to OpenAI?
Data sent through the OpenAI API is not used to train models per the terms of use, but for EU teams it is still a GDPR matter: you need a data processing agreement and to fix it in internal policy. If the data cannot leave at all, the remaining option is a self-hosted model at a different budget. This is decided at the start of the project, not after the fact.
What if the transcript is inaccurate?
Summary quality is no higher than transcript quality. If the telephony produces poor transcription (noise, accents, interruptions), the summary will inherit that. That is why, for teams with critical calls, the transcript source is often a specialized telephony, and HubSpot receives the finished text already.
Can you summarize emails the same way, not just calls?
Yes, the mechanics are the same: the email thread text is read through the CRM API, goes to OpenAI, and the result is written into a contact property. This is especially useful when handing a deal over - the new rep sees a summary of the correspondence instead of ten emails.
Bottom line
GPT summaries of calls and emails in the HubSpot record are not a setting but a small yet careful build: a workflow webhook (or polling), the Recordings API, OpenAI with structured output, and writing into a custom property via the CRM API. There are exactly three technical traps - the absence of native webhooks on engagements, idempotency and privacy - and all of them are solved at the design stage. The model cost is negligible; the value is that the wrap-up of every call appears in the record with no rep involved and becomes filterable.
If notes after calls get filled in only every other time on your team, and context gets lost when contacts are handed over - at Exceltic.dev we build this integration around your telephony and summary format. Tell us what your call stack is and where the contacts live, and we will take it from there.