Integrations

HubSpot: Telltide Seed Address Guide

Place Telltide seeds in HubSpot lists and workflows.

HubSpot's marketing contact model adds a layer beyond simple list membership: contacts must be designated as marketing contacts to receive workflow and campaign emails. Missing this setting is the most common reason seed contacts are created correctly but never receive anything. Check it first.

Quick reference

Send typeWhere to add seedsComplexity
Scheduled (Marketing Email)Add seed contact to any static or active segment selected as the email's recipient audienceLow
Ongoing (Workflow)Create seed contact, add to trigger segment or set trigger contact property, then manually enroll or let trigger fireMedium

> Terminology note: HubSpot rebranded "Lists" to "Segments" across the UI in 2025. The CRM API still exposes /crm/v3/lists/... for backward compatibility, so this guide uses "segment" for UI walkthroughs and "list" only when referring to API endpoints or the underlying object name.


1. Scheduled / one-off sends (Marketing Email)

HubSpot Marketing Emails are one-off sends (Regular type) sent to static or active segments. The seed must be a member of at least one segment included in the Recipients targeting.

Where to add seed addresses

Add the seed contact to any static segment that is selected (or can be selected) in the email's Recipients step. The simplest approach: maintain a dedicated "Telltide Seeds" static segment and include it in every marketing email's recipient audience.

Non-technical path

For CRM managers placing seeds without writing code.

Step-by-step: Create a seed contact

  1. Navigate to CRM > Contacts
  2. Click Create contact (upper right)
  3. Fill in: - Email (required, the seed inbox address) - First name, Last name (for personalization)
  4. If your account uses the marketing contacts model, check "Set this contact as a marketing contact" in the creation dialog (or set it immediately after via the contact record)
  5. Click Create contact

Step-by-step: Add seed contact to a static segment (bulk action)

  1. Navigate to CRM > Contacts
  2. Find the seed contact (use the search bar)
  3. Check the checkbox next to their name
  4. Click More in the top action bar > Add to static segment
  5. Select your "Telltide Seeds" segment (or the specific campaign target segment)
  6. Click Add

Limit: 100 records at a time via the UI bulk action.

Step-by-step: Add seed contact from the contact record

  1. Open the seed contact's record
  2. In the right panel, find the Segment memberships card
  3. Click Manage > Add to segment
  4. Select the static segment
  5. Save

CSV import

For seeding many addresses at once without API access:

  1. Navigate to CRM > Contacts
  2. Click Import (upper right) > Start an import > File from computer
  3. Upload a CSV with at minimum an Email column
  4. Map the columns to HubSpot contact properties
  5. On the final step, choose Add to static segment and select your "Telltide Seeds" segment so every imported row is added in one pass

Embedded form sign-up

The cleanest non-API way to make a seed marketable: submit a HubSpot form with the seed email. Most accounts auto-mark form-submitting contacts as marketing contacts.

  1. Navigate to Marketing > Forms and pick (or create) an internal-use form
  2. Open the public sharing link or the embedded form on a test page
  3. Submit the form using the seed email
  4. HubSpot creates or updates the contact and (in most account configurations) flips marketing contact status to true

Technical path

For developers placing seeds via the CRM v3 API.

Create a contact

POST https://api.hubapi.com/crm/v3/objects/contacts
Authorization: Bearer {{token}}
Content-Type: application/json

{
  "properties": {
    "email": "seed@example.com",
    "firstname": "Seed",
    "lastname": "Monitor"
  }
}

> hs_marketable_status and hs_marketable_reason_type are read-only HubSpot-managed properties. Sending a value is silently ignored. To make API-created seeds marketable, do one of the following: > - Set the account-level default at Settings > Marketing > Contacts to "Marketing" so new contacts inherit marketing status on create. > - Submit the seed via a HubSpot form (see Non-technical path above). > - Run a workflow with a "Set marketing contact status" action that flips the seed after creation.

Update contact by email

PATCH https://api.hubapi.com/crm/v3/objects/contacts/{email}?idProperty=email

Batch upsert contacts

POST https://api.hubapi.com/crm/v3/objects/contacts/batch/upsert

Batch upsert with idProperty: "email" works as long as each record puts the email as the top-level id field:

{
  "inputs": [
    {
      "idProperty": "email",
      "id": "seed@example.com",
      "properties": {
        "firstname": "Seed",
        "lastname": "Monitor"
      }
    }
  ]
}

Mixing legacy payload shapes (e.g., putting the email only inside properties) returns a "non-unique property email" error.

