or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

connections.mdindex.mdmemories.mdsearch.mdsettings.md

connections.mddocs/

0

# Connection Management

1

2

Third-party service integrations for automated content synchronization and document importing from Notion, Google Drive, and OneDrive platforms.

3

4

## Capabilities

5

6

### Create Connection

7

8

Initializes a new connection to a third-party service and returns an authorization URL for OAuth flow completion.

9

10

```typescript { .api }

11

/**

12

* Initialize connection and get authorization URL

13

* @param provider - Third-party service provider

14

* @param params - Connection configuration parameters

15

* @param options - Optional request configuration

16

* @returns Promise resolving to connection creation response with auth URL

17

*/

18

create(

19

provider: ConnectionProvider,

20

params?: ConnectionCreateParams,

21

options?: RequestOptions

22

): APIPromise<ConnectionCreateResponse>;

23

24

type ConnectionProvider = "notion" | "google-drive" | "onedrive";

25

26

interface ConnectionCreateParams {

27

/** Container tags for organizing imported content */

28

containerTags?: string[];

29

/** Maximum number of documents to import (optional limit) */

30

documentLimit?: number;

31

/** Additional metadata for the connection */

32

metadata?: { [key: string]: string | number | boolean } | null;

33

/** OAuth redirect URL after authorization */

34

redirectUrl?: string;

35

}

36

37

interface ConnectionCreateResponse {

38

/** Unique connection identifier */

39

id: string;

40

/** OAuth authorization URL for user to visit */

41

authLink: string;

42

/** Time until authorization expires */

43

expiresIn: string;

44

/** Final redirect destination after OAuth completion */

45

redirectsTo?: string;

46

}

47

```

48

49

**Usage Examples:**

50

51

```typescript

52

import Supermemory from "supermemory";

53

54

const client = new Supermemory({ apiKey: "your-api-key" });

55

56

// Create Notion connection

57

const notionConnection = await client.connections.create("notion", {

58

containerTags: ["team-workspace", "documentation"],

59

documentLimit: 1000,

60

redirectUrl: "https://your-app.com/oauth/callback",

61

metadata: { team: "engineering", purpose: "documentation" },

62

});

63

64

console.log("Visit this URL to authorize:", notionConnection.authLink);

65

console.log("Connection ID:", notionConnection.id);

66

67

// Create Google Drive connection

68

const driveConnection = await client.connections.create("google-drive", {

69

containerTags: ["personal", "documents"],

70

documentLimit: 500,

71

});

72

73

// Create OneDrive connection with minimal configuration

74

const onedriveConnection = await client.connections.create("onedrive");

75

```

76

77

### List Connections

78

79

Retrieves all connections for the organization with optional container tag filtering.

80

81

```typescript { .api }

82

/**

83

* List all connections

84

* @param params - Optional filtering parameters

85

* @param options - Optional request configuration

86

* @returns Promise resolving to array of connections

87

*/

88

list(

89

params?: ConnectionListParams,

90

options?: RequestOptions

91

): APIPromise<ConnectionListResponse>;

92

93

interface ConnectionListParams {

94

/** Filter connections by container tags */

95

containerTags?: string[];

96

}

97

98

type ConnectionListResponse = ConnectionListItem[];

99

100

interface ConnectionListItem {

101

/** Connection identifier */

102

id: string;

103

/** Connection creation timestamp */

104

createdAt: string;

105

/** Service provider name */

106

provider: string;

107

/** Document import limit */

108

documentLimit?: number;

109

/** Connected account email */

110

email?: string;

111

/** OAuth token expiration time */

112

expiresAt?: string;

113

/** Connection metadata */

114

metadata?: { [key: string]: unknown };

115

}

116

```

117

118

**Usage Examples:**

119

120

```typescript

121

// List all connections

122

const allConnections = await client.connections.list();

123

console.log(`Found ${allConnections.length} connections`);

124

125

// List connections filtered by tags

126

const teamConnections = await client.connections.list({

127

containerTags: ["team-workspace"],

128

});

129

130

// Process connections

131

allConnections.forEach((connection) => {

132

console.log(`${connection.provider} connection: ${connection.email}`);

133

if (connection.expiresAt) {

134

const expiry = new Date(connection.expiresAt);

135

console.log(`Expires: ${expiry.toLocaleDateString()}`);

136

}

137

});

138

```

139

140

### Get Connection by ID

141

142

Retrieves detailed information about a specific connection using its unique identifier.

143

144

