or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

additional-streams.mdauthentication.mdcrm-streams.mdcustom-objects.mdengagements.mdindex.mdmarketing.mdproperty-history.md

marketing.mddocs/

0

# Marketing Streams

1

2

Marketing automation and communication data streams including campaigns, emails, forms, workflows, and email events for comprehensive marketing analytics and campaign tracking.

3

4

## Capabilities

5

6

### Marketing Emails

7

8

Marketing email campaigns with statistics and performance metrics using HubSpot's v3 API.

9

10

```yaml { .api }

11

marketing_emails:

12

primary_key: ["id"]

13

cursor_field: "updatedAt"

14

sync_mode: incremental

15

schema:

16

type: object

17

properties:

18

id:

19

type: string

20

description: "Unique marketing email identifier"

21

name:

22

type: string

23

description: "Email campaign name"

24

subject:

25

type: string

26

description: "Email subject line"

27

createdAt:

28

type: string

29

format: date-time

30

description: "Email creation timestamp"

31

updatedAt:

32

type: string

33

format: date-time

34

description: "Last update timestamp"

35

publishedAt:

36

type: string

37

format: date-time

38

description: "Email publish timestamp"

39

state:

40

type: string

41

enum: ["DRAFT", "PUBLISHED", "SCHEDULED"]

42

description: "Email campaign state"

43

44

# Email content and settings

45

type:

46

type: string

47

description: "Email type (REGULAR, A_B_TEST, etc.)"

48

contentTypeCategory:

49

type: string

50

description: "Content category"

51

htmlTitle:

52

type: string

53

description: "HTML title"

54

previewText:

55

type: string

56

description: "Email preview text"

57

fromEmail:

58

type: string

59

format: email

60

description: "Sender email address"

61

replyTo:

62

type: string

63

format: email

64

description: "Reply-to email address"

65

66

# Statistics (merged from v3 statistics endpoint)

67

counters:

68

type: object

69

properties:

70

sent:

71

type: integer

72

description: "Number of emails sent"

73

delivered:

74

type: integer

75

description: "Number of emails delivered"

76

opens:

77

type: integer

78

description: "Number of email opens"

79

clicks:

80

type: integer

81

description: "Number of email clicks"

82

forwards:

83

type: integer

84

description: "Number of email forwards"

85

unsubscribes:

86

type: integer

87

description: "Number of unsubscribes"

88

bounces:

89

type: integer

90

description: "Number of bounces"

91

spamreports:

92

type: integer

93

description: "Number of spam reports"

94

95

# Calculated rates

96

openRate:

97

type: number

98

description: "Email open rate percentage"

99

clickRate:

100

type: number

101

description: "Email click rate percentage"

102

deliveryRate:

103

type: number

104

description: "Email delivery rate percentage"

105

```

106

107

**Usage Example:**

108

109

```yaml

110

streams:

111

- name: marketing_emails

112

sync_mode: incremental

113

cursor_field: ["updatedAt"]

114

destination_sync_mode: append_dedup

115

```

116

117

### Campaigns

118

119

Campaign records with performance statistics and metadata.

120

121

```yaml { .api }

122

campaigns:

123

primary_key: ["id"]

124

cursor_field: "lastUpdatedTime"

125

sync_mode: incremental

126

schema:

127

type: object

128

properties:

129

id:

130

type: string

131

description: "Unique campaign identifier"

132

name:

133

type: string

134

description: "Campaign name"

135

subject:

136

type: string

137

description: "Campaign subject line"

138

appId:

139

type: integer

140

description: "Application ID"

141

appName:

142

type: string

143

description: "Application name"

144

createdAt:

145

type: string

146

format: date-time

147

description: "Campaign creation timestamp"

148

lastUpdatedTime:

149

type: string

150

format: date-time

151

description: "Last update timestamp"

152

type:

153

type: string

154

description: "Campaign type"

155

156

# Campaign statistics

157

counters:

158

type: object

159

properties:

160

sent:

161

type: integer

162

description: "Total emails sent"

163

delivered:

164

type: integer

165

description: "Total emails delivered"

166

opens:

167

type: integer

168

description: "Total email opens"

169

clicks:

170

type: integer

171

description: "Total email clicks"

172

processed:

173

type: integer

174

description: "Total emails processed"

175

dropped:

176

type: integer

177

description: "Total emails dropped"

178

bounces:

179

type: integer

180

description: "Total bounces"

181

deferred:

182

type: integer

183

description: "Total deferred sends"

184

```

