> ## Documentation Index
> Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---
id: 414b9653-72fe-4f3e-847f-4fc0c3b5eff7
---

# Site search API

> Use the site search API to search for content across your HubSpot-hosted sites and retrieve indexed data for specific assets.

export const Tag = ({children, type = 'default', className = ''}) => {
  return <span className={`tag tag-${type} ${className}`.trim()}>
      {children}
    </span>;
};

export const SupportedProducts = ({marketing, sales, service, cms, data, commerce, marketingLevel, salesLevel, serviceLevel, cmsLevel, dataLevel, commerceLevel}) => {
  const translations = {
    description: "Requires one of the following products or higher.",
    productNames: {
      marketing: "Marketing Hub",
      sales: "Sales Hub",
      service: "Service Hub",
      cms: "Content Hub",
      data: "Data Hub",
      commerce: "Revenue Hub"
    },
    tiers: {
      free: "Free",
      starter: "Starter",
      professional: "Professional",
      enterprise: "Enterprise"
    }
  };
  const translateTier = tier => {
    if (!tier) return '';
    const lowerTier = tier.toLowerCase();
    return translations.tiers[lowerTier] || tier;
  };
  const products = [{
    name: marketing ? translations.productNames.marketing : '',
    level: translateTier(marketingLevel),
    icon: "https://mintlify-assets.b-cdn.net/Icons/marketing-bolt.svg",
    alt: "Marketing Hub"
  }, {
    name: sales ? translations.productNames.sales : '',
    level: translateTier(salesLevel),
    icon: "https://mintlify-assets.b-cdn.net/Icons/sales-star.svg",
    alt: "Sales Hub"
  }, {
    name: service ? translations.productNames.service : '',
    level: translateTier(serviceLevel),
    icon: "https://mintlify-assets.b-cdn.net/Icons/service-heart.svg",
    alt: "Service Hub"
  }, {
    name: cms ? translations.productNames.cms : '',
    level: translateTier(cmsLevel),
    icon: "https://mintlify-assets.b-cdn.net/Icons/content-play.svg",
    alt: "Content Hub"
  }, {
    name: data ? translations.productNames.data : '',
    level: translateTier(dataLevel),
    icon: "https://developers.hubspot.com/hubfs/Knowledge_Base_2023-24-25/subscription_key_icons/operations_icon.svg",
    alt: "Data Hub"
  }, {
    name: commerce ? translations.productNames.commerce : '',
    level: translateTier(commerceLevel),
    icon: "https://developers.hubspot.com/hubfs/Knowledge_Base/subscription_key_icons/commerce_icon.svg",
    alt: "Revenue Hub"
  }].filter(product => product.name && product.level);
  if (products.length === 0) return null;
  return <div>
      <div className="text-sm mb-2">{translations.description}</div>
      <div className={`grid ${products.length === 1 ? 'grid-cols-1' : 'grid-cols-2'} gap-1.5`}>
        {products.map((product, index) => <div key={index} style={{
    display: 'flex',
    alignItems: 'center'
  }}>
            <img src={product.icon} alt={product.alt} className="w-3.5 h-3.5 mr-1.5 mt-2.5 mb-2.5 flex-shrink-0 align-middle" />
            <span className="font-medium mr-1 text-sm">{product.name} -</span>
            <span className="text-sm">{product.level}</span>
          </div>)}
      </div>
    </div>;
};

export const ScopesList = ({scopes = [], description = "This API requires one of the following scopes:"}) => {
  if (!scopes || scopes.length === 0) {
    return null;
  }
  const sortedScopes = scopes.sort((a, b) => a.localeCompare(b));
  return <div>
      <div className="text-sm mb-2">{description}</div>
      <div>
        {sortedScopes.map((scope, index) => <div key={index}>
            <code>
              <span className="text-xs">{scope}</span>
            </code>
          </div>)}
      </div>
    </div>;
};

<AccordionGroup>
  <Accordion title="Supported products" defaultOpen="true" icon="cubes">
    <SupportedProducts marketing={true} marketingLevel="professional" cms={true} cmsLevel="professional" />
  </Accordion>

  <Accordion title="Required Scopes" icon="key">
    <ScopesList
      scopes={[
  'content'
]}
    />
  </Accordion>
</AccordionGroup>

The site search API allows you to search for content across HubSpot-hosted sites and retrieve indexed data for specific pages. Use this API to build custom search experiences for your website.

## Search your site

To search for content across your HubSpot-hosted sites, make a `GET` request to `/cms/site-search/2026-03/search`.

For example, the following request searches for blog posts containing "marketing" on the `blog.hubspot.com` domain:

