Back to Blog
HubSpotRevOpsB2B

HubSpot custom objects: when to build one

Abhishek Singla May 20, 2026 15 min read

A founder I worked with last quarter walked me through his HubSpot portal and asked why his renewals report was wrong by about $400K. The contracts team was tracking subscription terms in a Google Sheet. Customer success was tracking product usage in a Notion database. Finance was tracking invoices in QuickBooks. None of it talked to HubSpot. So when his head of sales pulled a renewals dashboard, the numbers came from deal stages that nobody had updated since the original close.

The fix was not another property. It was not another workflow. He needed a custom object.

I have built somewhere north of 60 HubSpot custom objects across client portals in the past three years. Most of them were the right call. A few were not. This post is the guide I wish someone had handed me when I started: when custom objects actually solve a problem, when a custom property does the job for a tenth of the work, and the build mistakes that quietly break reporting six months later.

What a custom object actually is

HubSpot ships with five standard objects: contacts, companies, deals, tickets, and products. A custom object is a sixth, seventh, eighth box you define yourself. It has its own properties, its own associations to other objects, its own permissions, and its own row in workflows and reports.

A subscription is a custom object. A shipment is a custom object. A loan application, a vehicle in your fleet, an event registration, a partnership agreement, a property listing. Anything that has its own lifecycle, its own owner, and its own attributes that do not belong on a contact or a deal.

The HubSpot product team gates custom objects behind Enterprise (CRM, Sales, Service, or Marketing). That alone changes the math for a lot of teams. If you are on Pro and reaching for custom objects, the price jump from Sales Pro to Enterprise is roughly $1,200 per seat per month at list. Walk through the cheaper options first.

When you actually need one

Here is the test I run with every client. A custom object is the right call when three things are true at once.

First, the entity has its own lifecycle. A subscription starts, gets paid, renews, churns. A shipment is created, picked, packed, shipped, delivered. A loan application is submitted, reviewed, approved or denied, funded. If the entity just sits there with one or two fixed values, it is a property.

Second, you need many of them per parent. A company can have many subscriptions. A deal can have many line items already covered by products. A contact can have many event registrations. If the cardinality is one-to-one with a company or a deal, it is a property.

Third, you need to report on it as its own thing. You want a list of all active subscriptions across all customers. You want a dashboard of every shipment delayed past SLA. You want a workflow that fires when an application moves to "approved." Reporting and workflows on the entity itself, not on the parent record.

If all three are true, build the custom object. If only two are true, a custom property on the parent object almost always wins.

Wrong reach for custom objects
A "renewal date" field on the deal record
Industry vertical tagging on companies
A single primary contact role per deal
Lead source attribution per contact
One-off NPS scores per customer
Real custom object cases
Subscriptions tied to a company with MRR, term, renewal date
Shipments with carrier, tracking, status, ETA
Loan applications with stage, risk score, decision
Partner agreements with tier, commission split, signed date
Equipment units with serial number, warranty, service history

The five custom objects I build most often

After a few dozen client builds, the same five patterns show up across B2B SaaS, B2B services, and account-based businesses. If your model fits one of these, the design work is mostly done.

1. Subscription

The most common one. The deal closes, the subscription begins. The deal is a one-time event. The subscription is the recurring relationship. You associate one to many subscriptions to a company. Each one carries plan tier, MRR, ARR, start date, term, auto-renew flag, renewal date, churn risk score, and a status. Customer success owns it. Finance reports on it. Renewal workflows fire from it.

The single biggest reporting problem I see in B2B SaaS portals is teams trying to model subscriptions as deals. It works for the first year. The second year the renewal opens, the rep clones the original deal, and now your closed-won pipeline counts the same logo twice in different years. A subscription custom object removes the ambiguity. Closed-won deals are acquisitions. Subscriptions are the recurring revenue.

2. Project or engagement

For agencies, professional services, and any business that sells deliverables rather than seats. A project has a scope, a start date, an end date, a project manager, a status, and a budget. It is associated to the company and the deal that originated it. Time tracked, milestones, deliverables, invoices: all of it hangs off the project.

If you are an agency running on HubSpot Sales Pro with a Notion or Asana sidecar for project work, this custom object plus a clean handoff workflow saves at least one full-time admin role inside two quarters. I have seen it twice.

3. Asset or unit

Common in equipment leasing, healthcare devices, vehicle fleets, and physical product businesses. Each unit has a serial number, a model, a warranty status, an install date, and a service history. The asset is owned by a company (or a contact, for B2C). Service tickets associate to the asset, not to the contact.

This is the case where custom objects pay back the fastest. The alternative is a properties graveyard on the contact record where you try to track "serial number 1," "serial number 2," "serial number 3" as separate fields. That breaks the moment a customer has more than three units.

4. Application or request

Banks, lenders, insurance, education, anywhere there is a structured intake form with its own approval lifecycle. The application has a status, an assignee, a decision date, a reason code, and a set of attachments. The same contact can submit multiple applications over time. Each one is its own record with its own workflow.