```typescript { .api }

145

/**

146

* Get connection details with id

147

* @param connectionID - Unique connection identifier

148

* @param options - Optional request configuration

149

* @returns Promise resolving to connection details

150

*/

151

getByID(

152

connectionID: string,

153

options?: RequestOptions

154

): APIPromise<ConnectionGetByIDResponse>;

155

156

interface ConnectionGetByIDResponse {

157

id: string;

158

createdAt: string;

159

provider: string;

160

documentLimit?: number;

161

email?: string;

162

expiresAt?: string;

163

metadata?: { [key: string]: unknown };

164

}

165

```

166

167

**Usage Example:**

168

169

```typescript

170

const connection = await client.connections.getByID("connection-id-123");

171

console.log(`Connection: ${connection.provider} (${connection.email})`);

172

console.log(`Created: ${connection.createdAt}`);

173

console.log(`Document limit: ${connection.documentLimit || "unlimited"}`);

174

```

175

176

### Get Connection by Tags

177

178

Finds a connection for a specific provider filtered by container tags.

179

180

```typescript { .api }

181

/**

182

* Get connection details with provider and container tags

183

* @param provider - Service provider to search for

184

* @param params - Container tags for filtering

185

* @param options - Optional request configuration

186

* @returns Promise resolving to matching connection

187

*/

188

getByTags(

189

provider: ConnectionProvider,

190

params: ConnectionGetByTagsParams,

191

options?: RequestOptions

192

): APIPromise<ConnectionGetByTagsResponse>;

193

194

interface ConnectionGetByTagsParams {

195

/** Container tags to match (required) */

196

containerTags: string[];

197

}

198

199

interface ConnectionGetByTagsResponse {

200

id: string;

201

createdAt: string;

202

provider: string;

203

documentLimit?: number;

204

email?: string;

205

expiresAt?: string;

206

metadata?: { [key: string]: unknown };

207

}

208

```

209

210

**Usage Examples:**

211

212

```typescript

213

// Find Notion connection for specific workspace

214

const workspaceNotion = await client.connections.getByTags("notion", {

215

containerTags: ["team-workspace", "engineering"],

216

});

217

218

// Find Google Drive connection for user

219

const userDrive = await client.connections.getByTags("google-drive", {

220

containerTags: ["user_123", "personal"],

221

});

222

```

223

224

### Delete Connection by ID

225

226

Permanently removes a connection using its unique identifier.

227

228

```typescript { .api }

229

/**

230

* Delete a specific connection by ID

231

* @param connectionID - Connection identifier to delete

232

* @param options - Optional request configuration

233

* @returns Promise resolving to deletion confirmation

234

*/

235

deleteByID(

236

connectionID: string,

237

options?: RequestOptions

238

): APIPromise<ConnectionDeleteByIDResponse>;

239

240

interface ConnectionDeleteByIDResponse {

241

/** Deleted connection ID */

242

id: string;

243

/** Service provider of deleted connection */

244

provider: string;

245

}

246

```

247

248

### Delete Connection by Provider

249

250

Removes connections for a specific provider filtered by container tags.

251

252

```typescript { .api }

253

/**

254

* Delete connection for a specific provider and container tags

255

* @param provider - Service provider

256

* @param params - Container tags for targeting specific connections

257

* @param options - Optional request configuration

258

* @returns Promise resolving to deletion confirmation

259

*/

260

deleteByProvider(

261

provider: ConnectionProvider,

262

params: ConnectionDeleteByProviderParams,

263

options?: RequestOptions

264

): APIPromise<ConnectionDeleteByProviderResponse>;

265

266

interface ConnectionDeleteByProviderParams {

267

/** Container tags to identify connections to delete (required) */

268

containerTags: string[];

269

}

270

271

interface ConnectionDeleteByProviderResponse {

272

/** Deleted connection ID */

273

id: string;

274

/** Service provider of deleted connection */

275

provider: string;

276

}

277

```

278

279

**Usage Examples:**

280

281

```typescript

282

// Delete specific connection

283

const deletedConnection = await client.connections.deleteByID("connection-id-123");

284

console.log(`Deleted ${deletedConnection.provider} connection: ${deletedConnection.id}`);

285

286

// Delete all Notion connections for a workspace

287

const deletedNotion = await client.connections.deleteByProvider("notion", {

288

containerTags: ["old-workspace", "deprecated"],

289

});

290

```

291

292

### Import/Sync Connection

293

294

Initiates manual synchronization of content from a connected service.

295

296

