offdataai
HubSpot · data model template

HubSpot Core Objects Source Replica data model

Faithful 3NF replica of core HubSpot objects with the native object Id as the business key and connector metadata (createdate, hs_lastmodifieddate, archived flag, sync time, soft-delete) for incremental, archive-aware loading. HubSpot's M:N associations (deal↔contact, deal↔company, contact↔list) are resolved with junction tables. Mirrors how Fivetran/Airbyte land HubSpot; serves as the raw schema beneath the HubSpot analytics mart.

A normalized (3NF) landing replica of core HubSpot objects exactly as an ELT connector (Fivetran/Airbyte) replicates them into the warehouse: owner, company, contact, deal_pipeline, deal_pipeline_stage, deal, engagement, email_campaign, email_event, ticket, contact_list (+ membership), deal↔contact / deal↔company associations, and form (+ submission) — the raw layer that staging models and marts build on. It is a normalized (3NF) relational model that mirrors the source system, suited to operational databases and to landing source data faithfully.

3NFHubSpotGDPRCCPACAN-SPAM
16
tables
181
columns
22
relationships
7
PII columns

Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: Snowflake). Edit it in plain English or on the canvas, then ship it to any supported warehouse.

Subject areas

platformcrm_coreactivitymarketingservice

Design decisions

  • Native object Id retained as the business key

    ELT connectors replicate HubSpot keyed on the object Id; keeping it as the business key (alongside a warehouse surrogate) preserves lineage to the source portal and lets associations resolve on the same id the API exposes.

  • hs_lastmodifieddate and archived flag on every object

    Incremental syncs filter on hs_lastmodifieddate and must honour archived/soft-deleted records; carrying both on every table makes the landing layer reloadable and archive-aware.

  • M:N associations resolved with junction tables

    HubSpot deals associate with many contacts and companies, and contacts belong to many lists; modelling these as junction tables (deal↔contact, deal↔company, contact↔list) keeps the replica in 3NF without repeating object data.

  • Conformed pipeline table for deals and tickets

    HubSpot stores deal and ticket pipelines in the same structure; a single pipeline table with a pipeline_type flag mirrors the source and avoids two near-identical tables.

Tables in the HubSpot Core Objects Source Replica model

Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.

Tables (13)

hs_owner

Grain: one row per owner (user)

ColumnTypeKeys
owner_keybigintPK
hubspot_idvarcharBK
emailvarcharPII
first_namevarcharPII
last_namevarcharPII
user_idvarchar
team_idvarchar
is_activeboolean
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_company

Grain: one row per company

ColumnTypeKeys
company_keybigintPK
hubspot_idvarcharBK
company_namevarchar
domainvarchar
industryvarchar
company_typevarchar
lifecycle_stagevarchar
countryvarchar
number_of_employeesinteger
annual_revenuedecimal
owner_keybigint
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_contact

Grain: one row per contact

ColumnTypeKeys
contact_keybigintPK
hubspot_idvarcharBK
emailvarcharPII
first_namevarcharPII
last_namevarcharPII
phonevarcharPII
job_titlevarchar
lifecycle_stagevarchar
lead_statusvarchar
original_sourcevarchar
email_opt_outboolean
associated_company_keybigint
owner_keybigint
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_deal

Grain: one row per deal

ColumnTypeKeys
deal_keybigintPK
hubspot_idvarcharBK
deal_namevarchar
amountdecimal
deal_typevarchar
stage_keybigint
pipeline_keybigint
owner_keybigint
close_datedate
is_closedboolean
is_wonboolean
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_engagement

Grain: one row per engagement (call/email/meeting/note/task)

ColumnTypeKeys
engagement_keybigintPK
hubspot_idvarcharBK
engagement_typevarchar
owner_keybigint
engagement_timestamptimestamp
activity_typevarchar
directionvarchar
duration_msbigint
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_email_campaign

Grain: one row per marketing email campaign

ColumnTypeKeys
email_campaign_keybigintPK
hubspot_idvarcharBK
campaign_namevarchar
subjectvarchar
email_typevarchar
from_namevarchar
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_email_event

Grain: one row per marketing email event

ColumnTypeKeys
email_event_keybigintPK
hubspot_idvarcharBK
email_campaign_keybigint
contact_keybigint
event_typevarchar
event_timestamptimestamp
device_typevarchar
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_ticket