This is where custom objects start replacing tickets. Tickets are designed for support work: short cycles, single resolution, queue routing. Applications often need richer state machines, multi-week review windows, and structured decision fields. The ticket object groans under the weight. The custom object handles it.

5. Partner agreement or referral

For partner-led growth motions. A partner is a company in your CRM. The partner agreement is the formal contract: tier, commission percentage, effective date, expiry, exclusivity terms. Deals associate to partner agreements. Commission calculations run off the agreement, not the company record.

The reason to split partner agreement from the company is renewals and tier changes. A partner can move from Silver to Gold mid-year. The historical commission on deals closed under Silver should still calculate at the Silver rate. A custom object preserves the snapshot. A property on the company record overwrites it.

The rule

If the entity has its own lifecycle, its own owner, and its own report, it is a custom object. If it does not, it is a property.

I have walked back from custom objects more often than I have walked back to them. Most teams over-build. Start with properties, prove the gap, then add the object.

When a property does the job

Before you build, pressure-test against the cheaper options. Most "we need a custom object" conversations end with a custom property and a workflow.

A single renewal date on the company. A churn risk score on the deal. An industry tag on the company. A primary contact role. A campaign source on the contact. All of these are properties. None of them need an object.

The signal is one-to-one. One company, one renewal date. One contact, one campaign source. The moment you find yourself thinking "we need three of these per record," step back and reconsider. Three of anything per record is the moment a property starts to break. Five is when you have lost.

I had a client last year who insisted on a custom object for "client meetings." Each meeting had a date, attendees, notes, and a follow-up flag. We almost built it. Then I asked what reporting they actually wanted off the object. The answer was "we want to see how many meetings happened with each account this quarter." That report is a one-line filter on the existing meeting engagement object that HubSpot already ships. We did not need a custom object. We needed a saved view.

The build sequence that does not break

The reason most custom object builds turn into disasters six months in is sequence. People start in the wrong place. The right order looks like this.

Step 01
ERD on paper
Draw the entity, its parents, and its relationships before opening HubSpot. Lucidchart or a napkin both work.
Step 02
Property list
List every field the object needs. Group by required vs optional. Get sign-off from the team that will use it.
Step 03
Sandbox build
Build in the sandbox portal, never in production. Test associations, workflows, and reports on dummy data first.
Step 04
Migrate and freeze
Move to production with a one-shot import. Freeze property changes for 30 days. Watch for reporting drift.

The freeze period matters more than people think. Once an object is live and connected to workflows, every property rename, every association change, every required-field flip risks breaking a downstream report or sequence. A 30-day freeze gives the team time to use the object, find the gaps, and propose changes as a batch instead of a constant trickle.

The five mistakes that wreck custom objects

I have cleaned up enough broken builds to spot the patterns from across the room.

Mistake one: skipping the ERD. Teams open the custom object builder and start adding properties from memory. Two weeks later they discover the object needs to associate to companies and deals, but the deals association was never set up, and now half the records are orphaned. Draw the diagram first.

Mistake two: bad API names. Display names can change. Internal API names cannot. If you ship a property called Status with the API name status, then later realize you needed subscription_status, you cannot rename it without breaking every integration, workflow, and report that references it. Prefix everything with the object name. subscription_status, subscription_mrr, subscription_renewal_date. Future you will thank present you.

Mistake three: too many properties. The technical limit is 1,000 per object. The practical limit is closer to 40. Past 40, the record page becomes unreadable, users stop filling in fields, and your reporting fragments. If you find yourself adding a 50th property, ask whether it should be a separate object or a calculation on an existing one.

Mistake four: ignoring association limits. HubSpot caps associations at 500 per record on most plans. If your custom object can have thousands of related records (think: a customer with 10,000 IoT devices), you will hit the wall fast. Design around it. Either roll up at the parent level or split the data model.

Mistake five: no Zapier path. Custom objects are not supported by most Zapier triggers and actions. If your workflow assumes you can fire a Zap when a custom object record is created, you are wrong. The HubSpot API works, but it requires real engineering. Plan the integration story before you build, not after.

$1,200
per seat per month
40
properties before reporting fragments
500
association cap per record

How custom objects fit your reporting stack

The payoff of a well-built custom object is not the object itself. It is the reporting that becomes possible.

Subscription objects give you real-time MRR dashboards that match what finance sees in Stripe. Project objects give you utilization reports by project manager. Asset objects give you warranty expiry alerts and service revenue forecasts. Application objects give you funnel reporting on approval rates by stage, by reviewer, by source.

The trick is to design the properties with the report in mind. Want to report on monthly MRR change? Add a subscription_mrr_change_this_month calculated property. Want to report on renewal risk? Add a subscription_renewal_health enumeration with three values: healthy, watch, at risk. Decide the report first. Build the property to feed it.

If you are running on HubSpot and want a sanity check on whether your data model can support the reports your CEO is asking for, this is the kind of audit we run in our CRM and RevOps work. Most of the time the answer is a smaller change than the client expects: three new properties, one workflow, and a fresh association. Sometimes it is a full custom object build. Either way the analysis is the same.

Custom objects vs. external systems

A real question I get from founders every month: should this live in HubSpot at all, or in a separate system?

