Skip to content

How to Think like an Architect by Building Scalable Custom Objects

Custom objects are a uniquely powerful way to keep a business in sync, to automate tasks, and even to report on business data. Because custom objects can be such a powerful part of a business' data architecture, collaboration and thoughtful planning are important. In this guide to planning and designing a custom object, we're going to consider the full lifecycle of the object as well as how to name and define objects and properties for scale. All of this should happen before and during the process of creating the actual custom object. This guide is both technical and strategic. If you're a technical user building, customizing, or integrating on HubSpot, or a strategic user working in operations or marketing role, this is for you. 

Define the purpose of the object

This may seem obvious at first, but it’s important to ask: What is the reason you are creating a custom object? You're likely thinking of a specific thing you want to do with the object: Create a CRM card that leverages it, create reports on it, create a workflow from it, or display it on a website. What I'm asking, though, is what is its primary underlying goal?

In most situations, the underlying goal likely is something like this: Keeping the whole company (sales, service, marketing, developers, operations, accounting, executives, etc) in sync as to the details related to that object, and potentially even keeping customers in sync with some of the details of that object through your website or emails, enabling them to act on it.

Having this primary goal in mind will help you make decisions that set you up better than simply focusing on the individual action you want to do with the object.

Write this goal down somewhere that you and your team members can see it.

I've created an optional workbook you can use to keep your notes organized as you follow along.

Define the lifecycle of this object

Hopefully, if you're using HubSpot, you're familiar with the inbound methodology and the flywheel. At the center of your flywheel are your customers (Attract, Engage, Delight). Multiple teams overlap in responsibility for each stage (Marketing, Sales, Service, etc). Your custom object will likely have a lifecycle, too, but it may not be a circle like the flywheel — it may be linear.

For example, a marketing event's lifecycle might look like this:

  1. Marketer creates an event.
  2. Contacts receive an email/or other announcements about the event.
  3. Contacts go to a landing page detailing what to expect at the event, and they fill out a form to register for the event.
  4. Event starts, new registrations are blocked, and actual attendance of the event is observed and logged. Potentially, the event starts getting video recorded.
  5. Maybe some more granular data about the event needs to be tracked during the event.
  6. Event ends. Landing page gets updated to reflect that the event is over.
  7. An email is sent to attendees thanking them for coming, recapping what happened, and including any additional useful resources (like a video recording).
  8. Internal post-event analysis/reporting is done.
  9. Sales, service, marketing, technical consulting, developer advocacy, etc. link contacts to the recording of the event if it was relevant. Internal teams make decisions based on the data from that event, determining what worked, what didn't, and refining for future events.

Throughout that whole lifecycle, sales and service can see if their contacts are attending  — and even suggest attending it or watching it after the fact based on the contact's needs. Additionally, having the context that someone attended the event can help sales and service build on top of the information from that event. This saves everyone time and helps deliver a more personal experience to the customer.

Write out the lifecycle of your object.

This will come in handy later.

Don't worry about getting every little detail about this lifecycle correct right off the bat. It's likely you know some big obvious lifecycle stages for the object, but there are areas in the lifecycle where you may have gaps.

Gather the current and potential future stakeholders

From the lifecycle, you've probably figured out that multiple teams may touch this object — including some you may not have expected.

You're going to want to rally a representative stakeholder for each of those teams to ensure each team will get the value they want out of that object.

You may want one (or more) representatives from:

  • Marketing
  • Service
  • Sales
  • CMS development, CRM development, revenue operations
  • Other internal teams that could interact with the object

You may be thinking, "hold on a minute, I'm creating this object so I can do X action with it. Inviting all these people will make this take forever.". 

The goal of inviting all of these folks isn't to get into the weeds of your team's individual processes and use of the object — it's to better understand everyone else's touch points with the object. You can't really figure out the data structure without understanding the context of how it can/will be used. Doing this now will prevent you from having to restructure, clean, and reformat data down the road due to a conflict with how it needs to be used, which can save you a ton of time and frustration.

  1. Show all of the stakeholders the lifecycle you have written down. 
  2. You're going to ask them a series of questions. For each question, write down their responses, as you'll refer back to them later.
    1. Ask them if they see missing or inaccurate details from their perspective. Update your documentation of this lifecycle now so you don't forget anything.
    2. Ask them if their team calls/refers to the object by a different name. (Sometimes different teams refer to something based on the lifecycle stage they start to work with, or by technical internal names.) 
    3. Ask them, from their team's perspective, what’s the most important information that their team needs to know about that object? 
    4. Ask them, from their team's perspective, what information may be nice-to-have, but isn't required at this time. 