185

186

### Email Events

187

188

Individual email interaction events including opens, clicks, bounces, and deliveries.

189

190

```yaml { .api }

191

email_events:

192

primary_key: ["id"]

193

cursor_field: "created"

194

sync_mode: incremental

195

schema:

196

type: object

197

properties:

198

id:

199

type: string

200

description: "Unique email event identifier"

201

created:

202

type: string

203

format: date-time

204

description: "Event timestamp"

205

emailCampaignId:

206

type: string

207

description: "Associated email campaign ID"

208

recipient:

209

type: string

210

format: email

211

description: "Recipient email address"

212

type:

213

type: string

214

enum: [

215

"DELIVERED", "SENT", "DROPPED", "DEFERRED",

216

"BOUNCE", "OPEN", "CLICK", "PRINT", "FORWARD",

217

"SPAMREPORT", "UNSUBSCRIBE", "SUPPRESSED"

218

]

219

description: "Type of email event"

220

221

# Event-specific details

222

portalId:

223

type: integer

224

description: "HubSpot portal ID"

225

appId:

226

type: integer

227

description: "Application ID"

228

sentBy:

229

type: object

230

properties:

231

id:

232

type: string

233

created:

234

type: string

235

format: date-time

236

237

# Event metadata (varies by event type)

238

url:

239

type: string

240

description: "Clicked URL (for CLICK events)"

241

response:

242

type: string

243

description: "Bounce reason (for BOUNCE events)"

244

attemptNumber:

245

type: integer

246

description: "Delivery attempt number"

247

248

# Associated contact information

249

filteredContactId:

250

type: string

251

description: "Associated contact ID"

252

filteredContactVid:

253

type: string

254

description: "Associated contact VID"

255

```

256

257

### Forms

258

259

Form definitions and configurations for lead capture and data collection.

260

261

```yaml { .api }

262

forms:

263

primary_key: ["id"]

264

cursor_field: "updatedAt"

265

sync_mode: incremental

266

schema:

267

type: object

268

properties:

269

id:

270

type: string

271

description: "Unique form identifier"

272

name:

273

type: string

274

description: "Form name"

275

createdAt:

276

type: string

277

format: date-time

278

description: "Form creation timestamp"

279

updatedAt:

280

type: string

281

format: date-time

282

description: "Last update timestamp"

283

cssClass:

284

type: string

285

description: "CSS class for form styling"

286

redirect:

287

type: string

288

description: "Redirect URL after form submission"

289

submitText:

290

type: string

291

description: "Submit button text"

292

followUpId:

293

type: string

294

description: "Follow-up email ID"

295

notifyRecipients:

296

type: string

297

description: "Notification recipients"

298

299

# Form fields configuration

300

formFieldGroups:

301

type: array

302

items:

303

type: object

304

properties:

305

fields:

306

type: array

307

items:

308

type: object

309

properties:

310

name:

311

type: string

312

description: "Field name"

313

label:

314

type: string

315

description: "Field label"

316

type:

317

type: string

318

description: "Field type"

319

fieldType:

320

type: string

321

description: "Specific field type"

322

required:

323

type: boolean

324

description: "Whether field is required"

325

hidden:

326

type: boolean

327

description: "Whether field is hidden"

328

defaultValue:

329

type: string

330

description: "Default field value"

331

options:

332

type: array

333

items:

334

type: object

335

properties:

336

label:

337

type: string

338

value:

339

type: string

340

description: "Field options for select/radio fields"

341

342

# Form performance metrics

343

performanceData:

344

type: object

345

properties:

346

views:

347

type: integer

348

description: "Form view count"

349

submissions:

350

type: integer

351

description: "Form submission count"

352

conversionRate:

353

type: number

354

description: "Form conversion rate"

355

```

356

357

### Form Submissions

358

359

Individual form submission records with submitted data and contact associations.

360

