CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/airbyte-airbyte-source-hubspot

HubSpot source connector for Airbyte that syncs CRM data including contacts, companies, deals, and marketing activities with support for OAuth and Private App authentication

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

engagements.mddocs/

Engagement Streams

Activity and interaction data streams including calls, emails, meetings, notes, and tasks with associations to CRM entities for comprehensive activity tracking.

Capabilities

Engagements Calls

Call engagement records with call details and participant information.

engagements_calls:
  primary_key: ["id"]
  cursor_field: "updatedAt"
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique call engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Call creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "When the call occurred"
      type:
        type: string
        const: "CALL"
        description: "Engagement type"
      ownerId:
        type: string
        description: "Owner/creator of the call record"
      
      # Call-specific metadata
      metadata:
        type: object
        properties:
          toNumber:
            type: string
            description: "Phone number called"
          fromNumber:
            type: string
            description: "Phone number called from"
          status:
            type: string
            description: "Call status (COMPLETED, BUSY, NO_ANSWER, etc.)"
          duration:
            type: integer
            description: "Call duration in milliseconds"
          disposition:
            type: string
            description: "Call outcome/disposition"
          recordingUrl:
            type: string
            description: "URL to call recording if available"
      
      # Associated entities
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
            description: "Associated contact IDs"
          companyIds:
            type: array
            items:
              type: string
            description: "Associated company IDs"
          dealIds:
            type: array
            items:
              type: string
            description: "Associated deal IDs"

Engagements Emails

Email engagement records with email metadata and participant information.

engagements_emails:
  primary_key: ["id"]
  cursor_field: "updatedAt"  
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique email engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Email creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "When the email was sent"
      type:
        type: string
        const: "EMAIL"
        description: "Engagement type"
      ownerId:
        type: string
        description: "Owner/sender of the email"
      
      # Email-specific metadata
      metadata:
        type: object
        properties:
          subject:
            type: string
            description: "Email subject line"
          html:
            type: string
            description: "Email HTML content"
          text:
            type: string
            description: "Email plain text content"
          from:
            type: object
            properties:
              email:
                type: string
                format: email
              firstName:
                type: string
              lastName:
                type: string
          to:
            type: array
            items:
              type: object
              properties:
                email:
                  type: string
                  format: email
                firstName:
                  type: string
                lastName:
                  type: string
          cc:
            type: array
            items:
              type: object
              properties:
                email:
                  type: string
                  format: email
          bcc:
            type: array
            items:
              type: object
              properties:
                email:
                  type: string
                  format: email
      
      # Associated entities
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
            description: "Associated contact IDs"
          companyIds:
            type: array
            items:
              type: string
            description: "Associated company IDs"
          dealIds:
            type: array
            items:
              type: string
            description: "Associated deal IDs"

Engagements Meetings

Meeting engagement records with meeting details and attendee information.

engagements_meetings:
  primary_key: ["id"]
  cursor_field: "updatedAt"
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique meeting engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Meeting creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "Meeting start time"
      type:
        type: string
        const: "MEETING"
        description: "Engagement type"
      ownerId:
        type: string
        description: "Owner/organizer of the meeting"
      
      # Meeting-specific metadata
      metadata:
        type: object
        properties:
          title:
            type: string
            description: "Meeting title/subject"
          body:
            type: string
            description: "Meeting description/agenda"
          startTime:
            type: string
            format: date-time
            description: "Meeting start time"
          endTime:
            type: string
            format: date-time
            description: "Meeting end time"
          location:
            type: string
            description: "Meeting location"
          meetingUrl:
            type: string
            description: "Meeting URL for virtual meetings"
          source:
            type: string
            description: "Meeting source (INTEGRATION, CRM_UI, etc.)"
      
      # Associated entities
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
            description: "Associated contact IDs"
          companyIds:
            type: array
            items:
              type: string
            description: "Associated company IDs"
          dealIds:
            type: array
            items:
              type: string
            description: "Associated deal IDs"

Engagements Notes

Note engagement records with note content and entity associations.

engagements_notes:
  primary_key: ["id"]
  cursor_field: "updatedAt"
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique note engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Note creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "When the note was created"
      type:
        type: string
        const: "NOTE"
        description: "Engagement type"
      ownerId:
        type: string
        description: "Owner/author of the note"
      
      # Note-specific metadata
      metadata:
        type: object
        properties:
          body:
            type: string
            description: "Note content/text"
          
      # Associated entities
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
            description: "Associated contact IDs"
          companyIds:
            type: array
            items:
              type: string
            description: "Associated company IDs"
          dealIds:
            type: array
            items:
              type: string
            description: "Associated deal IDs"

Engagements Tasks

