or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-client.mdbase-stream-classes.mdcrm-streams.mdcustom-objects.mdengagement-streams.mderror-handling.mdindex.mdmarketing-sales-streams.mdproperty-history-streams.mdsource-connector.mdweb-analytics.md

marketing-sales-streams.mddocs/

0

# Marketing & Sales Streams

1

2

Stream classes for marketing and sales data including forms, form submissions, owners, and products. These streams provide access to HubSpot's marketing automation and sales enablement features.

3

4

## Capabilities

5

6

### Form Streams

7

8

Access to HubSpot form definitions and form submission data.

9

10

```python { .api }

11

class Forms(ClientSideIncrementalStream):

12

"""

13

Stream for HubSpot form definitions.

14

15

Provides access to form data including:

16

- Form configuration and fields

17

- Form settings and styling

18

- Form submission settings

19

- Form performance metadata

20

- Custom form properties

21

"""

22

23

class FormSubmissions(ClientSideIncrementalStream):

24

"""

25

Stream for HubSpot form submission records.

26

27

Provides access to form submission data including:

28

- Submitted form field values

29

- Submission timestamp and source

30

- Contact information from submission

31

- Form conversion tracking

32

- Page context and referrer information

33

"""

34

```

35

36

### Owner Streams

37

38

Access to HubSpot user and owner information for sales team management.

39

40

```python { .api }

41

class Owners(ClientSideIncrementalStream):

42

"""

43

Stream for HubSpot owner (user) records.

44

45

Provides access to owner data including:

46

- User profile information

47

- Owner permissions and roles

48

- Team assignments

49

- Owner activity status

50

- Custom owner properties

51

"""

52

53

class OwnersArchived(ClientSideIncrementalStream):

54

"""

55

Stream for archived HubSpot owner records.

56

57

Provides access to deactivated or archived

58

owner accounts with historical data.

59

"""

60

```

61

62

### Product & E-commerce Streams

63

64

Access to product catalog and line item data for e-commerce integration.

65

66

```python { .api }

67

class Products(CRMObjectIncrementalStream):

68

"""

69

Stream for HubSpot product records.

70

71

Provides access to product data including:

72

- Product name, description, and SKU

73

- Pricing and cost information

74

- Product categories and properties

75

- Inventory tracking data

76

- Custom product properties

77

"""

78

79

class LineItems(CRMObjectIncrementalStream):

80

"""

81

Stream for HubSpot line item records.

82

83

Provides access to line item data including:

84

- Product associations and quantities

85

- Pricing and discount information

86

- Line item properties

87

- Deal and quote associations

88

- Custom line item properties

89

"""

90

```

91

92

### Goal Streams

93

94

Access to HubSpot goal and performance tracking data.

95

96

```python { .api }

97

class Goals(CRMObjectIncrementalStream):

98

"""

99

Stream for HubSpot goal records.

100

101

Provides access to goal data including:

102

- Goal definitions and targets

103

- Goal progress tracking

104

- Goal assignment and ownership

105

- Performance metrics

106

- Custom goal properties

107

"""

108

```

109

110

### Feedback Streams

111

112

Access to customer feedback and survey response data.

113

114

```python { .api }

115

class FeedbackSubmissions(CRMObjectIncrementalStream):

116

"""

117

Stream for HubSpot feedback submission records.

118

119

Provides access to feedback data including:

120

- Survey responses and ratings

121

- Feedback content and comments

122

- Customer satisfaction scores

123

- Feedback categorization

124

- Custom feedback properties

125

"""

126

```

127

128

## Usage Examples

129

130

### Form Performance Analysis

131

132

