<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Best practices in APIs &amp; Integrations</title>
    <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223431#M85457</link>
    <description>&lt;P&gt;Hello I tried your solution but&amp;nbsp;&lt;/P&gt;&lt;P&gt;I’ve checked your suggested solution in the documentation, but I couldn’t find the &lt;STRONG&gt;associations&lt;/STRONG&gt; parameter in the &lt;STRONG&gt;Search API.&lt;/STRONG&gt;&lt;BR /&gt;I’ve also tested it both via an &lt;STRONG&gt;HTTP request&lt;/STRONG&gt; and using the &lt;STRONG&gt;JavaScript SDK.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Here’s the code:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;async function search1() {
    const client = new Client({ accessToken });
    const body = {
        "filterGroups": [{
            "filters": [{
                "propertyName": "hs_object_id",
                "operator": "EQ",
                "value": "43230655641"
            }]
        }],
        "properties": ["dealname", "amount", "closedate"],
        "associations": ["contacts", "companies"],
        "limit": 100
    }
    const resp = await client.crm.deals.searchApi.doSearch(body);
    const { results, paging, ...rest } = resp
    console.log(results)
}


async function search2() {
    const url = 'https://api.hubapi.com/crm/v3/objects/0-3/search';
    const options = {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            "filterGroups": [{
                "filters": [{
                    "propertyName": "hs_object_id",
                    "operator": "EQ",
                    "value": "43230655641"
                }]
            }],
            "properties": ["dealname", "amount", "closedate"],
            "associations": ["contacts", "companies", "line_items"],
            "limit": 200
        })
    };

    const response = await fetch(url, options);
    const { results, paging, ...rest } = await response.json();
    console.log(results)
}

async function works() {
    const client = new Client({ accessToken});
    const resp = await client.crm.deals.basicApi.getById(43230655641, [],[], ["contacts", "companies", "line_items"]);
    console.log(resp)
}


search1() //sdk search api no assoc

// [
//   SimplePublicObject {
//     createdAt: 2025-09-01T11:41:53.093Z,
//     archived: false,
//     id: '43230655641',
//     properties: {
//       amount: '6572.81',
//       closedate: '2025-11-30T11:38:12.791Z',
//       createdate: '2025-09-01T11:41:53.093Z',
//       dealname: 'Intimus International ⭐ Renewal',
//       hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//       hs_object_id: '43230655641'
//     },
//     updatedAt: 2025-11-13T10:00:49.886Z
//   }
// ]

search2() //http search api no assoc

// [
//   {
//     id: '43230655641',
//     properties: {
//       amount: '6572.81',
//       closedate: '2025-11-30T11:38:12.791Z',
//       createdate: '2025-09-01T11:41:53.093Z',
//       dealname: 'Intimus International ⭐ Renewal',
//       hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//       hs_object_id: '43230655641'
//     },
//     createdAt: '2025-09-01T11:41:53.093Z',
//     updatedAt: '2025-11-13T10:00:49.886Z',
//     archived: false,
//     url: 'https://app.hubspot.com/contacts/9471187/record/0-3/43230655641'
//   }
// ]

works() // basci api get with assoc

