> ## 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: 35294e0e-3970-4231-b7c3-a62b9d6c7851
---

# Lead Scoring API (BETA)

> Create, manage, and retrieve score configurations and score values for CRM objects.

export const SupportedProducts = ({marketing, sales, service, cms, data, commerce, crm, marketingLevel, salesLevel, serviceLevel, cmsLevel, dataLevel, commerceLevel, crmLevel}) => {
  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",
      crm: "Smart CRM"
    },
    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"
  }, {
    name: crm ? translations.productNames.crm : '',
    level: translateTier(crmLevel),
    icon: "https://developer.hubspot.com/hubfs/Knowledge_Base_2023-24-25/developer/icons/SmartCRM.svg",
    alt: "Smart CRM"
  }].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 BetaDisclaimerBanner = () => <Warning>
        This functionality is currently in beta. By participating in this beta, you agree to HubSpot's <a href="https://legal.hubspot.com/developer-terms">Developer Terms</a> and <a href="https://legal.hubspot.com/developerbetaterms">Developer Beta Terms</a>. Note that the functionality is still under active development and is subject to change based on testing and feedback.
    </Warning>;

export const RequiredIndicator = () => {
  return <span className="required-indicator">
      required
    </span>;
};

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 sales={true} salesLevel="professional" marketing={true} marketingLevel="professional" />
  </Accordion>

  <Accordion title="Scope requirements">
    <ScopesList
      scopes={[
  'marketing.lead_scoring.read',
  'marketing.lead_scoring.write'
]}
    />
  </Accordion>
</AccordionGroup>

Use the Lead Scoring API to draft, publish, and manage lead score configurations (i.e. rules, criteria). Once a score is published, you can retrieve records' current scores or view score history over time.

Learn more about [lead scores](https://knowledge.hubspot.com/scoring/understand-the-lead-scoring-tool) in HubSpot.

<BetaDisclaimerBanner />

## Create a lead score

To create a new score configuration, make a `POST` request to `/marketing/lead-scoring/2026-09-beta/scores`.

Include the following in the request body:

| Parameter                                 | Type   | Description                                                                                                                                                                                                                                                                             |
| ----------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objectTypeId` <RequiredIndicator />      | String | The ID of the CRM object to score: `0-1` for contacts or `0-2` for companies.                                                                                                                                                                                                           |
| `name` <RequiredIndicator />              | String | The score's name.                                                                                                                                                                                                                                                                       |
| `allowedGroupTypes` <RequiredIndicator /> | Array  | The [scoring types](https://knowledge.hubspot.com/scoring/understand-the-lead-scoring-tool#types-of-scores) permitted in this score's logic. Accepted values: `fit`, `intent`. Include both values to allow groups with both scoring types (i.e. a combined score).                     |
| `groupConfigs` <RequiredIndicator />      | Array  | The [rule groups](https://knowledge.hubspot.com/scoring/build-lead-scores#set-up-score-criteria-and-points) that make up the score's criteria. Each group contains a `groupCategory` (`fit` or `intent`), a `groupName`, and a `ruleConfigurations` array that sets a group's rules.    |
| `maxScore`                                | Number | The maximum total score value. Default value is `100` for each scoring type.                                                                                                                                                                                                            |
| `outputConfiguration`                     | Object | Information about how record score values are stored and synced. Include the following fields: `outputProperty` (the name of the property where the score values are stored on records) and `syncEnabled` (whether to sync the output property value after scoring: `true` or `false`). |

The request creates a new score with an initial draft configuration. Drafts must be [published](#publish-a-draft) to become active scores that evaluate records.

```json theme={null}
{
  "objectTypeId": "0-1",
  "name": "New Lead Score",
  "allowedGroupTypes": [
    "fit",
    "intent"
  ],
  "groupConfigs": [
    {
      "groupId": 0,
      "groupName": "Engagement",
      "groupCategory": "intent",
      "ruleConfigurations": []
    }
  ],
  "maxScore": 100,
  "outputConfiguration": {
    "outputProperty": "hubspot_lead_score",
    "syncEnabled": true
  }
}
```

A successful response returns `201` with a `Location` header pointing to the new score resource, with a `scoreStatus` of `"draft"`.

## Publish a draft

To publish a draft, make a `POST` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/draft/publish`.

For new scores, this turns on the score and triggers an evaluation of records. For existing scores, the score is updated and the request triggers a re-evaluation of records based on the updated criteria.

A successful response returns the score with a `scoreStatus` of `"published"`.

## Retrieve scores

To retrieve a paginated list of lead scores, make a `GET` request to `/marketing/lead-scoring/2026-09-beta/scores`. Include the `limit` and `after` query parameters to specify the number of scores returned and to paginate results.

The response will look similar to the following, with a `results` array of score summaries and a `paging` object for pagination.

```json theme={null}
{
  "results": [
    {
      "id": "12345",
      "name": "Lead Score",
      "scoreType": "MH",
      "scoredObjectTypeId": "0-2",
      "lastConfigurationChangeTimestamp": "2026-07-20T08:00:00.000Z"
    },
    {
      "id": "56789",
      "name": "Marketing Score",
      "scoreType": "MH",
      "scoredObjectTypeId": "0-1",
      "lastConfigurationChangeTimestamp": "2026-07-25T07:00:00.000Z"
    }
  ],
  "paging": {
    "next": {
      "after": "1011112",
      "link": "https://api.hubapi.com/marketing/lead-scoring/2026-09-beta/scores?limit=2&after=1011112"
    }
  }
}
```

## Retrieve score configurations

* To retrieve the published configuration for a score, make a `GET` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}`.
* To retrieve the current draft configuration for a score, make a `GET` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/draft`.