```python

133

from source_hubspot.streams import Forms, FormSubmissions, API

134

135

api = API(credentials)

136

137

# Get form definitions

138

forms = Forms(

139

api=api,

140

start_date="2023-01-01T00:00:00Z",

141

credentials=credentials

142

)

143

144

# Get form submissions

145

submissions = FormSubmissions(

146

api=api,

147

start_date="2023-01-01T00:00:00Z",

148

credentials=credentials

149

)

150

151

# Analyze form performance

152

form_performance = {}

153

154

# First, get all forms

155

for form_record in forms.read_records(sync_mode="full_refresh"):

156

form_id = form_record['guid']

157

form_name = form_record['name']

158

form_performance[form_id] = {

159

'name': form_name,

160

'submissions': 0,

161

'unique_contacts': set()

162

}

163

164

# Count submissions per form

165

for submission_record in submissions.read_records(sync_mode="full_refresh"):

166

form_guid = submission_record['formId']

167

contact_email = None

168

169

# Extract email from form values

170

for value in submission_record.get('values', []):

171

if value.get('name') == 'email':

172

contact_email = value.get('value')

173

break

174

175

if form_guid in form_performance:

176

form_performance[form_guid]['submissions'] += 1

177

if contact_email:

178

form_performance[form_guid]['unique_contacts'].add(contact_email)

179

180

# Display results

181

for form_id, data in form_performance.items():

182

unique_count = len(data['unique_contacts'])

183

conversion_rate = (unique_count / data['submissions'] * 100) if data['submissions'] > 0 else 0

184

print(f"Form: {data['name']}")

185

print(f" Submissions: {data['submissions']}")

186

print(f" Unique contacts: {unique_count}")

187

print(f" Conversion rate: {conversion_rate:.1f}%")

188

```

189

190

### Sales Team Performance

191

192

```python

193

from source_hubspot.streams import Owners, Deals

194

195

# Get owner information

196

owners = Owners(

197

api=api,

198

start_date="2023-01-01T00:00:00Z",

199

credentials=credentials

200

)

201

202

# Build owner lookup

203

owner_lookup = {}

204

for owner_record in owners.read_records(sync_mode="full_refresh"):

205

owner_id = str(owner_record['ownerId'])

206

owner_lookup[owner_id] = {

207

'name': f"{owner_record.get('firstName', '')} {owner_record.get('lastName', '')}".strip(),

208

'email': owner_record.get('email', ''),

209

'deals_count': 0,

210

'deals_value': 0

211

}

212

213

# Analyze deals by owner

214

deals = Deals(

215

api=api,

216

start_date="2023-01-01T00:00:00Z",

217

credentials=credentials

218

)

219

220

for deal_record in deals.read_records(sync_mode="full_refresh"):

221

owner_id = deal_record['properties'].get('hubspot_owner_id')

222

deal_amount = float(deal_record['properties'].get('amount', 0) or 0)

223

224

if owner_id and owner_id in owner_lookup:

225

owner_lookup[owner_id]['deals_count'] += 1

226

owner_lookup[owner_id]['deals_value'] += deal_amount

227

228

# Display sales performance

229

print("Sales Team Performance:")

230

sorted_owners = sorted(owner_lookup.items(), key=lambda x: x[1]['deals_value'], reverse=True)

231

for owner_id, data in sorted_owners:

232

if data['deals_count'] > 0:

233

avg_deal_size = data['deals_value'] / data['deals_count']

234

print(f"{data['name']}: {data['deals_count']} deals, ${data['deals_value']:,.2f} total, ${avg_deal_size:,.2f} avg")

235

```

236

237

### Product Catalog Management

238

239

```python

240

from source_hubspot.streams import Products, LineItems

241

242

# Get product catalog

243

products = Products(

244

api=api,

245

start_date="2023-01-01T00:00:00Z",

246

credentials=credentials

247

)

248

249

product_catalog = {}

250

for product_record in products.read_records(sync_mode="full_refresh"):

251

product_id = product_record['id']

252

properties = product_record['properties']

253

254

product_catalog[product_id] = {

255

'name': properties.get('name', 'Unnamed Product'),

256

'price': float(properties.get('price', 0) or 0),

257

'sku': properties.get('sku', ''),

258

'sales_count': 0,

259

'revenue': 0

260

}

261

262

# Analyze line item sales

263

line_items = LineItems(

264

api=api,

265

start_date="2023-01-01T00:00:00Z",

266

credentials=credentials

267

)

268

269

for line_item_record in line_items.read_records(sync_mode="full_refresh"):

270

properties = line_item_record['properties']

271

product_id = properties.get('hs_product_id')

272

quantity = int(properties.get('quantity', 0) or 0)

273

price = float(properties.get('price', 0) or 0)

274

275

if product_id and product_id in product_catalog:

276

product_catalog[product_id]['sales_count'] += quantity

277

product_catalog[product_id]['revenue'] += (quantity * price)

278

279

# Display product performance

280

print("Product Performance:")

281

sorted_products = sorted(product_catalog.items(), key=lambda x: x[1]['revenue'], reverse=True)

282

for product_id, data in sorted_products[:10]: # Top 10 products

283

print(f"{data['name']} (SKU: {data['sku']})")

284

print(f" Units sold: {data['sales_count']}")

285

print(f" Revenue: ${data['revenue']:,.2f}")

286

print(f" Avg selling price: ${data['revenue'] / max(data['sales_count'], 1):,.2f}")

287

```

