> For the complete documentation index, see [llms.txt](https://docs.stacksync.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stacksync.com/two-way-sync/api-proxy/hubspot.md).

# HubSpot

The simplest HubSpot API you have ever seen!

## TL;DR

This API proxy lets you do any operation on your HubSpot data but removes from you all the complexity of setting up and using the classic HubSpot API 🤩

**No need to worry** about ~~setting up a connected app~~, ~~rotating the security token~~, ~~using bulk API or not~~, ~~record formatting~~ and more! Everything is managed for you 💆‍♀️

Operations:

* [Get Records](#get)
* [Create a custom field into a HubSpot object](#add-a-custom-field-to-a-hubspot-object)
* [Pass Through](#pass-through)

### Regions 🌍

Depending on your region, you can use

🇪🇺 `https://eu.api-proxy.stacksync.com/`

🇺🇸 `https://us.api-proxy.stacksync.com/`

## Get

Get the content of up to 100 records. The number of records returned matches the number of `Id`s passed in the request.

You can pass the optional `fields` parameter (list of field names that you want to be returned for each record). If the list of `fields` is not passed or is empty `"fields":[]`, all fields are returned.

{% hint style="info" %}
Currently the following HubSpot objects are supported:<br>

* Companies
* Contacts
* Deals
* Feedback submissions
* Line items
* Products
* Quotes
* Discounts
* Fees
* Taxes
* Tickets
* Goals
* Custom objects

The following objects will be added in the future:

* Owners
* Associations
* Audit Logs
* Pipelines
* Stages
  {% endhint %}

{% tabs %}
{% tab title="cURL" %}

```url
curl -X POST https://eu.api-proxy.stacksync.com/v1/object/get/Contact \
        -H "Authorization: Bearer your_api_proxy_service_token" \
        -H "Content-Type: application/json" \
        -d '{"data": {"ids": ["227400", "264150"], "fields": ["firstname"]}}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

object_name = 'Contact'

url = f"https://eu.api-proxy.stacksync.cloud/v1/object/get/{object_name}"

data ={
"data":
      {
         "ids" : ["227400", "227386"],
         "fields" : ["firstname"]
      }
}

api_proxy_service_token = "your_api_proxy_service_token"

headers = {
    'Authorization': f'Bearer {api_proxy_service_token}',
    'Content-Type': 'application/json'
}

response = requests.post(url, json=data, headers=headers)

```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const object_name = 'Contact';
const url = `https://eu.api-proxy.stacksync.cloud/v1/object/get/${object_name}`;

const data ={
data:
    {
      ids: ["227386", "227400"],
      fields: ["firstname"]
    }
};

const api_proxy_service_token = 'your_api_proxy_service_token';

const headers = {
  'Authorization': `Bearer ${apiProxyServiceToken}`,
  'Content-Type': 'application/json'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

```

{% endtab %}
{% endtabs %}

Example response body:

```json
{
	"data": [
		{
			"archived": false,
			"createdAt": "2024-01-31T13:17:43.128Z",
			"id": "227400",
			"properties": {
				"createdate": "2024-01-31T13:17:43.128Z",
				"firstname": null,
				"hs_object_id": "227400",
				"lastmodifieddate": "2024-02-02T15:05:54.183Z"
			},
			"updatedAt": "2024-02-02T15:05:54.183Z"
		},
		{
			"archived": false,
			"createdAt": "2024-01-31T13:17:43.128Z",
			"id": "227386",
			"properties": {
				"createdate": "2024-01-31T13:17:43.128Z",
				"firstname": null,
				"hs_object_id": "227386",
				"lastmodifieddate": "2024-01-31T13:28:37.746Z"
			},
			"updatedAt": "2024-01-31T13:28:37.746Z"
		}
	]
}
```

## Add a custom field to a HubSpot object

Add a custom field to a HubSpot object. Standard and custom objects are supported.

The required request body parameters are:

* `name` The internal property name, which must be used when referencing the property via the API.
* `label` A human-readable property label that will be shown in HubSpot.
* `type` The data type of the property.
* `fieldType` Controls how the property appears in HubSpot.
* `groupName` The name of the property group the property belongs to.

Each `type` has one or more valid `fieldTypes`, using incompatible `type` and `fieldType` will not work. The full list of `types` and `fieldTypes` and valid combinations can be found [here](https://developers.hubspot.com/docs/api/crm/properties#property-type-and-fieldtype-values).

{% tabs %}
{% tab title="cURL" %}

```url
curl -X POST https://eu.api-proxy.stacksync.com/v1/object/add_custom_field/{object_name} \
        -H "Authorization: Bearer your_api_proxy_service_token" \
        -H "Content-Type: application/json" \
        -d '{"data": {"name": "field_name", "type": "field_type", "label": "field_label", "fieldType": "field_type", "groupName": "group_name"}}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

headers = {
    'Authorization': 'Bearer your_api_proxy_service_token',
    # Already added when you pass json=
    # 'Content-Type': 'application/json',
}

json_data = {
    'data': {
        'name': 'field_name',
        'type': 'field_type',
        'label': 'field_label'
    },
}

response = requests.post(
    'https://eu.api-proxy.stacksync.cloud/v1/object/add_custom_field/{object_name}',
    headers=headers,
    json=json_data,
)
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
fetch('https://eu.api-proxy.stacksync.cloud/v1/object/add_custom_field/{object_name}'
  method: 'POST',
  headers: {
    'Authorization': 'Bearer your_api_proxy_service_token',
    'Content-Type': 'application/json'
  },
  // body: '{"data": {"field_name": "field_name", "field_type": "field_type"}}',
  body: JSON.stringify({
    'data': {
      'field_name': 'field_name',
      'field_type': 'field_type'
    }
  })
});
```

{% endtab %}
{% endtabs %}

Example Response Body:

```json
{
    "data": {
	"archived": false,
	"calculated": false,
	"createdAt": "2024-01-11T23:43:00.066Z",
	"createdUserId": "46192612",
	"description": "",
	"displayOrder": -1,
	"externalOptions": false,
	"fieldType": "text",
	"formField": false,
	"groupName": "companyinformation",
	"hasUniqueValue": false,
	"hidden": false,
	"label": "StacksyncID",
	"modificationMetadata": {
		"archivable": true,
		"readOnlyDefinition": false,
		"readOnlyValue": false
	},
	"name": "enumeration",
	"options": [],
	"type": "string",
	"updatedAt": "2024-01-11T23:43:00.066Z",
	"updatedUserId": "46192612"
   },
   "message": "Custom field added successfully"
}
```

Example requests for different field types for the HubSpot Company object:

{% tabs %}
{% tab title="String" %}

```
curl -X POST https://eu.api-proxy.stacksync.com/v1/object/add_custom_field/company \
        -H "Authorization: Bearer *****" \
        -H "Content-Type: application/json" \
        -d '{
                "data": {
                    "name": "custom_field",
                    "label": "Custom Field", 
                    "type": "string",  
                    "fieldType": "text",
                    "groupName": "companyinformation"
                }
            }'
```

{% endtab %}

{% tab title="Enumeration" %}
For enumeration, the options property is required. The options property is a list of objects with the following properties:

* `label` (required) The display name of the option.
* `value` (required) The value of the option which will be used internally.
* `description` (optional) A text description for the option.
* `hidden` (optional) If true, the property won't be visible and can't be used in forms.

```
data {
	...
	"type": "enumeration",
	"options": [
	    {
		"label": "Option A",
		"description": "Choice number one",
		"value": "A",
		"hidden": false
	    },
	    {
	        "label": "Option B",
		"description": "Choice number two",
		"value": "B",
		"hidden": false
	    }
	]
	...
}
```

Example of full cURL request:

```
curl -X POST 

https://eu.api-proxy.stacksync.cloud/v1/object/add_custom_field/company \
        -H "Authorization: Bearer ******" \
        -H "Content-Type: application/json" \
        -d '{
	"data": {
		"name": "custom_field",
		"label": "Custom Field",
		"type": "enumeration",
		"fieldType": "select",
		"groupName": "companyinformation",
		"options": [
			{
			    "label": "Option A",
			    "description": "Choice number one",
			    "value": "A",
			    "displayOrder": 1,
			    "hidden": false
			},
			{
			    "label": "Option B",
			    "description": "Choice number two",
			    "value": "B",
			    "displayOrder": 2,
			    "hidden": false
			}
		]
		}
	}
}'
```

{% endtab %}
{% endtabs %}

## Pass Through

Make a request to any HubSpot API which supports OAuth by providing the URL, Request Method and the Request Body.

{% hint style="info" %}
HubSpot indicates whether an endpoint can be used with an OAuth token in their API documentation: <https://developers.hubspot.com/docs/api/overview>

<img src="https://2867423571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfJjIdV9cuW6K8asJjTPJ%2Fuploads%2FdbRu2Ph9aiISUQmnoTti%2FScreenshot%202024-02-12%20030631.png?alt=media&amp;token=cc96bd14-96f4-4e85-8c09-700ed4a1eddd" alt="" data-size="original">
{% endhint %}

A request will be sent to the URL provided using the request method and request body. The request body can be empty.

```
curl -X [GET | POST | PUT | PATCH | DELETE] 
https://eu.api-proxy.stacksync.com/v1/proxy/INSERT_REQUEST_URL_HERE \
-H "Authorization: Bearer your_api_proxy_service_token" \
-d 'Optional'
```

Example request:

**Create a new HubSpot Contact**

{% tabs %}
{% tab title="cURL" %}

```url
curl -X POST https://eu.api-proxy.stacksync.com/v1/proxy/https://api.hubapi.com/crm/v3/objects/contacts/batch/create \
        -H "Authorization: Bearer your_api_proxy_service_token" \
        -H "Content-Type: application/json" \
        -d '{"inputs": [{"properties":{	"email": "john@company.com"}}]}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

url = "https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/objects/contacts/batch/create"

api_proxy_service_token = "your_api_proxy_service_token"

data ={
	"inputs": [
		{
			"properties": {
				"email": "john@company.com"
			}
		}
	]
}

headers = {
    'Authorization': f'Bearer {api_proxy_service_token}',
    'Content-Type': 'application/json'
}

response = requests.postt(url, json=data,, headers=headers)

```

{% endtab %}

{% tab title="Javascript" %}

```javascript
const url = `https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/objects/contacts/batch/create`;

const api_proxy_service_token = 'your_api_proxy_service_token';

const data ={
	"inputs": [
		{
			"properties": {
				"email": "john@company.com"
			}
		}
	]
}

const headers = {
  'Authorization': `Bearer ${apiProxyServiceToken}`,
  'Content-Type': 'application/json'
};

fetch(url, {
  method: 'POST',
  headers: headers,
  body: JSON.stringify(data)
})
  .then(response => response.json())
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error(error);
  });