Add contact to a static list (v3 lists membership)

PUT https://api.hubapi.com/crm/v3/lists/{listId}/memberships/add
Content-Type: application/json

[123456]

The body is a JSON array of contact record IDs (integers). Retrieve a contact's record ID via GET /crm/v3/objects/contacts/{email}?idProperty=email.

Notes:

  • This endpoint only accepts writes against MANUAL or SNAPSHOT processing-type lists. Writes to DYNAMIC (active) lists are silently rejected because membership is determined by filter criteria.
  • Use the v3 list ID, not the legacy v1 list ID. The migration guide warns that mixing the two can update or delete the wrong list.

> The legacy v1 endpoint (PUT /contacts/v1/lists/{listId}/add with a {"vids":[...]} body) was sunset on 2026-04-30 and now returns 404. Use the v3 lists API above.

Authentication and minimum scopes

Use a Private App token (Bearer token) rather than legacy API keys. Navigate to Settings > Integrations > Private Apps to create a token. Concrete minimum scopes for the operations above:

  • crm.objects.contacts.read
  • crm.objects.contacts.write
  • crm.lists.read
  • crm.lists.write

Missing scopes return 403 with cryptic error messages.

Always-on flow coverage

Telltide only catches a send that didn't go out if the seed is actually in the recipient pool of every relevant Workflow and recurring marketing email. For HubSpot specifically:

  • Workflow enrollment triggers. For each Marketing Workflow, open the enrollment trigger and confirm the seed contact record satisfies it. If the trigger is "Contact is member of [active segment]", make sure the seed is a member of that segment (either by satisfying its filters, or by adding an OR clause to the active segment criteria such as Email is any of seed@yourdomain.com). If the trigger is a property-value condition (e.g., Lifecycle stage is Customer), set that property on the seed.
  • Active segment criteria with an OR seed clause. The most reliable pattern: add an OR clause to every trigger active segment that always matches your seed email. Active segment recompute can take up to 2 hours after a property change, so the OR-on-email clause is faster than relying on a property-based filter.
  • Marketing emails using a workflow's "send to" filter. When a Workflow action sends a marketing email and the email itself filters its recipient audience further (via the "Send to" Recipient settings), confirm the seed is in the source segment used by that filter. A seed enrolled in the workflow but excluded by the email's own segment filter will not receive the send.
  • Static segment as universal include. Maintain a "Telltide Seeds" static segment and add it as an additional include on every recurring blast and on every workflow-driven marketing email's Recipients step. This is the single most reliable belt-and-braces tactic.
  • Suppression and frequency exclusions. Even with the seed in every segment, HubSpot will skip the send if the seed is on the suppression list (hard-bounced, spam-reported, globally unsubscribed) or has hit the frequency safeguard. Audit the seed contact periodically and exempt critical sends from the frequency cap.
  • Marketing contact status. Confirm the seed is a marketing contact in accounts using the marketing contacts model. Non-marketing contacts are silently skipped from every workflow email and marketing send regardless of segment membership. Transactional emails (paid add-on) do not require marketing contact status, so seeds in transactional flows have different requirements.

Profile attributes required

Seeds need:

  • Email address (the seed inbox)
  • Marketing contact status set to Marketing contact (if your account uses this model)
  • First name if used in personalization tokens
  • Any other contact properties referenced in the email content via personalization tokens

Seeds added to a segment will be excluded from the send if:

  • They are globally unsubscribed from email
  • They are opted out of the subscription type used in that email
  • Your account's frequency safeguard has already sent them the maximum allowed emails in the configured period

Ensuring seeds receive the same version as real recipients

HubSpot supports A/B testing on full marketing emails (subject line, content, send time, from name, and more), not only subject lines. When A/B testing is on, seeds are randomly assigned to a variant. Ensure the seed is not in any exclusion segment for the send.

Gotchas

Marketing contacts model: If your HubSpot account uses marketing contacts, only contacts with marketing contact status receive marketing emails. When creating a seed contact, explicitly toggle it to "Marketing contact" status. Non-marketing contacts will be silently skipped even if they are on the target segment. The marketing contacts model must be opted into; older accounts may still be on the legacy "all contacts are marketable" model.

Subscription type opt-out: Every HubSpot marketing email must be assigned to a subscription type (e.g., "Marketing Information"). If the seed contact is opted out of that specific subscription type, they will not receive the email. Check the seed's subscription preferences:

  1. Open the contact record
  2. Click Email subscriptions in the sidebar
  3. Confirm the relevant subscription type is set to "Subscribed"