361

```yaml { .api }

362

form_submissions:

363

primary_key: ["id"]

364

cursor_field: "submittedAt"

365

sync_mode: incremental

366

schema:

367

type: object

368

properties:

369

id:

370

type: string

371

description: "Unique form submission identifier"

372

formId:

373

type: string

374

description: "Associated form ID"

375

portalId:

376

type: integer

377

description: "HubSpot portal ID"

378

submittedAt:

379

type: string

380

format: date-time

381

description: "Submission timestamp"

382

contactId:

383

type: string

384

description: "Associated contact ID"

385

386

# Submission metadata

387

pageUrl:

388

type: string

389

description: "Page where form was submitted"

390

pageTitle:

391

type: string

392

description: "Page title"

393

userAgent:

394

type: string

395

description: "User agent string"

396

ipAddress:

397

type: string

398

description: "Submitter IP address"

399

400

# Submitted form values

401

values:

402

type: array

403

items:

404

type: object

405

properties:

406

name:

407

type: string

408

description: "Field name"

409

value:

410

type: string

411

description: "Submitted value"

412

objectTypeId:

413

type: string

414

description: "Object type ID"

415

description: "Array of submitted field values"

416

```

417

418

### Workflows

419

420

Marketing automation workflow definitions and configurations.

421

422

```yaml { .api }

423

workflows:

424

primary_key: ["id"]

425

cursor_field: "updatedAt"

426

sync_mode: incremental

427

schema:

428

type: object

429

properties:

430

id:

431

type: string

432

description: "Unique workflow identifier"

433

name:

434

type: string

435

description: "Workflow name"

436

type:

437

type: string

438

enum: ["DRIP_DELAY", "PROPERTY_ANCHOR", "DATE_ANCHOR"]

439

description: "Workflow type"

440

createdAt:

441

type: string

442

format: date-time

443

description: "Workflow creation timestamp"

444

updatedAt:

445

type: string

446

format: date-time

447

description: "Last update timestamp"

448

enabled:

449

type: boolean

450

description: "Whether workflow is active"

451

452

# Workflow enrollment criteria

453

onlyExecOnBizDays:

454

type: boolean

455

description: "Execute only on business days"

456

onlyExecuteOnBusinessDays:

457

type: boolean

458

description: "Execute only on business days (legacy)"

459

insertedAt:

460

type: string

461

format: date-time

462

description: "Workflow insertion timestamp"

463

464

# Workflow actions and triggers

465

actions:

466

type: array

467

items:

468

type: object

469

properties:

470

type:

471

type: string

472

description: "Action type"

473

delayMillis:

474

type: integer

475

description: "Delay in milliseconds"

476

actionId:

477

type: string

478

description: "Action identifier"

479

description: "Workflow actions"

480

481

# Performance metrics

482

contactListIds:

483

type: object

484

properties:

485

enrolled:

486

type: integer

487

description: "Number of contacts enrolled"

488

active:

489

type: integer

490

description: "Number of active contacts"

491

succeeded:

492

type: integer

493

description: "Number of successful completions"

494

```

495

496

### Email Subscriptions

497

498

Email subscription type definitions and preferences.

499

500

```yaml { .api }

501

email_subscriptions:

502

primary_key: ["id"]

503

sync_mode: full_refresh

504

schema:

505

type: object

506

properties:

507

id:

508

type: string

509

description: "Unique subscription type identifier"

510

name:

511

type: string

512

description: "Subscription type name"

513

description:

514

type: string

515

description: "Subscription description"

516

active:

517

type: boolean

518

description: "Whether subscription type is active"

519

createdAt:

520

type: string

521

format: date-time

522

description: "Creation timestamp"

523

updatedAt:

524

type: string

525

format: date-time

526

description: "Last update timestamp"

527

```

528

529

### Subscription Changes

530

531

Timeline of email subscription changes for contacts.

532

533