// SimplePublicObjectWithAssociations {
//   associations: {
//     companies: CollectionResponseAssociatedId { results: [Array] },
//     'line items': CollectionResponseAssociatedId { results: [Array] },
//     contacts: CollectionResponseAssociatedId { results: [Array] }
//   },
//   createdAt: 2025-09-01T11:41:53.093Z,
//   archived: false,
//   id: '43230655641',
//   properties: {
//     amount: '6572.81',
//     closedate: '2025-11-30T11:38:12.791Z',
//     createdate: '2025-09-01T11:41:53.093Z',
//     dealname: 'Intimus International ⭐ Renewal',
//     dealstage: '44299820',
//     hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//     hs_object_id: '43230655641',
//     pipeline: '17469980'
//   },
//   updatedAt: 2025-11-13T10:00:49.886Z
// }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The are something wrong in te assoc param?&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;I’ve considered using &lt;STRONG&gt;webhooks&lt;/STRONG&gt;, but I can’t receive the full deal information when a property is modified — I have to select each property individually.&lt;BR /&gt;Also, it’s not possible to trigger a webhook when the &lt;STRONG&gt;last modified date&lt;/STRONG&gt; of a HubSpot deal is updated.&lt;/P&gt;&lt;P&gt;On the other hand, I tested the &lt;STRONG&gt;webhook&lt;/STRONG&gt; for deal deletion, and the &lt;STRONG&gt;body&lt;/STRONG&gt; we receive is empty.&lt;BR /&gt;When running the test webhook it works fine, but in the actual environment it fails.&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;thanx&lt;/P&gt;</description>
    <pubDate>Thu, 13 Nov 2025 11:40:37 GMT</pubDate>
    <dc:creator>JorgeTwenix</dc:creator>
    <dc:date>2025-11-13T11:40:37Z</dc:date>
    <item>
      <title>Best practices</title>
      <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223363#M85450</link>
      <description>&lt;P&gt;Good morning,&lt;/P&gt;&lt;P&gt;I have the following use case: we have around &lt;STRONG&gt;100,000 deals&lt;/STRONG&gt;, and we need to retrieve those that have been modified (along with their associations) in the &lt;STRONG&gt;last 15 minutes&lt;/STRONG&gt;.&lt;/P&gt;&lt;P&gt;From what I’ve seen, it seems that the only way to find the most recent ones is by using the &lt;STRONG&gt;Search API&lt;/STRONG&gt;, but that doesn’t return the associations.&lt;/P&gt;&lt;P&gt;So, the only alternatives I can think of are:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;&lt;P&gt;Using the &lt;STRONG&gt;list&lt;/STRONG&gt; method from the &lt;STRONG&gt;Basic API&lt;/STRONG&gt;, which would require around 960 calls, or&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;Using the IDs from the first call and making between 1 and 100,000 calls to the &lt;STRONG&gt;get&lt;/STRONG&gt; method from the &lt;STRONG&gt;Basic API&lt;/STRONG&gt;.&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Is there a more efficient way to do this?&lt;BR /&gt;Does the &lt;STRONG&gt;Search API&lt;/STRONG&gt; have any option to include associations?&lt;BR /&gt;Or does the &lt;STRONG&gt;List API&lt;/STRONG&gt; allow filtering by IDs, similar to the &lt;STRONG&gt;Batch API&lt;/STRONG&gt;?&lt;/P&gt;&lt;P&gt;Thank you very much for your help.&lt;/P&gt;</description>
      <pubDate>Thu, 13 Nov 2025 09:21:42 GMT</pubDate>
      <guid>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223363#M85450</guid>
      <dc:creator>JorgeTwenix</dc:creator>
      <dc:date>2025-11-13T09:21:42Z</dc:date>
    </item>
    <item>
      <title>Re: Best practices</title>
      <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223393#M85454</link>
      <description>&lt;P&gt;Great question! For retrieving 100,000 deals modified in the last 15 minutes WITH associations, here's the most efficient approach:&lt;/P&gt;&lt;P&gt;**Best Solution: Search API with filterGroups**&lt;/P&gt;&lt;P&gt;The Search API is actually the right choice, and YES - it CAN return associations! Here's how:&lt;/P&gt;&lt;P&gt;```&lt;BR /&gt;POST /crm/v3/objects/deals/search&lt;BR /&gt;{&lt;BR /&gt;"filterGroups": [{&lt;BR /&gt;"filters": [{&lt;BR /&gt;"propertyName": "hs_lastmodifieddate",&lt;BR /&gt;"operator": "GTE",&lt;BR /&gt;"value": "{{timestamp_15_min_ago}}"&lt;BR /&gt;}]&lt;BR /&gt;}],&lt;BR /&gt;"properties": ["dealname", "amount", "closedate"],&lt;BR /&gt;"associations": ["contacts", "companies"],&lt;BR /&gt;"limit": 100&lt;BR /&gt;}&lt;BR /&gt;```&lt;/P&gt;&lt;P&gt;**Key points:**&lt;BR /&gt;• Use the `associations` parameter in your Search API request&lt;BR /&gt;• Set `limit: 100` and paginate through results using `after` token&lt;BR /&gt;• Much more efficient than 960+ Basic API calls&lt;BR /&gt;• Returns deals AND their associations in one go&lt;/P&gt;&lt;P&gt;**Why this beats your alternatives:**&lt;BR /&gt;• **vs Basic API list method**: Search API filters server-side (way faster)&lt;BR /&gt;• **vs get + 100k calls**: You'd hit rate limits and waste time&lt;BR /&gt;• **vs Batch API**: Still requires you to know which IDs to fetch first&lt;/P&gt;&lt;P&gt;**Pro tip:** If you need this regularly, consider using webhooks to get notified when deals are modified instead of polling every 15 minutes!&lt;/P&gt;&lt;P&gt;Happy to help you implement this if you need code examples.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-unicode-emoji" title=":backhand_index_pointing_right:"&gt;👉&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://urlshortly.com/upwork" target="_blank"&gt;https://urlshortly.com/upwork&lt;/A&gt;&lt;/P&gt;&lt;P&gt;Certified in HubSpot Search API, Deals API &amp;amp; Integrations&lt;/P&gt;&lt;P&gt;#HubSpot #SearchAPI #DealsAPI #Associations #APIOptimization&lt;/P&gt;</description>
      <pubDate>Thu, 13 Nov 2025 10:20:20 GMT</pubDate>
      <guid>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223393#M85454</guid>
      <dc:creator>amjadkhatri</dc:creator>
      <dc:date>2025-11-13T10:20:20Z</dc:date>
    </item>
    <item>
      <title>Re: Best practices</title>
      <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223431#M85457</link>
      <description>&lt;P&gt;Hello I tried your solution but&amp;nbsp;&lt;/P&gt;&lt;P&gt;I’ve checked your suggested solution in the documentation, but I couldn’t find the &lt;STRONG&gt;associations&lt;/STRONG&gt; parameter in the &lt;STRONG&gt;Search API.&lt;/STRONG&gt;&lt;BR /&gt;I’ve also tested it both via an &lt;STRONG&gt;HTTP request&lt;/STRONG&gt; and using the &lt;STRONG&gt;JavaScript SDK.&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;Here’s the code:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;async function search1() {
    const client = new Client({ accessToken });
    const body = {
        "filterGroups": [{
            "filters": [{
                "propertyName": "hs_object_id",
                "operator": "EQ",
                "value": "43230655641"
            }]
        }],
        "properties": ["dealname", "amount", "closedate"],
        "associations": ["contacts", "companies"],
        "limit": 100
    }
    const resp = await client.crm.deals.searchApi.doSearch(body);
    const { results, paging, ...rest } = resp
    console.log(results)
}