```typescript { .api }

297

/**

298

* Initiate a manual sync of connections

299

* @param provider - Service provider to sync

300

* @param params - Optional filtering for which connections to sync

301

* @param options - Optional request configuration

302

* @returns Promise resolving to sync status message

303

*/

304

import(

305

provider: ConnectionProvider,

306

params?: ConnectionImportParams,

307

options?: RequestOptions

308

): APIPromise<string>;

309

310

interface ConnectionImportParams {

311

/** Filter connections to sync by container tags */

312

containerTags?: string[];

313

}

314

```

315

316

**Usage Examples:**

317

318

```typescript

319

// Sync all Notion connections

320

const notionSync = await client.connections.import("notion");

321

console.log("Notion sync result:", notionSync);

322

323

// Sync specific Google Drive connections

324

const driveSync = await client.connections.import("google-drive", {

325

containerTags: ["active-projects"],

326

});

327

328

// Sync all OneDrive connections

329

const onedriveSync = await client.connections.import("onedrive");

330

```

331

332

### List Connection Documents

333

334

Retrieves documents that have been indexed from a specific provider's connections.

335

336

```typescript { .api }

337

/**

338

* List documents indexed for a provider and container tags

339

* @param provider - Service provider

340

* @param params - Optional filtering parameters

341

* @param options - Optional request configuration

342

* @returns Promise resolving to indexed documents list

343

*/

344

listDocuments(

345

provider: ConnectionProvider,

346

params?: ConnectionListDocumentsParams,

347

options?: RequestOptions

348

): APIPromise<ConnectionListDocumentsResponse>;

349

350

interface ConnectionListDocumentsParams {

351

/** Filter documents by container tags */

352

containerTags?: string[];

353

}

354

355

type ConnectionListDocumentsResponse = ConnectionDocument[];

356

357

interface ConnectionDocument {

358

/** Document identifier */

359

id: string;

360

/** Document creation timestamp */

361

createdAt: string;

362

/** Processing status */

363

status: string;

364

/** Document summary */

365

summary: string | null;

366

/** Document title */

367

title: string | null;

368

/** Document type */

369

type: string;

370

/** Last update timestamp */

371

updatedAt: string;

372

}

373

```

374

375

**Usage Examples:**

376

377

```typescript

378

// List all Google Drive documents

379

const driveDocuments = await client.connections.listDocuments("google-drive");

380

console.log(`Found ${driveDocuments.length} Google Drive documents`);

381

382

// List Notion documents for specific workspace

383

const workspaceDocuments = await client.connections.listDocuments("notion", {

384

containerTags: ["team-workspace"],

385

});

386

387

// Process documents

388

driveDocuments.forEach((doc) => {

389

console.log(`${doc.type}: ${doc.title} (${doc.status})`);

390

if (doc.summary) {

391

console.log(`Summary: ${doc.summary.substring(0, 100)}...`);

392

}

393

});

394

```

395

396

## Connection Workflows

397

398

### Complete Connection Setup

399

400

```typescript

401

const setupNotionConnection = async () => {

402

try {

403

// Step 1: Ensure custom OAuth keys are configured in settings

404

await client.settings.update({

405

notionCustomKeyEnabled: true,

406

notionClientId: process.env.NOTION_CLIENT_ID,

407

notionClientSecret: process.env.NOTION_CLIENT_SECRET,

408

});

409

410

// Step 2: Create connection

411

const connection = await client.connections.create("notion", {

412

containerTags: ["team-docs", "engineering"],

413

documentLimit: 1000,

414

redirectUrl: "https://your-app.com/oauth/notion/callback",

415

metadata: {

416

team: "engineering",

417

purpose: "team-documentation",

418

setupBy: "admin",

419

},

420

});

421

422

console.log("Authorization URL:", connection.authLink);

423

console.log("Connection ID:", connection.id);

424

425

// Step 3: User completes OAuth flow (external process)

426

// Your application handles the OAuth callback

427

428

// Step 4: Verify connection was established

429

const verifiedConnection = await client.connections.getByID(connection.id);

430

console.log("Connection verified:", verifiedConnection.email);

431

432

// Step 5: Initial sync

433

const syncResult = await client.connections.import("notion", {

434

containerTags: ["team-docs"],

435

});

436

console.log("Initial sync:", syncResult);

437

438

return connection;

439

440

} catch (error) {

441

console.error("Connection setup failed:", error.message);

442

throw error;

443

}

444

};

445

```

446

447

### Batch Connection Management

448

449