Task engagement records with task details and completion status.

engagements_tasks:
  primary_key: ["id"]
  cursor_field: "updatedAt"
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique task engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Task creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "Task due date/timestamp"
      type:
        type: string
        const: "TASK"
        description: "Engagement type"
      ownerId:
        type: string
        description: "Owner/assignee of the task"
      
      # Task-specific metadata
      metadata:
        type: object
        properties:
          subject:
            type: string
            description: "Task title/subject"
          body:
            type: string
            description: "Task description"
          status:
            type: string
            description: "Task status (NOT_STARTED, IN_PROGRESS, COMPLETED, etc.)"
          forObjectType:
            type: string
            description: "Object type task is for (CONTACT, COMPANY, DEAL)"
          priority:
            type: string
            description: "Task priority level"
          taskType:
            type: string
            description: "Type of task (TODO, CALL, EMAIL, etc.)"
          reminders:
            type: array
            items:
              type: object
              properties:
                reminderTime:
                  type: string
                  format: date-time
      
      # Associated entities  
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
            description: "Associated contact IDs"
          companyIds:
            type: array
            items:
              type: string
            description: "Associated company IDs"
          dealIds:
            type: array
            items:
              type: string
            description: "Associated deal IDs"

Legacy Engagements Stream

Unified engagement stream containing all engagement types (legacy stream for backward compatibility).

engagements:
  primary_key: ["id"]
  cursor_field: "updatedAt"
  sync_mode: incremental
  schema:
    type: object
    properties:
      id:
        type: string
        description: "Unique engagement identifier"
      createdAt:
        type: string
        format: date-time
        description: "Engagement creation timestamp"
      updatedAt:
        type: string
        format: date-time
        description: "Last update timestamp"
      timestamp:
        type: string
        format: date-time
        description: "When the engagement occurred"
      type:
        type: string
        enum: ["CALL", "EMAIL", "MEETING", "NOTE", "TASK"]
        description: "Type of engagement"
      ownerId:
        type: string
        description: "Owner of the engagement"
      metadata:
        type: object
        description: "Type-specific engagement metadata"
        additionalProperties: true
      associations:
        type: object
        properties:
          contactIds:
            type: array
            items:
              type: string
          companyIds:
            type: array
            items:
              type: string
          dealIds:
            type: array
            items:
              type: string

Engagement API Strategy

The connector uses an intelligent API selection strategy for the engagements stream:

Recent vs All Engagements API

EngagementsHttpRequester:
  type: HttpRequester
  
  # API Selection Logic:
  recent_api:
    path: "/engagements/v1/engagements/recent/modified"
    conditions:
      - start_time within last 29 days
      - total records <= 10,000
    benefits:
      - Faster response times
      - More recent data
      
  all_api:
    path: "/engagements/v1/engagements/paged"
    conditions:
      - start_time older than 29 days
      - total records > 10,000
    benefits:
      - Complete historical data
      - No record limits
      - Client-side filtering support

API Selection Process

  1. Check Date Range: If start_time is within last 29 days, consider Recent API
  2. Check Record Count: Make test request to Recent API to check total count
  3. Select API: Use Recent API if ≤10k records, otherwise use All API
  4. Apply Filtering: All API uses client-side incremental filtering

Association Processing

Engagement streams automatically populate association arrays by:

  1. Extract Associations: Parse engagement associations from API response
  2. Flatten Structure: Convert nested association objects to ID arrays
  3. Include Entity Types: Separate arrays for contacts, companies, deals

Example Association Structure:

{
  "id": "12345",
  "type": "CALL", 
  "associations": {
    "contactIds": ["101", "102"],
    "companyIds": ["201"],
    "dealIds": ["301", "302", "303"]
  }
}

Usage Patterns

Activity Timeline Analysis:

SELECT type, COUNT(*) as count, DATE(timestamp) as date
FROM engagements_calls
WHERE timestamp >= '2024-01-01'
GROUP BY type, DATE(timestamp)
ORDER BY date DESC;

Owner Activity Tracking:

SELECT 
  ownerId,
  COUNT(*) as total_activities,
  COUNT(CASE WHEN type = 'CALL' THEN 1 END) as calls,
  COUNT(CASE WHEN type = 'EMAIL' THEN 1 END) as emails,
  COUNT(CASE WHEN type = 'MEETING' THEN 1 END) as meetings
FROM engagements
WHERE createdAt >= '2024-01-01'
GROUP BY ownerId;

Install with Tessl CLI

npx tessl i tessl/airbyte-airbyte-source-hubspot@6.0.1

docs

additional-streams.md

authentication.md

crm-streams.md

custom-objects.md

engagements.md

index.md

marketing.md

property-history.md

tile.json