Skip to content

How to Build a Custom Object Using Private Apps

HubSpot provides a set of standard CRM objects with each account, such as contacts, companies, and deals. However, these objects might not reflect the type of data you need to store. Now, you can create custom objects to represent and organize your CRM data based on your business needs. The best part is that these custom objects can be used the same way as other standard CRM objects, including automations or email templates. 

Use the custom objects API to define custom object schemas, properties, and associations to other CRM objects. You can use an API testing application like Postman to make the call. This is the method used in this tutorial.

Authenticate Using a Private App

Creating a custom object requires authentication. You can authenticate using a private app or OAuth. To authenticate this API call, let’s build a private app. Private apps are a scoped form of authentication, meaning you’re not risking sensitive account data being stolen if your personal access token is leaked. The private app will only grant permissions to the scopes you determine and you can change the scopes it has access to at any time.

In your account, click on the gear settings icon in the main menu. In the left-hand sidebar, click on Integrations, and then choose Private Apps

Click, Create a private app. Give the app a name, like Custom Object Authentication. 

Then, click on the Scopes tab. The Scopes tab is essential for making a successful call. For this private app, you’ll need the following scopes:

  • crm.objects.custom.write
  • crm.schemas.custom.write

These scopes are housed under the Standard dropdown. Scroll down until you find them and then click the checkboxes beside them. In doing so, you're granting this private app the ability to read and write custom object records, as well as create new custom object schemas, which is the call you’ll be making to create your new custom object.  

Now, in the top right corner, click Create app. In the popup window, click Continue creating. Next, in the new popup window, click on Show token, and then Copy, to copy your private app’s personal access token. Great, you now have the authentication needed to use the API call. 

Call the API endpoint in Postman

Postman allows you to make calls to your API without setting up your own app. To work with Postman, all you’ll need is the API endpoint, the authentication information, and the custom object JSON schema. To create a new custom object, you’ll make a POST request to the Bearer Token authentication type. Then, in the token field, you’ll paste your personal access token.

Once you’ve added your token and the endpoint, let’s start building your custom object schema. This will be passed along in the request’s body.

Build the Custom Object Schema

Custom object schemas have several required properties. Check the developer documentation for a deeper understanding. For this example, let’s keep the schema as simple as possible. The main three sections of a custom object schema are 

  1. The custom object name 
  2. The custom object’s properties
  3. The custom object’s association with other CRM objects

Keep in mind that the object’s name and label can’t be changed after its creation. Your custom object schema is required to have at least one property, and you can add other properties to your custom object after it’s been built.

The name is the internal label for the custom object and should be written in lowercase without spaces. You can add dashes between words if your name is longer than one word. The labels are the human-readable versions of the custom object name and will appear in your account. You'll create both a singular and plural version.

The primaryDisplayProperty is the property used for naming individual custom object records. The secondaryDisplayProperties are the properties that appear on individual records under the primaryDisplayProperty. The requiredProperties are the properties required when building a new custom object record. The searchableProperties are the properties indexed for searching in HubSpot. 

Each custom object must have at least one property. Inside the properties key, you’ll create an array that contains the different property fields. Each property must include a name, a label, a type, and fieldType. You have several types to choose from, including string, number, date, or enumeration. You must include values to choose from if the type is set to enumeration.

The last required section is associatedObjects. This value is also an array, and it can include the standard CRM objects, as well as associations to any other custom objects you’ve already created. 

Here’s the JSON schema to build a custom object called “Boat.”

{ "name": "boat", "labels": { "singular": "Boat", "plural": "Boats" }, "primaryDisplayProperty": "model", "secondaryDisplayProperties": [ "make" ], "searchableProperties": [ "year", "make", "hin", "model" ], "requiredProperties": [ "year", "make", "hin", "model" ], "properties": [ { "name": "condition", "label": "Condition", "type": "enumeration", "fieldType": "select", "options": [ { "label": "New", "value": "new" }, { "label": "Used", "value": "used" } ] }, { "name": "date_received", "label": "Date received", "type": "date", "fieldType": "date" }, { "name": "year", "label": "Year", "type": "number", "fieldType": "number" }, { "name": "make", "label": "Make", "type": "string", "fieldType": "text" }, { "name": "model", "label": "Model", "type": "string", "fieldType": "text" }, { "name": "hin", "label": "HIN", "type": "string", "hasUniqueValue": true, "fieldType": "text" }, { "name": "color", "label": "Color", "type": "string", "fieldType": "text" }, { "name": "mileage", "label": "Mileage", "type": "number", "fieldType": "number" }, { "name": "price", "label": "Price", "type": "number", "fieldType": "number" }, { "name": "notes", "label": "Notes", "type": "string", "fieldType": "text" } ], "associatedObjects": [ "CONTACT" ] }


Now, let’s add this schema to Postman. In the Body tab, make sure to choose the raw option. Then, set the language to JSON. Paste in your JSON schema, and then, in the top right-hand corner, click the blue Send button. If your call is successful, you should see a 201 Created status.

Finally, let’s return to the account to ensure the custom object has been created. You can now find a list of your custom objects in the main menu. Click on Contacts and then hover over Custom Objects. A flyout window will appear listing the custom objects you have in your account. Your new custom object “Boat” has been created! 


Custom objects work in the same way as any other CRM object. You can import data via a CSV to add records in bulk or use the Create button to add a new record one at a time. Define the right custom object for your business needs, and then use them in everything from your CMS pages to custom workflows.

Best of all, with private apps you’ll have peace of mind. You won’t have to worry that sensitive information could be leaked if your personal access token is stolen since the scopes restrict access to other parts of your account. You’ll also be able to track all calls made. Start building your custom objects safely and securely.