```typescript

450

const manageMultipleConnections = async () => {

451

// Get all connections

452

const connections = await client.connections.list();

453

454

// Group by provider

455

const byProvider = connections.reduce((acc, conn) => {

456

acc[conn.provider] = acc[conn.provider] || [];

457

acc[conn.provider].push(conn);

458

return acc;

459

}, {} as Record<string, typeof connections>);

460

461

// Check for expiring connections

462

const expiringConnections = connections.filter((conn) => {

463

if (!conn.expiresAt) return false;

464

const expiry = new Date(conn.expiresAt);

465

const daysUntilExpiry = (expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24);

466

return daysUntilExpiry < 30; // Expiring in 30 days

467

});

468

469

console.log("Connections by provider:", Object.keys(byProvider));

470

console.log("Expiring connections:", expiringConnections.length);

471

472

// Sync all connections

473

for (const provider of Object.keys(byProvider)) {

474

try {

475

const syncResult = await client.connections.import(provider as ConnectionProvider);

476

console.log(`${provider} sync:`, syncResult);

477

} catch (error) {

478

console.error(`${provider} sync failed:`, error.message);

479

}

480

}

481

};

482

```

483

484

### Connection Monitoring

485

486

```typescript

487

const monitorConnections = async () => {

488

const connections = await client.connections.list();

489

490

for (const connection of connections) {

491

console.log(`\n${connection.provider.toUpperCase()} Connection: ${connection.id}`);

492

console.log(`Email: ${connection.email || "N/A"}`);

493

console.log(`Created: ${new Date(connection.createdAt).toLocaleDateString()}`);

494

495

if (connection.expiresAt) {

496

const expiry = new Date(connection.expiresAt);

497

const daysLeft = Math.ceil((expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24));

498

console.log(`Expires: ${expiry.toLocaleDateString()} (${daysLeft} days)`);

499

500

if (daysLeft < 7) {

501

console.log("⚠️ Connection expires soon!");

502

}

503

}

504

505

// Check document count

506

try {

507

const documents = await client.connections.listDocuments(

508

connection.provider as ConnectionProvider,

509

{ containerTags: connection.metadata?.containerTags as string[] }

510

);

511

console.log(`Documents: ${documents.length}`);

512

513

// Check processing status

514

const statusCounts = documents.reduce((acc, doc) => {

515

acc[doc.status] = (acc[doc.status] || 0) + 1;

516

return acc;

517

}, {} as Record<string, number>);

518

519

console.log("Status breakdown:", statusCounts);

520

521

} catch (error) {

522

console.log("Could not fetch documents:", error.message);

523

}

524

}

525

};

526

```

527

528

### Error Handling and Recovery

529

530

```typescript

531

const handleConnectionErrors = async (provider: ConnectionProvider) => {

532

try {

533

const syncResult = await client.connections.import(provider);

534

return { success: true, result: syncResult };

535

536

} catch (error) {

537

if (error instanceof AuthenticationError) {

538

console.error(`${provider} authentication failed - OAuth token may have expired`);

539

540

// Find connections for this provider

541

const connections = await client.connections.list();

542

const providerConnections = connections.filter(c => c.provider === provider);

543

544

for (const connection of providerConnections) {

545

console.log(`Connection ${connection.id} may need re-authorization`);

546

// In a real application, you might trigger a re-authorization flow

547

}

548

549

} else if (error instanceof RateLimitError) {

550

console.error(`${provider} rate limit exceeded - will retry later`);

551

552

// Implement exponential backoff retry

553

const delay = 60000; // 1 minute

554

console.log(`Retrying ${provider} sync in ${delay / 1000} seconds`);

555

556

return new Promise((resolve) => {

557

setTimeout(async () => {

558

try {

559

const retryResult = await client.connections.import(provider);

560

resolve({ success: true, result: retryResult });

561

} catch (retryError) {

562

resolve({ success: false, error: retryError.message });

563

}

564

}, delay);

565

});

566

567

} else if (error instanceof BadRequestError) {

568

console.error(`${provider} sync failed - invalid configuration:`, error.message);

569

570

} else {

571

console.error(`${provider} sync failed:`, error.message);

572

}

573

574

return { success: false, error: error.message };

575

}

576

};

577

578

// Usage

579

const syncAllProvidersWithErrorHandling = async () => {

580

const providers: ConnectionProvider[] = ["notion", "google-drive", "onedrive"];

581

582

const results = await Promise.all(

583

providers.map(provider => handleConnectionErrors(provider))

584

);

585

586

results.forEach((result, index) => {

587

const provider = providers[index];

588

if (result.success) {

589

console.log(`✅ ${provider}: ${result.result}`);

590

} else {

591

console.log(`❌ ${provider}: ${result.error}`);

592

}

593

});

594

};

595

```