288

289

### Goal Tracking

290

291

```python

292

from source_hubspot.streams import Goals

293

294

goals = Goals(

295

api=api,

296

start_date="2023-01-01T00:00:00Z",

297

credentials=credentials

298

)

299

300

# Track goal progress

301

goal_progress = {}

302

for goal_record in goals.read_records(sync_mode="full_refresh"):

303

properties = goal_record['properties']

304

goal_name = properties.get('name', 'Unnamed Goal')

305

target_value = float(properties.get('target_value', 0) or 0)

306

current_value = float(properties.get('current_value', 0) or 0)

307

308

progress_percent = (current_value / target_value * 100) if target_value > 0 else 0

309

310

goal_progress[goal_name] = {

311

'target': target_value,

312

'current': current_value,

313

'progress': progress_percent,

314

'status': properties.get('status', 'Unknown')

315

}

316

317

print("Goal Progress:")

318

for goal_name, data in goal_progress.items():

319

status_indicator = "โœ…" if data['progress'] >= 100 else "๐Ÿ”„" if data['progress'] >= 50 else "โš ๏ธ"

320

print(f"{status_indicator} {goal_name}: {data['progress']:.1f}% ({data['current']}/{data['target']})")

321

```

322

323

### Customer Feedback Analysis

324

325

```python

326

from source_hubspot.streams import FeedbackSubmissions

327

328

feedback = FeedbackSubmissions(

329

api=api,

330

start_date="2023-01-01T00:00:00Z",

331

credentials=credentials

332

)

333

334

# Analyze feedback ratings

335

feedback_stats = {

336

'total_responses': 0,

337

'rating_distribution': {},

338

'average_rating': 0,

339

'total_rating': 0

340

}

341

342

for feedback_record in feedback.read_records(sync_mode="full_refresh"):

343

properties = feedback_record['properties']

344

rating = properties.get('rating')

345

346

if rating:

347

rating = float(rating)

348

feedback_stats['total_responses'] += 1

349

feedback_stats['total_rating'] += rating

350

351

rating_bucket = int(rating)

352

if rating_bucket not in feedback_stats['rating_distribution']:

353

feedback_stats['rating_distribution'][rating_bucket] = 0

354

feedback_stats['rating_distribution'][rating_bucket] += 1

355

356

if feedback_stats['total_responses'] > 0:

357

feedback_stats['average_rating'] = feedback_stats['total_rating'] / feedback_stats['total_responses']

358

359

print(f"Customer Feedback Summary:")

360

print(f"Total responses: {feedback_stats['total_responses']}")

361

print(f"Average rating: {feedback_stats['average_rating']:.2f}")

362

print("Rating distribution:")

363

for rating in sorted(feedback_stats['rating_distribution'].keys()):

364

count = feedback_stats['rating_distribution'][rating]

365

percentage = count / feedback_stats['total_responses'] * 100

366

print(f" {rating} stars: {count} ({percentage:.1f}%)")

367

```

368

369

## Stream Base Classes

370

371

### ClientSideIncrementalStream

372

373

Used by forms, owners, and other streams that implement client-side incremental logic.

374

375

```python { .api }

376

class ClientSideIncrementalStream(BaseStream, CheckpointMixin):

377

"""

378

Base class for streams with client-side incremental sync.

379

380

Handles state management and checkpointing for streams

381

that don't support server-side incremental queries.

382

"""

383

```

384

385

### CRMObjectIncrementalStream

386

387

Used by products, line items, goals, and feedback streams.

388

389

```python { .api }

390

class CRMObjectIncrementalStream(CRMObjectStream, IncrementalStream):

391

"""

392

Base class for CRM object streams with incremental sync.

393

394

Combines CRM object functionality with incremental

395

sync capabilities for optimal data synchronization.

396

"""

397

```

398

399

## OAuth Scopes

400

401

Marketing & sales streams require specific OAuth scopes:

402

403

- **Forms**: `forms`

404

- **Form Submissions**: `forms`

405

- **Owners**: `crm.objects.owners.read`

406

- **Products**: `e-commerce`

407

- **Line Items**: `e-commerce`, `crm.objects.line_items.read`

408

- **Goals**: `crm.objects.goals.read`

409

- **Feedback Submissions**: Custom object scopes may apply