```

{% endtab %}
{% endtabs %}

Example response:

```json
{
	"completedAt": "2024-02-12T02:18:24.961Z",
	"results": [
		{
			"archived": false,
			"createdAt": "2024-02-12T02:18:24.748Z",
			"id": "441751",
			"properties": {
				"createdate": "2024-02-12T02:18:24.748Z",
				"email": "john@company.com",
				"hs_all_contact_vids": "441751",
				"hs_email_domain": "company.com",
				"hs_is_contact": "true",
				"hs_is_unworked": "true",
				"hs_lifecyclestage_lead_date": "2024-02-12T02:18:24.748Z",
				"hs_marketable_status": "false",
				"hs_marketable_until_renewal": "false",
				"hs_object_id": "441751",
				"hs_object_source": "INTEGRATION",
				"hs_object_source_id": "1749998",
				"hs_object_source_label": "INTEGRATION",
				"hs_pipeline": "contacts-lifecycle-pipeline",
				"lastmodifieddate": "2024-02-12T02:18:24.748Z",
				"lifecyclestage": "lead"
			},
			"updatedAt": "2024-02-12T02:18:24.748Z"
		}
	],
	"startedAt": "2024-02-12T02:18:24.720Z",
	"status": "COMPLETE"
}
```

#### Get the schema / columns of a standard Hubspot object

{% tabs %}
{% tab title="cURL" %}

```
curl -X GET 
https://eu.api-proxy.stacksync.com/v1/proxy/https://api.hubapi.com/crm/v3/properties/<object_name> \
-H "Authorization: Bearer your_api_proxy_service_token" \
```

{% endtab %}

{% tab title="Python" %}

```
import requests