The response includes all scoring criteria, rules, filters, and timestamps. The `scoreStatus` field indicates whether the score is `published` or `published_with_draft`.

```json theme={null}
{
  "id": "12345",
  "objectTypeId": "0-1",
  "name": "Lead Score",
  "scoreStatus": "published",
  "scoreType": "MH",
  "groupConfigs": [
    {
      "groupId": 1,
      "groupName": "Engagement Signals",
      "groupCategory": "fit",
      "maxValue": 50.0,
      "ruleConfigurations": [
        {
          "scalingFactor": 1.0,
          "enabled": true,
          "maximumValue": 10.0,
          "configuration": {
            "type": "PROPERTY_RULE",
            "propertyName": "num_unique_forms_submitted",
            "operator": "GT",
            "value": "0"
          }
        }
      ]
    }
  ],
  "outputConfiguration": {
    "outputProperty": "hubspot_lead_score",
    "syncEnabled": true
  },
  "allowedGroupTypes": ["fit", "intent"],
  "maxScore": 100,
  "createdAt": "2026-06-01T12:00:00.000Z",
  "updatedAt": "2026-07-20T08:00:00.000Z",
  "publishedAt": "2026-07-15T16:30:00.000Z"
}
```

## Upsert a draft

To update the active draft for a score, make a `PUT` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/draft`.

This request fully updates the configuration, meaning the entire draft is overwritten with the updated request body. If no draft exists, a new one is created.

```json theme={null}
{
  "scoreId": 12345,
  "objectTypeId": "0-1",
  "name": "Updated Lead Score",
  "groupConfigs": [
    {
      "groupId": 1,
      "groupName": "Engagement Signals",
      "groupCategory": "intent",
      "maxValue": 60.0,
      "ruleConfigurations": [
        {
          "scalingFactor": 1.0,
          "enabled": true,
          "maximumValue": 15.0,
          "configuration": {
            "type": "PROPERTY_RULE",
            "propertyName": "num_unique_forms_submitted",
            "operator": "GT",
            "value": "0"
          }
        }
      ]
    }
  ],
  "allowedGroupTypes": [
    "fit",
    "intent"
  ],
  "maxScore": 100
}
```

A successful response returns `200` with the updated draft. Validation failures return a `VALIDATION_ERROR` response.

## Revert a draft to the published configuration

To discard all unpublished changes and revert the draft to the live configuration, make a `POST` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/draft/reset`.

No request body is required. A successful response returns `204 No Content`.

## Deactivate a score

To turn a score off, while preserving the score configuration, make a `POST` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/deactivate`.

No request body is required. The response returns the score metadata reflecting its new inactive state.

```json theme={null}
{
  "scoreId": "12345",
  "objectTypeId": "0-1",
  "name": "Lead Score",
  "scoreStatus": "draft",
  "scoreType": "MH",
  "groupConfigs": [],
  "allowedGroupTypes": [],
  "createdAt": "2026-06-01T12:00:00.000Z",
  "updatedAt": "2026-07-28T10:00:00.000Z"
}
```

The deactivated score returns to a draft which you can [update](#upsert-a-draft) or [publish](#publish-a-draft). The score's `groupConfigs` are retained.

## Clone a score

To duplicate an existing score configuration into a new score, make a `POST` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}/clone`. In the request body, include the `scoreName`. This is the name for the new cloned score.

If the source score has an active draft, the clone is created from the draft configuration. If no draft exists, the published configuration is cloned.

```json theme={null}
{
  "scoreName": "Lead Score (Copy)"
}
```

A successful response returns `201` with the `scoreStatus` as `"draft"`.

## Delete a score

To delete a score, make a `DELETE` request to `/marketing/lead-scoring/2026-09-beta/scores/{scoreId}`.

No request body is required. A successful response returns `204 No Content`.

## Read record score values

You can retrieve record score values via the [objects API](/docs/api-reference/latest/crm/using-object-apis). In your request, retrieve each score's `outputProperty`.

For example, to retrieve contacts' value for the *New Lead Score*, with the output property `hubspot_lead_score`:

* To retrieve an individual contact with their score value, make a `GET` request to `/crm/objects/2026-03/contacts/{recordId}?properties=hubspot_lead_score`.
* To retrieve all contacts with their score values, make a `GET` request to `/crm/objects/2026-03/contacts?properties=hubspot_lead_score`.
* To retrieve multiple specific contacts with their score values, make a `POST` request to `/crm/objects/2026-03/contacts/batch/read`. In your request body, include the score property in the `properties` array, and the `id` values of records to retrieve as `inputs`. For example:

```json theme={null}
{
  "properties": ["hubspot_lead_score"],
  "inputs": [
    {
      "id": "1234567"
    },
    {
      "id": "987456"
    }
  ]
}
```

To search for records with specific score values, use the [search API](/docs/api-reference/latest/crm/search-the-crm) and filter by specific values for the `outputProperty`. For example, to search for contacts with a *New Lead Score* (`outputProperty`:`hubspot_lead_score`) value over 50, make a `POST` request to `/crm/objects/2026-03/contacts/search` and use the following request body:

```json theme={null}
{
  "filterGroups": [
    {
      "filters": [
        {
          "propertyName": "hubspot_lead_score",
          "operator": "GT",
          "value": 50
        }
      ]
    }
  ]
}
```