Transactional email exception: HubSpot's transactional email add-on does not require recipients to be marketing contacts. If you are seeding receipts, password resets, or other transactional flows, the marketing-contact requirement does not apply but other deliverability rules still do.

Email frequency safeguard: If your account has a frequency cap configured (Settings > Tools > Marketing > Email > Frequency safeguards), seeds may be excluded after hitting the cap. Exempt individual emails from the cap if needed. The frequency safeguard is a Marketing Hub Enterprise feature; it does not exist on lower tiers.

Active segment recompute delay: Active segments with complex filters can take up to 2 hours to recompute membership. Seeds added by changing a triggering property may not enter the recipient pool immediately. Adding an OR-on-email clause (see Always-on flow coverage) is faster.

Suppression list blocks manual enrollment: HubSpot refuses to manually enroll a contact who is on the email suppression list (hard-bounced, spam-reported, globally unsubscribed). This is a failure mode that does not surface for seeds whose inbox previously bounced.

GDPR mode: If GDPR functionality is enabled, a legal basis for processing may be required. Set the "Legal basis for processing contact's data" property on the seed contact. Recommended value: "Legitimate interest, Customer" (matches HubSpot's exact label).


2. Ongoing / automated journeys (Workflows)

HubSpot Workflows are the automation engine for triggered email sequences. The seed contact must satisfy the enrollment trigger and pass any contact property filters within the workflow.

Creating trap profiles

The seed contact must:

  1. Exist as a HubSpot contact (CRM record)
  2. Be a marketing contact (if the model is in use)
  3. Be subscribed to the subscription type used in the workflow's emails
  4. Either satisfy the enrollment trigger naturally, or be manually enrolled

Step-by-step: Create a workflow contact

Follow the contact creation steps in Section 1. After creation, set any contact properties the workflow needs (see journey-specific requirements below).

Enrollment trigger types

Trigger categoryExamplesSeed approach
Filter (property/criteria)Segment membership, lifecycle stage, contact property valueSet the qualifying property on the seed, or add seed to the trigger segment
Event (interaction)Form submitted, email opened, page viewed, custom behavioral eventSubmit the form, or manually enroll (events are harder to simulate)
ScheduleAnnual date, contact date propertySet the date property on the seed; wait for trigger, or manually enroll

Creating trap profiles per journey type

Welcome / onboarding

  • Trigger: Form submission, or "Contact is member of [segment]" filter trigger
  • Seed requirements: Email address, marketing contact status, subscription to the email type used
  • How to trigger:
  • Segment-based: Add seed contact to the trigger segment. The workflow will enroll them at the next evaluation (usually within minutes).
  • Form-based: Submit the form with the seed email address. HubSpot creates/updates the contact and triggers the enrollment.
  • Manual enrollment fallback: If the trigger is complex to simulate, manually enroll the seed directly from the workflow editor (see manual enrollment steps below)
  • Re-enrollment: Disable re-enrollment for welcome workflows (the default). Seeds only enter once.

Abandoned cart

  • Trigger: Cart object status or deal stage from your ecommerce integration. For the native HubSpot ecommerce integration: a Cart object with Status = "Abandoned Checkout" (cart-based flow) or a Checkout Abandoned deal stage on the Ecommerce Pipeline (deal-based flow).
  • Seed requirements: Email address, marketing contact status, the abandonment event fired against the contact
  • How to trigger: Depends entirely on your ecommerce integration. For the native HubSpot ecommerce integration, the event fires when an identified cart session is abandoned. Simulating this for a seed requires:
  • Adding the seed email to a checkout in your store and abandoning it, OR
  • Setting a custom contact property (e.g., abandoned_cart_date) via API and building the workflow trigger around that property instead
  • Workaround for non-native integrations: Create a custom contact property Abandoned Cart Date (Date picker type). Set this property on the seed contact to trigger a property-based enrollment. The workflow checks this property and sends the cart recovery email.
  • Event property data: For email personalization (product names, cart total), either pass event properties through the integration or use separate contact properties populated by your backend

Winback / re-engagement

  • Trigger: Filter enrollment based on a date property (e.g., "Last Purchase Date is more than 90 days ago")
  • Seed requirements: Email address, marketing contact status, Last Purchase Date custom contact property (Date picker type) set to a date older than the trigger threshold
  • How to set up: Create a custom Date picker contact property called Last Purchase Date: 1. Navigate to Settings (gear icon) > Data Management > Properties, choose Contact properties from the Object dropdown, then click Create property 2. Set Object type: Contact, Field type: Date picker 3. Name: Last Purchase Date
  • How to trigger: Set the seed's Last Purchase Date to a date 91+ days in the past, then add the filter enrollment trigger: "Last Purchase Date is more than 90 days ago"
  • Re-enrollment: Enable re-enrollment so the contact can re-enter after their next purchase is recorded

Important limitation: HubSpot has no default contact property for last purchase date. You must create this custom property. If your ecommerce integration does not populate it automatically, update it via the Contacts API.

Post-purchase

  • Trigger: Deal stage change to "Closed Won" (deal-based workflow) or ecommerce integration order event
  • Seed requirements: Email address, marketing contact status; for deal-based triggers, the contact needs an associated deal record in "Closed Won" stage
  • For deal-based workflow: 1. Create a test deal associated with the seed contact 2. Set the deal stage to "Closed Won" 3. The deal-based workflow fires and can set a contact property or send an email directly
  • For native ecommerce integrations: The integration fires an order event when a purchase is completed. Add the seed email to a test order in your store.

Birthday / anniversary

  • Trigger: "Based on a schedule" enrollment trigger, running annually, combined with a "Delay until date" action set to the contact's birthday property
  • Seed requirements: Email address, marketing contact status, a custom Date picker contact property (e.g., Birthdate)

Critical: HubSpot's default "Date of birth" property is a single-line text field and cannot be used for date-based workflow logic. You must create a custom Date picker property.

Workflow setup (post-July 2024):

  1. Create a new Contact-based workflow
  2. Set enrollment trigger: "Based on a schedule" > "Annually" > select the month/day you want to test
  3. Add enrollment filter: "Birthdate is known"
  4. Add action: Delay until date > select your Birthdate property > "On this date"
  5. Add action: Send marketing email (birthday email)

For seed testing:

  1. Set the seed's Birthdate property to today's date
  2. Create the "Based on schedule" trigger for today's date
  3. Manually enroll the seed contact into the workflow

Manually enrolling seed contacts in workflows

Use manual enrollment to bypass trigger conditions when simulating them is impractical.

Manual enrollment requires Super Admin or "View and Edit workflow" permissions.

From the workflow editor:

  1. Navigate to Automation > Workflows
  2. Open the target workflow
  3. Click Enroll (top right of the workflow editor)
  4. Search for and select the seed contact
  5. Confirm enrollment

From the Contacts index:

  1. Navigate to CRM > Contacts
  2. Check the seed contact
  3. In the bulk action bar, click More > Enroll in workflow (single-contact rows expose the same action via row-level actions)
  4. Select the workflow > click Enroll

From the contact record:

  1. Open the seed contact record
  2. Find Workflow memberships in the right panel
  3. Click Manage > Enroll in workflow > select workflow > confirm

Manually enrolled contacts always start from the beginning of the workflow (step 1). They cannot be enrolled mid-workflow.

Manually unenrolling seed contacts

  1. Navigate to Automation > Workflows > hover the workflow > More > View details
  2. Click the Enrollment history tab
  3. Use the Choose contact dropdown to find the seed record
  4. Hover the event > click Unenroll
  5. Confirm

The unenroll option only appears if the contact is currently active in the workflow.

Re-enrollment settings

By default, HubSpot workflows only enroll a contact once. To allow re-testing:

  1. Open the workflow editor
  2. Click Edit enrollment trigger
  3. Click the Settings tab
  4. Check "Allow contacts who meet the enrollment triggers to re-enroll when any one of the following occurs"
  5. Select the re-enrollment trigger condition

Note: A contact cannot be enrolled twice simultaneously. If the seed is already active in the workflow, it will not re-enroll until the current enrollment completes.


3. Platform-specific considerations

API options

The full API walkthrough (create contact, update by email, batch upsert with idProperty: "email", add to static list via v3 lists membership, authentication, and minimum scopes) is in Section 1 under Technical path. Key notes that apply across the guide:

  • The legacy v1 lists endpoint (PUT /contacts/v1/lists/{listId}/add) was sunset on 2026-04-30 and now returns 404. Use PUT /crm/v3/lists/{listId}/memberships/add with a JSON array of record IDs.
  • hs_marketable_status is read-only via the API. Set marketing contact status by configuring the account-level default at Settings > Marketing > Contacts, by submitting the seed via a HubSpot form, or by running a workflow action that flips marketing contact status.
  • v3 lists membership writes only succeed against MANUAL or SNAPSHOT lists. Active (DYNAMIC) lists are filter-managed and reject writes silently.
  • Use the v3 list ID, not the legacy v1 list ID. Mixing them can update or delete the wrong list.

Rate limits and sending caps

OperationLimit
API requests (general, per private app)110 requests per 10 seconds
API requests (daily, per private app, Free / Starter)250,000 per day
API requests (daily, per private app, Professional)650,000 per day
API requests (daily, per private app, Enterprise)1,000,000 per day
API requests (daily, public / OAuth apps)No daily cap (per-account 110/10s rate limit still applies)
Contacts index: Add to static segment100 contacts at a time via UI

Email frequency safeguard: Configurable at Settings > Tools > Marketing > Email > Frequency safeguards (Marketing Hub Enterprise only). Affects all marketing and workflow emails. Exempt individual emails from the cap in the email's Send settings.

Marketing Hub tier gating

The following capabilities used elsewhere in this guide require specific tiers:

  • Marketing Workflows: Marketing Hub Professional or higher (Operations Hub Professional unlocks the Workflows tool generally)
  • Frequency safeguard: Marketing Hub Enterprise
  • A/B testing for marketing emails: Marketing Hub Professional or higher
  • Marketing contacts model: Must be opted into; older accounts may still be on the legacy "all contacts are marketable" model

Duplicate contact handling

HubSpot uses email address as the primary unique identifier. If you create a contact with an email that already exists:

  • Via UI: HubSpot blocks the creation and shows the existing contact
  • Via API: Returns the existing contact's record

A single contact record can have additional email addresses stored in the built-in additional-emails feature; values inside that feature are deduplicated against the primary Email property as well, so the same address cannot live as a primary on one contact and an additional on another. Custom Email 2 / Email 3 properties are NOT deduplicated.

HubSpot's deduplication tool (Settings > Data Management > Duplicates) identifies suspected duplicate pairs for manual review. Auto-merge can be enabled for automatically merging matched records.

Platform-specific terminology

HubSpot termWhat it means
Marketing contactA contact with marketing contact status = true. Required to receive marketing/workflow emails in accounts using the marketing contacts model.
Active segment (formerly active list)A dynamic segment that updates automatically based on filter criteria. The CRM API still exposes these as lists with processingType: DYNAMIC.
Static segment (formerly static list)A manually managed segment where membership only changes when you explicitly add or remove contacts. API processing types: MANUAL or SNAPSHOT.
WorkflowHubSpot's automation engine; handles triggered email sequences.
Enrollment triggerThe condition that causes a contact to enter a workflow.
Subscription typeA category for email communications. Contacts can be opted in or out of each type independently.
Transactional emailA separate paid add-on for receipts, password resets, and other non-marketing sends. Recipients do NOT need to be marketing contacts.
Send frequency safeguardAn account-level cap on how many marketing emails a contact can receive within a configurable time window. Marketing Hub Enterprise only.
VIDHubSpot's internal numeric contact ID. Used in legacy v1 API list operations.
Private AppHubSpot's recommended authentication method for API access; generates a Bearer token with scoped permissions.

Known limitations and workarounds

Date-based triggers changed in July 2024: The legacy "Specific date" and "Contact date property" workflow types were discontinued. Use the "Based on a schedule" enrollment trigger with a "Delay until date" action for birthday/anniversary campaigns.

Abandoned cart requires an active ecommerce integration: HubSpot does not have a generic "abandoned cart" event; it depends on your specific integration to fire the event. If the integration is not in place, simulate via a custom contact property and a property-based workflow trigger.

Manual enrollment does not fire enrollment trigger: Manually enrolling a contact bypasses the enrollment trigger conditions and starts them at step 1. This is the correct behavior for seed testing when trigger simulation is impractical.

Contacts cannot be enrolled in a workflow twice simultaneously: If a seed is already active in a workflow, attempting to manually enroll them again does nothing. Unenroll them first, then re-enroll.

Manual enrollment respects the suppression list: HubSpot will refuse to manually enroll a contact who is on the email suppression list (hard-bounced, spam-reported, globally unsubscribed). This is a failure mode that does not surface for seeds whose inbox previously bounced.

Active segment recompute can lag up to 2 hours: Seeds added by changing a triggering property may not enter the recipient pool immediately. Add an OR-on-email clause to the active segment's filters for instant inclusion.

Marketing email sends require a published email: You cannot send a draft email to a seed via a workflow. The email used in a workflow action must be an approved, published HubSpot Marketing Email.

Start monitoring your HubSpot sends

Place a Telltide seed in your HubSpot audience, and we will tell you when an expected email did not land.

Start free