```yaml { .api }

534

subscription_changes:

535

primary_key: ["timestamp", "portalId", "recipient", "subscriptionId"]

536

cursor_field: "timestamp"

537

sync_mode: incremental

538

schema:

539

type: object

540

properties:

541

timestamp:

542

type: string

543

format: date-time

544

description: "Change timestamp"

545

portalId:

546

type: integer

547

description: "HubSpot portal ID"

548

recipient:

549

type: string

550

format: email

551

description: "Contact email address"

552

subscriptionId:

553

type: string

554

description: "Subscription type ID"

555

change:

556

type: string

557

enum: ["SUBSCRIBED", "UNSUBSCRIBED", "NOT_OPTED_IN"]

558

description: "Type of subscription change"

559

source:

560

type: string

561

description: "Source of the change"

562

causedByEvent:

563

type: object

564

properties:

565

id:

566

type: string

567

created:

568

type: string

569

format: date-time

570

description: "Event that caused the change"

571

```

572

573

### Contact Lists

574

575

Contact list definitions and configurations.

576

577

```yaml { .api }

578

contact_lists:

579

primary_key: ["id"]

580

cursor_field: "updatedAt"

581

sync_mode: incremental

582

schema:

583

type: object

584

properties:

585

id:

586

type: string

587

description: "Unique contact list identifier"

588

name:

589

type: string

590

description: "List name"

591

createdAt:

592

type: string

593

format: date-time

594

description: "List creation timestamp"

595

updatedAt:

596

type: string

597

format: date-time

598

description: "Last update timestamp"

599

listType:

600

type: string

601

enum: ["STATIC", "DYNAMIC"]

602

description: "List type"

603

size:

604

type: integer

605

description: "Number of contacts in list"

606

607

# List filters (for dynamic lists)

608

filters:

609

type: array

610

items:

611

type: object

612

properties:

613

filterFamily:

614

type: string

615

property:

616

type: string

617

type:

618

type: string

619

operation:

620

type: object

621

description: "List filtering criteria"

622

```

623

624

## Marketing Email Statistics Integration

625

626

The marketing_emails stream uses a specialized transformation to merge statistics:

627

628

### Statistics Transformation

629

630

```yaml { .api }

631

MarketingEmailStatisticsTransformation:

632

type: RecordTransformation

633

634

# Transformation process:

635

# 1. For each marketing email record

636

# 2. Make request to /marketing/v3/emails/{emailId}/statistics

637

# 3. Merge statistics data into email record

638

# 4. Handle missing statistics gracefully with warning logs

639

640

error_handling:

641

- Log warnings for missing statistics

642

- Continue processing without failing sync

643

- Preserve original email data if statistics unavailable

644

```

645

646

### Statistics Endpoint Integration

647

648

The connector automatically fetches statistics for each marketing email by:

649

650

1. **Extract Email IDs**: From main marketing emails response

651

2. **Parallel Requests**: To statistics endpoint for each email

652

3. **Merge Data**: Statistics merged into email records

653

4. **Error Handling**: Missing statistics logged but don't fail sync

654

655

## Usage Patterns

656

657

**Campaign Performance Analysis:**

658

```sql

659

SELECT

660

name,

661

counters.sent,

662

counters.opens,

663

counters.clicks,

664

ROUND((counters.opens::float / counters.sent) * 100, 2) as open_rate,

665

ROUND((counters.clicks::float / counters.sent) * 100, 2) as click_rate

666

FROM marketing_emails

667

WHERE state = 'PUBLISHED'

668

ORDER BY counters.sent DESC;

669

```

670

671

**Email Event Analysis:**

672

```sql

673

SELECT

674

type,

675

COUNT(*) as event_count,

676

DATE(created) as event_date

677

FROM email_events

678

WHERE created >= '2024-01-01'

679

GROUP BY type, DATE(created)

680

ORDER BY event_date DESC, event_count DESC;

681

```

682

683

**Form Conversion Tracking:**

684

```sql

685

SELECT

686

f.name as form_name,

687

COUNT(fs.id) as submissions,

688

f.performanceData.views as views,

689

ROUND((COUNT(fs.id)::float / f.performanceData.views) * 100, 2) as conversion_rate

690

FROM forms f

691

LEFT JOIN form_submissions fs ON f.id = fs.formId

692

WHERE f.updatedAt >= '2024-01-01'

693

GROUP BY f.id, f.name, f.performanceData.views

694

ORDER BY submissions DESC;

695

```