```shell wrap theme={null}
curl 'https://api.hubapi.com/cms/site-search/2026-03/search?q=marketing&type=BLOG_POST&domain=blog.hubspot.com&limit=10' \
  --request GET \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

The following query parameters are available:

| Parameter     | Type    | Description                                                                                                                                                                                                           |
| ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `q`           | String  | The term to search for.                                                                                                                                                                                               |
| `type`        | String  | Specifies the type of content to search. Options include: `SITE_PAGE`, `LANDING_PAGE`, `BLOG_POST`, `LISTING_PAGE`, `KNOWLEDGE_ARTICLE`. Defaults to all content types except `LANDING_PAGE` and `KNOWLEDGE_ARTICLE`. |
| `domain`      | String  | A domain to match search results for. Multiple domains can be provided  using `&` as a separator (e.g., `domain=blog.hubspot.com&domain=marketing.hubspot.com`).                                                      |
| `pathPrefix`  | String  | Specifies a path prefix to filter search results. Only returns results with URL paths that start with the specified value.                                                                                            |
| `matchPrefix` | Boolean | Inverts the behavior of the `pathPrefix` filter when set to `false`. Defaults to `true`.                                                                                                                              |
| `language`    | String  | Specifies the language of content to be searched. Must be a valid [ISO 639-1 language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) (e.g., `es` for Spanish).                                          |
| `groupId`     | String  | Specifies which blog(s) to search by blog ID. Can be used multiple times to search more than one blog.                                                                                                                |
| `tableId`     | Integer | Specifies a specific HubDB table to search. Only returns results from the specified table.                                                                                                                            |
| `hubdbQuery`  | String  | Specify a HubDB query to further filter the search results.                                                                                                                                                           |
| `property`    | String  | Specifies which properties to search. Options include `title`, `description`, and `html`. All properties are searched by default.                                                                                     |
| `length`      | String  | Specifies the length of the search results description. `SHORT` returns the first 128 characters of the meta description. `LONG` builds a more detailed snippet based on the page content.                            |
| `limit`       | Integer | The number of results to return per page. Defaults to `10`, maximum is `100`.                                                                                                                                         |
| `offset`      | Integer | Used to page through results. Use the `offset` value from the previous response to get the next set of results.                                                                                                       |

### Boosting parameters

The following parameters control how results are ranked:

| Parameter         | Type    | Description                                                                                                                                                                                                                        |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autocomplete`    | Boolean | Specifies whether you are showing autocomplete results. Defaults to `false`.                                                                                                                                                       |
| `boostLimit`      | Number  | The maximum amount a result will be boosted based on its view count. Defaults to `5.0`.                                                                                                                                            |
| `boostRecent`     | String  | A relative time window where scores of content published outside this window decay. Only applies to blog posts. For example, `10d` boosts posts published within the last 10 days. Supported time units: `ms`, `s`, `m`, `h`, `d`. |
| `popularityBoost` | Number  | How strongly a result is boosted based on its view count. Defaults to `1.0`.                                                                                                                                                       |

The response includes a `total` count and an array of search results:

```json theme={null}
{
  "total": 12,
  "offset": 0,
  "limit": 10,
  "results": [
    {
      "id": 24314356,
      "score": 2.536124,
      "type": "BLOG_POST",
      "domain": "blog.hubspot.com",
      "url": "https://blog.hubspot.com/blog/tabid/6307/bid/11692/Inbound-Marketing-Vs-Outbound-Marketing.aspx",
      "featuredImageUrl": "https://cdn2.hubspot.net/hubfs/53/assets/hubspot.com/buzz/HubSpotOpenGraph.png",
      "language": "en-us",
      "title": "Inbound <span class=\"hs-search-highlight hs-highlight-title\">Marketing</span> Vs. Outbound <span class=\"hs-search-highlight hs-highlight-title\">Marketing</span>",
      "description": "This blog post is one of several <span class=\"hs-search-highlight hs-highlight-html\">Marketing</span> Transformation Success Stories...",
      "authorFullName": "Hobbes Baron",
      "tags": ["Inbound Marketing"],
      "publishedDate": 1302130260000
    }
  ],
  "searchTerm": "marketing",
  "page": 0
}
```