How to name your object

Pull out the information you collected from the stakeholders. The name you choose should be something that your sales, service, marketing, developers, and other stakeholders will all be able to understand as being the same thing. This means the name should not be tied to a stage of a process the object is in. Instead, use a name that will describe the object throughout the full lifecycle.

The name should ideally be short, simple, and easily understood. 

The internal name should be the plural form of that object since you're defining a collection of objects. Some examples from HubSpot defined objects:

  • Contacts
  • Companies
  • Marketing Events
  • Products

You will be able to designate a plural and singular label for the object so it displays properly in UIs (User Interfaces), but under the hood using a plural name will make more sense in code and match HubSpot's default objects nomenclature.

Defining your properties

Have your notes from your stakeholder conversations handy. You're going to need them.

Primary display property

The primary display property for the object is the property that will show in the app views most prominently. Since this shows in the listing view for that object, you'll want to make sure that this is something fairly unique, human readable, and easy to recognize at a glance.

For example, an ID number of some kind may be unique, but for most things that's not going to be as human readable and recognizable as a name of some kind. With events, you usually refer to them by the event's name, while contacts are referred to by their names.

Note that I said it should be "fairly" unique. Depending on the object type, you may not need it to be truly unique. Names of people for example are not unique. Even though I sign my name Jon McLaren, that doesn't make me a movie or video game voice over actor. If you do know your records should always have a unique value for the property, you can require it to be unique.

This primary display property should be something that all of the stakeholders need to know in order to be able to work with the object.

Write down the property.

Secondary properties

Secondary display properties appear on the individual object records immediately under the primary display property. You can have multiple secondary properties. The first of the secondary properties you provide will also display as a fourth filter in the object's record listing, so it can be useful to plan for which property that should be.

To determine your secondary properties, review all of the information each team needed. What is the next piece of information that is needed by nearly everyone? Perhaps the object will need a property that indicates the state the object is in. For example, a rental car company might create a property called "vehicle availability" and give it the options of "Available," "Needs Maintenance," or "In use".

The sales team needs this to ensure they assign only available vehicles to customers, the maintenance team needs this to easily view only vehicles currently needing maintenance, and the collections team needs to see which cars are currently "In use" beyond the expected return date in order to charge the customer appropriately. 

Write down that important property.

Now that you have your first one, you can add one more secondary property. It should be the next most important piece of information commonly needed by the majority of the teams.

Write down the property.

The remaining properties

Just like you did with the primary and secondary properties, continue to identify all of the other overlapping pieces of information that most teams will need when working with the object.

Write these properties down.

All of the information that doesn't overlap should be kept in a list. Identify the ones that teams denoted as required for them to be able to work. 

Write down those required properties.

Identify the information that doesn't overlap but is needed by your team for the current use-case. Write it down.

Properties that are not needed for your team's use-case and not deemed required by other teams should be kept in a list, but not necessarily created right away. Remember, you will be able to add new properties to the object after its initial creation. If you try to create a lot of properties for data your team isn't directly interacting with on a regular basis, you're likely to set up the properties in a way that doesn't mesh well with the reality of that data or the process it's part of. 

Review your list and determine types and field types

You should have a list of all of the data that's truly required to be able to use this object. You now need to decide in what format that data will be required. Take your time with this; it's not going to be as easy as you might initially think. And don't worry about being perfect the first time — you're going to run this by the other stakeholders before you add the schema to your account.

Let's start with identifying the easiest field types and data types.

Look through your list and write date next to all of the properties in which the user should expect a date (e.g., "start date," "end date," "date of event").

Do you also need to know the exact time or is just knowing the day enough? If the time is also necessary, then write time next to those properties.

Look for all properties in which the only possible answer is a number. This number should not require special characters like quotes, "x," commas, or hyphens to make sense of it. Note that some parts of the world use commas instead of periods to indicate decimal points, which is an exception to the comma rule. For dimensions of something, it likely makes sense to split each dimension into a separate property.  For example, "Length," "width," and "height," instead of one field called "Dimensions" (10x3x5).