# Parameters
url = "https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/properties/<object_name>"
headers = {
    "Authorization": "Bearer your_api_proxy_service_token"
}

# Send GET request
response = requests.get(url, headers=headers)

```

{% endtab %}

{% tab title="Javascript" %}

```
// Parameters
const url = "https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/properties/<object_name>";
const headers = {
    "Authorization": "Bearer your_api_proxy_service_token"
};

// Send GET request
fetch(url, { method: 'GET', headers: headers })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));

```

{% endtab %}
{% endtabs %}

#### Get the schema / columns of custom Hubspot objects

{% tabs %}
{% tab title="cURL" %}

```
curl -X GET 
https://eu.api-proxy.stacksync.com/v1/proxy/https://api.hubapi.com/crm/v3/schemas \
-H "Authorization: Bearer your_api_proxy_service_token"
```

{% endtab %}

{% tab title="Python" %}

```
import requests

# Set up the URL and headers
url = "https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/schemas"
headers = {
    "Authorization": "Bearer your_api_proxy_service_token"
}

# Execute the GET request
response = requests.get(url, headers=headers)

```

{% endtab %}

{% tab title="Javascript" %}

```
// Define the URL and headers
const url = "https://eu.api-proxy.stacksync.cloud/v1/proxy/https://api.hubapi.com/crm/v3/schemas";
const headers = {
    "Authorization": "Bearer your_api_proxy_service_token"
};

// Perform the GET request
fetch(url, { method: 'GET', headers: headers })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));

```

{% endtab %}
{% endtabs %}
