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
```