Grain: one row per Service Hub ticket

ColumnTypeKeys
ticket_keybigintPK
hubspot_idvarcharBK
subjectvarchar
pipeline_keybigint
ticket_stagevarchar
owner_keybigint
company_keybigint
contact_keybigint
priorityvarchar
source_typevarchar
close_datedate
is_closedboolean
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_contact_list_member

Grain: one row per contact per list (membership junction)

Junction resolving the many-to-many between contacts and lists.

ColumnTypeKeys
list_member_keybigintPK
list_keybigint
contact_keybigint
added_datetimestamp
fivetran_syncedtimestamp

hs_deal_contact

Grain: one row per deal↔contact association

Junction resolving the many-to-many between deals and contacts.

ColumnTypeKeys
deal_contact_keybigintPK
deal_keybigint
contact_keybigint
fivetran_syncedtimestamp

hs_deal_company

Grain: one row per deal↔company association

Junction resolving the many-to-many between deals and companies.

ColumnTypeKeys
deal_company_keybigintPK
deal_keybigint
company_keybigint
fivetran_syncedtimestamp

hs_form

Grain: one row per marketing form

ColumnTypeKeys
form_keybigintPK
hubspot_idvarcharBK
form_namevarchar
form_typevarchar
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_form_submission

Grain: one row per form submission

ColumnTypeKeys
form_submission_keybigintPK
submission_idvarcharBK
form_keybigint
contact_keybigint
submitted_attimestamp
page_urlvarchar
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

Lookup tables (3)

hs_deal_pipeline

Grain: one row per pipeline (deal or ticket)

ColumnTypeKeys
pipeline_keybigintPK
hubspot_idvarcharBK
pipeline_labelvarchar
pipeline_typevarchar
display_orderinteger
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_deal_pipeline_stage

Grain: one row per pipeline stage

ColumnTypeKeys
stage_keybigintPK
hubspot_idvarcharBK
pipeline_keybigint
stage_labelvarchar
display_orderinteger
probabilitydecimal
is_closed_wonboolean
is_closed_lostboolean
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

hs_contact_list

Grain: one row per contact list

ColumnTypeKeys
list_keybigintPK
hubspot_idvarcharBK
list_namevarchar
list_typevarchar
created_datetimestamp
updated_datetimestamp
is_archivedboolean
fivetran_syncedtimestamp
fivetran_deletedboolean

Relationships

Each relationship is a foreign key on the first table referencing the second.

  • hs_company.owner_key → hs_owner (many-to-one)
  • hs_contact.associated_company_key → hs_company (many-to-one)
  • hs_contact.owner_key → hs_owner (many-to-one)
  • hs_deal_pipeline_stage.pipeline_key → hs_deal_pipeline (many-to-one)
  • hs_deal.stage_key → hs_deal_pipeline_stage (many-to-one)
  • hs_deal.pipeline_key → hs_deal_pipeline (many-to-one)
  • hs_deal.owner_key → hs_owner (many-to-one)
  • hs_engagement.owner_key → hs_owner (many-to-one)
  • hs_email_event.email_campaign_key → hs_email_campaign (many-to-one)
  • hs_email_event.contact_key → hs_contact (many-to-one)
  • hs_ticket.pipeline_key → hs_deal_pipeline (many-to-one)
  • hs_ticket.owner_key → hs_owner (many-to-one)
  • hs_ticket.company_key → hs_company (many-to-one)
  • hs_ticket.contact_key → hs_contact (many-to-one)
  • hs_contact_list_member.list_key → hs_contact_list (many-to-one)
  • hs_contact_list_member.contact_key → hs_contact (many-to-one)
  • hs_deal_contact.deal_key → hs_deal (many-to-one)
  • hs_deal_contact.contact_key → hs_contact (many-to-one)
  • hs_deal_company.deal_key → hs_deal (many-to-one)
  • hs_deal_company.company_key → hs_company (many-to-one)
  • hs_form_submission.form_key → hs_form (many-to-one)
  • hs_form_submission.contact_key → hs_contact (many-to-one)

Related templates

All templates →
Start for $1

From requirements to AI-ready context, in one platform.

Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.

Get startedBook a demo

Plans from $1/month · cancel any time