Write number next to each of these.

Look for all properties where you expect a file to be uploaded. Write string file next to them.

From here it gets a little harder.

Identify all of the properties for which the answer can only be true/false or yes/no. These properties should be ones that are absolute, without in-between or alternative states. You shouldn't be able to say "this object is kind-of  ____" (the blank representing the state that the property is for). For example, an inn either has vacancy or it doesn't. They may not have the specific room you want, but vacancy is purely whether they have rooms left or not.

Write enumeration booleancheckbox next to each of these properties. 

Identify all of the properties that may have more than two states. This might be, for example, a field indicating the lifecycle stage of an object. These should not be properties where the ability to write in custom text is needed.

Write enumeration next to each of these properties.

It would also be a good idea to write out each of the possible values you see for this field.

For each of those properties where multiple of the values might be true at the same time, also write checkboxAdditionally, write out each of the possible values for this field.

For each of those properties where only one of the values can be true at the same time, you will write radio/select. If there are five or less options, radio may be preferred. Beyond that, select is best if you have a large number of options, like a list of countries. If there's a small number of options that can't be assumed, write them out (a property called countries, you can assume, will be a list of countries).

Your remaining properties should be strings.

Write string by the rest of your properties.

The field type for these depends on the amount of content you expect to be entered into the field. 

  • If the user will need to enter full sentences, or multiple lines of text, write textarea.
  • If the user will only need to write a word, short phrase, URL, or other short text, write text.

You have all of your field types and their data types now, but I caution you not to create your object just yet. Send this list to the stakeholders and ask them to comment if they see any areas where they disagree about the type of data being stored. Disagreements often have to do with boolean fields and enumeration fields, because some teams will find more granular options. If you're worried about it taking too long, give them a deadline and say you'll assume they see no issues if none were provided prior to that deadline.

Start creating your object schema

At the time of writing this article, creating custom objects through the API or CLI gives you the greatest range of control over field types and associations at creation. 

To use the API or CLI, you'll create a JSON object. 

Here's an example of a "cars" object's JSON schema:

{ "name": "cars", "labels": { "singular": "Car", "plural": "Cars" }, "primaryDisplayProperty": "model", "secondaryDisplayProperties": [ "make" ], "searchableProperties": [ "year", "make", "vin", "model" ], "requiredProperties": [ "year", "make", "vin", "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": "vin", "label": "VIN", "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 that you know your object name and your labels, you can fill those in. 

When creating properties, though, property names should be short, descriptive, and (ideally) imply their data type. Note: This doesn't necessarily mean prefixing everything.

For example, for an event object's start and end date property names, you might literally use start_date and end_date. It's obvious from this that you're expecting the value of those properties to be dates.

If an event had attendees, using a name like attendee_count or number_of_attendees indicates it's going to return a number, likely an integer.

This name only needs to make sense to your HubSpot users and developers. HubSpot forms can use labels to provide more external-facing wording when needed.

One last consideration: Is the data coming from a specific integration?

Consider prefixing the name so it's clear to everyone where that data came from or what it's related to. You'll want to establish norms with prefixing related to that specific integration — and then stick to them. Otherwise, you may end up with a confusing situation in which  fb_, meta_, facebook_, are all used to refer to the same integration/app.

Additionally, if a user in HubSpot sees that name/label, will they understand it to mean the same thing as someone seeing it in the integrated software? They should.

Congratulations

You've successfully architected a custom object schema that enables your team to solve for your current use-case while also looking ahead for future teams who may want to tap into that same object. You've been intentional about the data types for properties, and prioritized the ones that are most important for cross-team collaboration. You've named properties in ways that make it easy for other developers to quickly understand the data they're working with, reducing trial and error. After you've created a few object schemas, you'll likely find your own additional best practices. It's a great idea to document them and share them within your company to help teams build for scale. If you've found this article helpful, include it in your documentation and share it with your team.

You're ready to get that schema into HubSpot. You can use the CLI or API, depending on your preference. Once your object is available in HubSpot, you're ready to start creating, working with, and building your CRM cards, website templates, modules, reporting, and other useful tools leveraging your new object type.