async function search2() {
    const url = 'https://api.hubapi.com/crm/v3/objects/0-3/search';
    const options = {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            "filterGroups": [{
                "filters": [{
                    "propertyName": "hs_object_id",
                    "operator": "EQ",
                    "value": "43230655641"
                }]
            }],
            "properties": ["dealname", "amount", "closedate"],
            "associations": ["contacts", "companies", "line_items"],
            "limit": 200
        })
    };

    const response = await fetch(url, options);
    const { results, paging, ...rest } = await response.json();
    console.log(results)
}

async function works() {
    const client = new Client({ accessToken});
    const resp = await client.crm.deals.basicApi.getById(43230655641, [],[], ["contacts", "companies", "line_items"]);
    console.log(resp)
}


search1() //sdk search api no assoc

// [
//   SimplePublicObject {
//     createdAt: 2025-09-01T11:41:53.093Z,
//     archived: false,
//     id: '43230655641',
//     properties: {
//       amount: '6572.81',
//       closedate: '2025-11-30T11:38:12.791Z',
//       createdate: '2025-09-01T11:41:53.093Z',
//       dealname: 'Intimus International ⭐ Renewal',
//       hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//       hs_object_id: '43230655641'
//     },
//     updatedAt: 2025-11-13T10:00:49.886Z
//   }
// ]

