Skip to content

Association Labels

Association labels define named relationships between HubSpot object types. For example, a “Primary Contact” label on the contact-to-company association, or a “Partner” label on a company-to-company self-association. JetStack AI imports and deploys user-defined association labels, enabling you to replicate your custom relationship taxonomy across portals.

JetStack AI captures the following for each association label:

  • Label name — The display name of the association (e.g., “Decision Maker”, “Billing Contact”)
  • Association category — Always USER_DEFINED for importable labels
  • From object type — The source object in the relationship (e.g., contact)
  • To object type — The target object in the relationship (e.g., company)
  • Association type ID — HubSpot’s internal identifier for the association type

JetStack AI imports only labels with the USER_DEFINED category. Labels with the HUBSPOT_DEFINED category (such as “Primary Company” or the default unlabeled association) are system-managed and cannot be created or modified via the API. These are automatically present in every HubSpot portal and do not need to be migrated.

Association labels can reference:

  • Custom object types — If the association connects a standard object to a custom object (or two custom objects), the custom object type IDs must be remapped to the target portal’s IDs. Custom objects should be deployed before association labels.

There are no other asset dependencies for association labels. They do not reference forms, workflows, properties, or other content assets.

HubSpot’s v4 association API creates association labels as bidirectional pairs. A single API call to create a label between contacts and companies produces two results:

  1. Forward label — e.g., “Decision Maker” from contact to company
  2. Inverse label — e.g., “Decision Maker” from company to contact (the reverse direction)

JetStack AI expects this two-result response and maps both the forward and inverse association type IDs for use by other assets that reference associations.

Before creating a label, JetStack AI checks whether a label with the same name and type ID already exists on the target object pair. The check process:

  1. Fetch all existing association labels between the two object types
  2. Compare by label name and association type ID
  3. If a match is found, skip creation and use the existing label’s IDs

If the HubSpot API returns an “already exists” error during creation, JetStack AI treats this as a success with a warning rather than a failure. The existing label is looked up and its IDs are recorded for mapping purposes. This prevents deployment failures when re-deploying to a portal that already has some labels configured.

When an association label connects to a custom object type, the object type ID in the label definition is portal-specific. During deployment:

  1. The source portal’s custom object type ID is looked up in the deployment’s custom object mapping
  2. The ID is replaced with the target portal’s corresponding custom object type ID
  3. The label is created with the remapped type IDs

If the custom object type has not been deployed or mapped, the label deployment fails with a clear error message indicating which custom object type is missing.

Some association labels support a max limit — a cap on how many associations of that type can exist on a single record. For example, you might limit “Primary Contact” to 1 per company.

Max limit configuration uses a separate API endpoint from label creation. JetStack AI attempts to set the max limit after the label is created. If the max limit API call fails, this is treated as a warning only — the label itself is still successfully created without the limit constraint.

Not all association types support max limits. The API will reject the request for unsupported types, and JetStack AI handles this gracefully.

The v4 API response returns an array with two label objects. JetStack AI parses both and stores:

  • results[0] — The forward direction label with its type ID
  • results[1] — The inverse direction label with its type ID

If the API returns fewer than two results (which is unexpected), JetStack AI logs a warning and uses whatever results are available. The forward direction is always prioritized.

Some association labels connect an object type to itself (e.g., company-to-company for “Parent Company” / “Child Company” relationships). These work the same as cross-type associations from a deployment perspective, but the forward and inverse labels may have different names (e.g., “Parent” forward, “Child” inverse).

Deploying the same association labels to a portal that already has them results in no changes. The existence check catches duplicates, and the “already exists” handling ensures the deployment completes without errors. This makes association label deployment safely idempotent.

  • “Custom object type not found in mapping” — The association references a custom object that was not deployed or mapped. Deploy the custom object type first, then retry the association label deployment.
  • “Max limit configuration failed” — The association type does not support max limits, or the API returned an error. The label was still created successfully. Set the max limit manually in HubSpot if needed.
  • Duplicate labels after deploy — If labels appear duplicated, check whether both USER_DEFINED and HUBSPOT_DEFINED versions exist. The system-defined version cannot be removed. User-defined duplicates can be deleted in HubSpot.
  • Missing inverse label — The bidirectional creation should always produce both directions. If only one direction appears, check the deploy log for API response anomalies.