The honest answer depends on who owns the workflow.

If sales and customer success own the workflow, HubSpot wins. Custom objects keep the data alongside the contact, the company, and the deal. Reps see it on the record. Workflows fire across object boundaries. Reporting lives in one place.

If finance or engineering owns the workflow, an external system usually wins. A subscription billing system like Stripe or Chargebee handles invoices, dunning, and tax. A product analytics tool like Mixpanel handles event-level usage. Trying to model invoices in HubSpot custom objects works for the first month, then breaks the moment your accounting team needs revenue recognition logic.

The clean pattern is: source-of-truth system holds the canonical record, HubSpot syncs a derived custom object for sales and CS visibility. Stripe holds the subscription. HubSpot holds a subscription custom object that is read-only and synced nightly. Sales sees it. Finance owns it. Nobody fights about whose numbers are right.

This is the same architecture I covered in the CRM data enrichment guide. Pick your source of truth, sync derivatives, never let two systems fight for the same field.

What this looks like in practice

A B2B SaaS client of mine, around 80 employees, was running HubSpot Pro with a Google Sheets sidecar for renewals. The renewals sheet had every paying customer, contract start date, MRR, term, and renewal date. The CS team updated it manually after every QBR.

Three reporting problems were costing them real money. First, the sheet was always out of date because nobody owned its hygiene. Second, the sales leader had no view of renewals risk by rep or by segment. Third, the CFO was rebuilding revenue forecasts every month from scratch because the sheet did not match HubSpot deal stages.

We did three things. Upgraded to Enterprise. Built a subscription custom object with 22 properties: tier, MRR, ARR, start date, term, renewal date, auto-renew, churn risk, owner, status, and a handful of segment fields. Migrated 312 subscriptions from the sheet in one import.

Six weeks later: the CS team had a dashboard showing every subscription up for renewal in the next 90 days, with risk scoring and owner. The sales leader had a renewal pipeline view that mirrored new business. The CFO pulled MRR straight from HubSpot and stopped rebuilding the forecast. Renewal rate visibility went from a guess at the start of each quarter to a number the team trusted enough to plan against.

Cost: roughly $15K in implementation across four weeks, plus the Enterprise upgrade. Time saved on the CS side: about 6 hours per week of sheet maintenance. The reporting clarity was the bigger win.

The shift
312

Subscriptions migrated from a spreadsheet sidecar into a HubSpot custom object in one import. Six weeks later the CFO trusted the renewal forecast enough to plan against it.

A quick word on the integration tax

Custom objects are not free downstream. Every integration you add later has to be checked for custom object support. Most do not have it out of the box.

Salesforce sync: works, but with caveats around field mapping and bidirectional updates. Slack: works for notifications. Outlook and Gmail: do not surface custom objects in the inbox sidebar by default. Zapier: limited support, often requires the HubSpot API directly. Most third-party HubSpot apps: support standard objects only.

Before you build, list every integration the object needs to touch. If a critical workflow runs through Zapier or a third-party app that does not support custom objects, build the integration plan first. We have used n8n on several client builds to bridge the gap, since it talks to the HubSpot API directly and handles custom objects without complaint. The same logic applies if you are running heavier automation through any AI automation layer.

Thinking about a custom object build?

If you are weighing whether to add a custom object or stick with properties, we can do the analysis in an hour. Book a free 30-minute audit and we will tell you which way the math goes.

Book an audit →

FAQ

Do I need HubSpot Enterprise to use custom objects?

Yes. Custom objects are an Enterprise feature across HubSpot CRM, Sales, Service, and Marketing Hub. If you are on Pro and need custom objects, the upgrade is roughly $1,200 per seat per month at list price. Run the cost-benefit before you commit. For many teams a clean set of custom properties on the existing objects gets 80% of the value.

How many custom objects can I create in HubSpot?

10 custom object definitions on Enterprise. Each definition can hold up to 2 million records. In practice, very few B2B teams need more than three or four custom objects total. If you are reaching for five or six, your data model probably needs a second look.

Can I create custom objects without an engineer?

Yes, for simple cases. HubSpot ships a no-code custom object builder in settings that handles object creation, properties, and associations. Engineering gets involved when you need to sync data from an external system, build a custom integration via the HubSpot API, or migrate historical records. Plan for at least one developer-day if external sync is in scope.

What is the difference between a custom object and a custom property?

A property is a single field on an existing record. One contact, one phone number. A custom object is a separate record type with its own lifecycle, properties, and associations. One company can have many subscription records, each with its own term, MRR, and renewal date. Use a property for one-to-one data. Use a custom object for one-to-many.

Can I delete a custom object after I build it?

Yes, but with consequences. Deleting an object removes all records, properties, and associations tied to it. Workflows referencing the object break. Reports built on it disappear. If you are unsure whether you need an object, build it in the sandbox portal first and run it for two weeks before promoting to production.

If you want help thinking through a custom object build or your broader HubSpot data model, we run audits and implementations through our CRM and RevOps practice. The first conversation is free and usually saves teams a few thousand dollars worth of bad property decisions.