search2() //http search api no assoc

// [
//   {
//     id: '43230655641',
//     properties: {
//       amount: '6572.81',
//       closedate: '2025-11-30T11:38:12.791Z',
//       createdate: '2025-09-01T11:41:53.093Z',
//       dealname: 'Intimus International ⭐ Renewal',
//       hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//       hs_object_id: '43230655641'
//     },
//     createdAt: '2025-09-01T11:41:53.093Z',
//     updatedAt: '2025-11-13T10:00:49.886Z',
//     archived: false,
//     url: 'https://app.hubspot.com/contacts/9471187/record/0-3/43230655641'
//   }
// ]

works() // basci api get with assoc

// SimplePublicObjectWithAssociations {
//   associations: {
//     companies: CollectionResponseAssociatedId { results: [Array] },
//     'line items': CollectionResponseAssociatedId { results: [Array] },
//     contacts: CollectionResponseAssociatedId { results: [Array] }
//   },
//   createdAt: 2025-09-01T11:41:53.093Z,
//   archived: false,
//   id: '43230655641',
//   properties: {
//     amount: '6572.81',
//     closedate: '2025-11-30T11:38:12.791Z',
//     createdate: '2025-09-01T11:41:53.093Z',
//     dealname: 'Intimus International ⭐ Renewal',
//     dealstage: '44299820',
//     hs_lastmodifieddate: '2025-11-13T10:00:49.886Z',
//     hs_object_id: '43230655641',
//     pipeline: '17469980'
//   },
//   updatedAt: 2025-11-13T10:00:49.886Z
// }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The are something wrong in te assoc param?&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;I’ve considered using &lt;STRONG&gt;webhooks&lt;/STRONG&gt;, but I can’t receive the full deal information when a property is modified — I have to select each property individually.&lt;BR /&gt;Also, it’s not possible to trigger a webhook when the &lt;STRONG&gt;last modified date&lt;/STRONG&gt; of a HubSpot deal is updated.&lt;/P&gt;&lt;P&gt;On the other hand, I tested the &lt;STRONG&gt;webhook&lt;/STRONG&gt; for deal deletion, and the &lt;STRONG&gt;body&lt;/STRONG&gt; we receive is empty.&lt;BR /&gt;When running the test webhook it works fine, but in the actual environment it fails.&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;thanx&lt;/P&gt;</description>
      <pubDate>Thu, 13 Nov 2025 11:40:37 GMT</pubDate>
      <guid>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223431#M85457</guid>
      <dc:creator>JorgeTwenix</dc:creator>
      <dc:date>2025-11-13T11:40:37Z</dc:date>
    </item>
    <item>
      <title>Re: Best practices</title>
      <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223552#M85477</link>
      <description>&lt;P&gt;Hey &lt;SPAN style="background: var(--ck-color-mention-background); color: var(--ck-color-mention-text);"&gt;&lt;a href="https://community.hubspot.com/t5/user/viewprofilepage/user-id/1012629"&gt;@JorgeTwenix&lt;/a&gt;&lt;/SPAN&gt; &lt;span class="lia-unicode-emoji" title=":waving_hand:"&gt;👋&lt;/span&gt; Thank you for the great post. I don't think you are doing anything wrong. Your analysis is correct about the limitations with the Search API and it &lt;STRONG&gt;not&lt;/STRONG&gt; returning associations the way you want. The documentation offers `&lt;A href="https://developers.hubspot.com/docs/api-reference/search/guide#search-through-associations" target="_blank"&gt;&lt;STRONG&gt;pseudo-associations&lt;/STRONG&gt;&lt;/A&gt;" as an option but not &lt;STRONG&gt;associations&lt;/STRONG&gt; the way you need it to be returned.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The current approach to solve your problem is a two-step process that uses the &lt;STRONG&gt;Search API&lt;/STRONG&gt; and the &lt;STRONG&gt;v4 Associations API&lt;/STRONG&gt; together. I've also seen folks leverage GraphQL to make unified requests when their portal has access — &lt;A href="https://developers.hubspot.com/docs/cms/start-building/features/data-driven-content/graphql/query-hubspot-data-using-graphql" target="_blank"&gt;&lt;STRONG&gt;Query HubSpot data using GraphQL&lt;/STRONG&gt;&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Best,&lt;/P&gt;
