Getting call notes into Salesforce and HubSpot without losing half of them
HubSpot stores a logged call as its own record, with a body, an outcome and a list of associations. Salesforce stores the same event as an Activity hanging off two lookups: the person it was with, and the record it was about. That structural difference explains most of the pain when you share call notes with your CRM, because a note can save perfectly and still be invisible on the opportunity your VP opens on Friday morning.
I pulled both vendors’ documentation on 20 Aug 2026 while writing this. One of them refused to hand over its field reference, which I’ve flagged near the bottom rather than guessing around it. Everything below is either quoted from a page fetched that day or marked as unchecked.
What it means to share call notes with your CRM
Sharing a call note with your CRM writes three separate things, not one: an activity record carrying a timestamp, the note text itself, and a set of associations that tie the note to a contact, a company and usually a deal. The text is the easy part. Associations decide whether the note is ever found again.
There are three routes in, and they fail differently. Copy and paste is the honest baseline, it never breaks, and it dies the week a rep runs seven calls in a day. A native integration from your notetaker or dialer writes the record for you and inherits whatever association rules the CRM admin set. A custom API push gives you control over every field and hands you the rate limits as a bonus prize.
Salesforce: the Activity needs a Who and a What
In Salesforce, logging a call creates an activity record, and two lookup fields decide where that record shows up. One points at a person (a contact or a lead). The other points at the related record, which is normally an account or an opportunity. Both matter. If your integration fills in the contact and leaves the opportunity blank, the note appears on the person’s timeline and nowhere near the deal, so pipeline review shows an opportunity with no recent activity even though the rep talked to the buyer for 41 minutes on Tuesday.
That is the single most common complaint I could find behind CRM note-sharing tickets, and it isn’t a bug in anyone’s product. It’s a mapping choice somebody made once, in a settings screen, and then forgot.
The second Salesforce trap arrives when you backfill. Writing a year of historical notes through the API means burning against a hard daily allocation. Salesforce’s platform API limits cheat sheet gives Enterprise and Professional editions “100,000 + (number of licenses x calls per license type) + purchased API Call Add-Ons” per 24 hours, with per-license figures of “Salesforce: 1,000” on those editions and “Salesforce: 5,000” on Unlimited and Performance. Developer Edition gets “15,000”. Concurrent long-running requests are capped separately at “Production orgs and Sandboxes: 25”.
Read that formula twice before you plan a migration. A 20-seat Enterprise org has roughly 120,000 calls a day to play with, which sounds enormous until a sync tool retries failed writes in a loop and another integration is already sitting on the same allocation.
HubSpot: the call is its own object, and associations are configurable
HubSpot’s model is flatter and, honestly, easier to reason about. A call is an object. You attach it to whatever records it belongs to. In the UI, HubSpot’s guide to creating or logging activities on a record tells you to “click the Log call icon to log a made call”, then set a date, an outcome and a direction, then hit “Log activity”. The default outcome list is fixed and short: Busy, Connected, Left live message, Left voicemail, No answer, and Wrong number.
Through the API the shape is more explicit. HubSpot’s calls engagement guide documents hs_call_body as “The description of the call, including any notes”, hs_timestamp as the required property that marks the call’s time of creation, and hs_call_duration as “The duration of the call in milliseconds”. Recording links go in hs_call_recording_url, where “Only HTTPS, secure URLs will be accepted”. Associations ride along in an associations array on the create request, each entry carrying a to.id and an associationTypeId.
Two of those will bite you. hs_call_duration is milliseconds, so a well-meaning script that sends 1,847 produces a call that lasted under two seconds. And hs_call_disposition takes an internal GUID rather than the friendly outcome label you read in the interface, which means the value you can see on screen is not the value the API wants.
The part worth setting up properly is automatic association. HubSpot’s automatic activity association settings let an admin configure “meetings logged on a contact to also automatically associate with the primary company and its most recently associated open deal”, with per-activity choices that run from None through “Log to 1 most recently associated” and “Log to 5 most recently associated” up to logging to all associated records. Super Admin permission is required to change it.
Pick the wrong option there and a single discovery call gets stapled onto five open deals, three of which have nothing to do with the conversation. Reporting then tells you those deals are progressing. They aren’t.
Where each piece of a call note lands
| Piece of the note | Salesforce | HubSpot |
|---|---|---|
| Summary text | Activity comments field on the logged call | hs_call_body |
| When it happened | Activity date on the record | hs_timestamp, required on create |
| Outcome | Call result picklist | hs_call_disposition, GUID not label |
| Length | Call duration in seconds | hs_call_duration in milliseconds |
| Recording link | Custom or packaged field, varies by org | hs_call_recording_url, HTTPS only |
| Who it was with | Person lookup on the Activity | Association to the contact |
| Which deal it belongs to | Related-record lookup, often left empty | Association to the deal, can be automatic |
Six things that break
- The deal association is missing. Notes land on the contact, dashboards read the opportunity, and the two never meet. Check this first, always.
- Auto-association is too generous. Five open deals inherit a call about one of them. Your activity metrics quietly become fiction.
- Duration units. Seconds in one system, milliseconds in the other, and nobody notices until a report claims the team averages 0.4-second calls.
- The whole transcript gets pasted in. Text fields have limits, formatting collapses, and a 9,000-word transcript in an activity body is unreadable in a timeline anyway. Push a summary and next steps. Link the recording.
- Two tools log the same call. A dialer writes one record, a notetaker writes another, and now the account has duplicate activities with slightly different timestamps. Deduplicating after the fact is miserable.
- Contact matching by email fails. The buyer joined from a personal address, or from a colleague’s calendar invite, so the note attaches to a new contact record that nobody watches.
Five of those six are configuration, not code. That’s the good news and the annoying news at the same time, because configuration problems get discovered by an unhappy sales manager rather than by a failing test.
Getting a note worth sharing in the first place
None of the mechanics above help if the note itself is four bullet points a rep typed from memory two hours after the call ended. That’s the part Craqly handles: a live assistant that listens during the call and produces the summary, the objections and the next steps while the conversation is still happening, so the thing you push into Salesforce or HubSpot is written before anyone forgets the numbers.
Pricing, checked on craqly.com/pricing on 20 Aug 2026: Starter is $0 with 20 credits a month, Pro is $38/mo or $19/mo billed yearly with 180 credits, Pro Max is $59/mo or $39/mo yearly with 420 credits, and Ultra is $99/mo or $69/mo yearly with 780 credits. The page states the credit rule as “1 credit = 1 minute of live session · credits reset every month”. Yearly billing saves 20%, and stealth mode is listed on every tier including the free one. Full details are on the pricing page.
For the writing side of this, our meeting summary templates give you a shape that survives being pasted into a CRM field, and the piece on how to capture action items covers what to keep versus what to drop. Once the note is filed, follow-up templates for sales calls pick up where the CRM record stops.
What I couldn’t verify on 20 Aug 2026
Salesforce’s object reference and field reference pages for the Task object render client-side, and every fetch I ran against the Task object reference returned a navigation index instead of field text. So I’m not quoting a character limit for the Salesforce comments field, or exact API names for call result and call duration, because I couldn’t read them today. Open the page in a browser and check your own org’s field-level setup before you build against it. I also haven’t tested a native Craqly connector into either CRM, and I’m not going to imply one exists.
If you only fix one thing this week, open the association settings in whichever CRM you run and log a test call against a real deal. Then go look at the deal and see whether the note is there. It’s a five-minute check, and it catches the failure that makes every other piece of this pointless.