| Field              | Type    | Description                                                                                          |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------- |
| `id`               | Integer | The ID of the content.                                                                               |
| `score`            | Number  | The matching score of the content.                                                                   |
| `type`             | String  | The type of content (`SITE_PAGE`, `LANDING_PAGE`, `BLOG_POST`, `LISTING_PAGE`, `KNOWLEDGE_ARTICLE`). |
| `domain`           | String  | The domain the content is hosted on.                                                                 |
| `url`              | String  | The URL of the content.                                                                              |
| `title`            | String  | The title of the content. Matching terms are wrapped in `<span>` tags for highlighting.              |
| `description`      | String  | The description of the content. Matching terms are wrapped in `<span>` tags for highlighting.        |
| `featuredImageUrl` | String  | The URL of the featured image (if applicable).                                                       |
| `language`         | String  | The content's language.                                                                              |
| `authorFullName`   | String  | The name of the author (for blog posts).                                                             |
| `tags`             | Array   | Tags associated with the content (for blog posts).                                                   |
| `publishedDate`    | Integer | The publish date as a Unix timestamp in milliseconds.                                                |
| `category`         | String  | The category of the article (for knowledge articles).                                                |
| `subcategory`      | String  | The subcategory of the article (for knowledge articles).                                             |
| `tableId`          | Integer | The HubDB table ID (for dynamic pages).                                                              |
| `rowId`            | Integer | The row ID in the HubDB table (for dynamic pages).                                                   |

### Pagination

Results are paginated using offset-based pagination. To retrieve the next page of results, include an `offset` query parameter with the value from the previous response.

For example, if the first request returned `offset: 0` and `limit: 10`, retrieve the next page with `offset=10`:

```shell wrap theme={null}
curl 'https://api.hubapi.com/cms/site-search/2026-03/search?q=marketing&limit=10&offset=10' \
  --request GET \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Get indexed data for an asset

To retrieve all indexed data for a specific asset, make a `GET` request to `/cms/site-search/2026-03/indexed-data/{contentId}`. This is useful for debugging why a particular asset is not appearing in search results.

For example, the following request retrieves indexed data for a blog post with ID `24314356`:

```shell wrap theme={null}
curl 'https://api.hubapi.com/cms/site-search/2026-03/indexed-data/24314356?type=BLOG_POST' \
  --request GET \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

The following parameters are available:

| Parameter                                    | Type    | Description                                                                                                        |
| -------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| `contentId` <Tag type="error">Required</Tag> | Integer | The ID of the asset (page ID, blog post ID, HubDB row ID, etc.). Specified in the URL path.                        |
| `type` <Tag type="error">Required</Tag>      | String  | The type of asset. Options include: `SITE_PAGE`, `BLOG_POST`, `KNOWLEDGE_ARTICLE`, `LANDING_PAGE`, `LISTING_PAGE`. |

The response includes all indexed fields for the asset:

```json theme={null}
{
  "id": "24314356",
  "type": "BLOG_POST",
  "fields": {
    "title_nested.en": {
      "name": "title_nested.en",
      "values": ["Inbound Marketing Vs. Outbound Marketing"],
      "value": "Inbound Marketing Vs. Outbound Marketing",
      "metadataField": false
    },
    "domain": {
      "name": "domain",
      "values": ["blog.hubspot.com"],
      "value": "blog.hubspot.com",
      "metadataField": false
    },
    "url": {
      "name": "url",
      "values": ["https://blog.hubspot.com/blog/tabid/6307/bid/11692/Inbound-Marketing-Vs-Outbound-Marketing.aspx"],
      "value": "https://blog.hubspot.com/blog/tabid/6307/bid/11692/Inbound-Marketing-Vs-Outbound-Marketing.aspx",
      "metadataField": false
    },
    "language": {
      "name": "language",
      "values": ["en-us"],
      "value": "en-us",
      "metadataField": false
    },
    "author_full_name": {
      "name": "author_full_name",
      "values": ["Hobbes Baron"],
      "value": "Hobbes Baron",
      "metadataField": false
    },
    "tag": {
      "name": "tag",
      "values": ["Inbound Marketing"],
      "value": "Inbound Marketing",
      "metadataField": false
    },
    "publishedDate": {
      "name": "publishedDate",
      "values": [1302130260000],
      "value": 1302130260000,
      "metadataField": false
    }
  }
}
```

Each field in the `fields` object contains:

| Field           | Type    | Description                                                      |
| --------------- | ------- | ---------------------------------------------------------------- |
| `name`          | String  | The name of the indexed field.                                   |
| `value`         | Any     | The primary value of the field.                                  |
| `values`        | Array   | All values for the field (some fields may have multiple values). |
| `metadataField` | Boolean | Whether the field is a metadata field used for internal routing. |

## Content types

The `type` parameter accepts the following values:

| Type                | Description                              |
| ------------------- | ---------------------------------------- |
| `SITE_PAGE`         | Website pages created in HubSpot.        |
| `LANDING_PAGE`      | Landing pages created in HubSpot.        |
| `BLOG_POST`         | Blog posts associated with your blog(s). |
| `LISTING_PAGE`      | Blog listing pages.                      |
| `KNOWLEDGE_ARTICLE` | Knowledge base articles.                 |