&lt;P&gt;Jaycee&lt;/P&gt;</description>
      <pubDate>Thu, 13 Nov 2025 15:43:34 GMT</pubDate>
      <guid>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1223552#M85477</guid>
      <dc:creator>Jaycee_Lewis</dc:creator>
      <dc:date>2025-11-13T15:43:34Z</dc:date>
    </item>
    <item>
      <title>Re: Best practices</title>
      <link>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1226700#M85637</link>
      <description>&lt;P data-start="0" data-end="17"&gt;Hi&amp;nbsp;&lt;a href="https://community.hubspot.com/t5/user/viewprofilepage/user-id/1012629"&gt;@JorgeTwenix&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-start="19" data-end="481"&gt;You’re not missing anything. The associations parameter is only supported on GET by ID and Batch Read, not on the Search API.&lt;/P&gt;
&lt;P data-start="19" data-end="481"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-start="19" data-end="481"&gt;The Search endpoint will silently ignore that field, which is exactly what you’re seeing in both your SDK test and the raw HTTP call. HubSpot calls these “pseudo associations,” and they only apply to native joins like owner or pipeline, not object to object associations (&lt;A href="https://developers.hubspot.com/docs/api-reference/search/guide" target="_blank"&gt;https://developers.hubspot.com/docs/api-reference/search/guide&lt;/A&gt; )&lt;/P&gt;
&lt;P data-start="19" data-end="481"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-start="483" data-end="961"&gt;That leaves you with the only scalable pattern for high volume incremental fetches: search for the modified IDs, then pull associations in a second step using the v4 Associations API. Jaycee’s reply is right on that point. For deletion events and incremental updates, HubSpot’s docs explain why the object must be rehydrated manually after the webhook fires because the webhook payload is intentionally minimal (&lt;A href="https://knowledge.hubspot.com/workflows/how-do-i-use-webhooks-with-hubspot-workflows" target="_blank"&gt;https://knowledge.hubspot.com/workflows/how-do-i-use-webhooks-with-hubspot-workflows&lt;/A&gt; )&lt;/P&gt;
&lt;P data-start="483" data-end="961"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-start="963" data-end="1204" data-is-last-node="" data-is-only-node=""&gt;A quick question. Do you need this fifteen minute delta because another platform is also writing to deals? If so, Stacksync keeps those bidirectional updates aligned in real time and removes the need for heavy polling cycles. Hope this helps&lt;/P&gt;</description>
      <pubDate>Thu, 20 Nov 2025 23:29:51 GMT</pubDate>
      <guid>https://community.hubspot.com/t5/APIs-Integrations/Best-practices/m-p/1226700#M85637</guid>
      <dc:creator>RubenBurdin</dc:creator>
      <dc:date>2025-11-20T23:29:51Z</dc:date>
    </item>
  </channel>
</rss>

