The official TypeScript library for the Supermemory API providing memory management, search, settings, and connection capabilities.
—
Third-party service integrations for automated content synchronization and document importing from Notion, Google Drive, and OneDrive platforms.
Initializes a new connection to a third-party service and returns an authorization URL for OAuth flow completion.
/**
* Initialize connection and get authorization URL
* @param provider - Third-party service provider
* @param params - Connection configuration parameters
* @param options - Optional request configuration
* @returns Promise resolving to connection creation response with auth URL
*/
create(
provider: ConnectionProvider,
params?: ConnectionCreateParams,
options?: RequestOptions
): APIPromise<ConnectionCreateResponse>;
type ConnectionProvider = "notion" | "google-drive" | "onedrive";
interface ConnectionCreateParams {
/** Container tags for organizing imported content */
containerTags?: string[];
/** Maximum number of documents to import (optional limit) */
documentLimit?: number;
/** Additional metadata for the connection */
metadata?: { [key: string]: string | number | boolean } | null;
/** OAuth redirect URL after authorization */
redirectUrl?: string;
}
interface ConnectionCreateResponse {
/** Unique connection identifier */
id: string;
/** OAuth authorization URL for user to visit */
authLink: string;
/** Time until authorization expires */
expiresIn: string;
/** Final redirect destination after OAuth completion */
redirectsTo?: string;
}Usage Examples:
import Supermemory from "supermemory";
const client = new Supermemory({ apiKey: "your-api-key" });
// Create Notion connection
const notionConnection = await client.connections.create("notion", {
containerTags: ["team-workspace", "documentation"],
documentLimit: 1000,
redirectUrl: "https://your-app.com/oauth/callback",
metadata: { team: "engineering", purpose: "documentation" },
});
console.log("Visit this URL to authorize:", notionConnection.authLink);
console.log("Connection ID:", notionConnection.id);
// Create Google Drive connection
const driveConnection = await client.connections.create("google-drive", {
containerTags: ["personal", "documents"],
documentLimit: 500,
});
// Create OneDrive connection with minimal configuration
const onedriveConnection = await client.connections.create("onedrive");Retrieves all connections for the organization with optional container tag filtering.
/**
* List all connections
* @param params - Optional filtering parameters
* @param options - Optional request configuration
* @returns Promise resolving to array of connections
*/
list(
params?: ConnectionListParams,
options?: RequestOptions
): APIPromise<ConnectionListResponse>;
interface ConnectionListParams {
/** Filter connections by container tags */
containerTags?: string[];
}
type ConnectionListResponse = ConnectionListItem[];
interface ConnectionListItem {
/** Connection identifier */
id: string;
/** Connection creation timestamp */
createdAt: string;
/** Service provider name */
provider: string;
/** Document import limit */
documentLimit?: number;
/** Connected account email */
email?: string;
/** OAuth token expiration time */
expiresAt?: string;
/** Connection metadata */
metadata?: { [key: string]: unknown };
}Usage Examples:
// List all connections
const allConnections = await client.connections.list();
console.log(`Found ${allConnections.length} connections`);
// List connections filtered by tags
const teamConnections = await client.connections.list({
containerTags: ["team-workspace"],
});
// Process connections
allConnections.forEach((connection) => {
console.log(`${connection.provider} connection: ${connection.email}`);
if (connection.expiresAt) {
const expiry = new Date(connection.expiresAt);
console.log(`Expires: ${expiry.toLocaleDateString()}`);
}
});Retrieves detailed information about a specific connection using its unique identifier.
/**
* Get connection details with id
* @param connectionID - Unique connection identifier
* @param options - Optional request configuration
* @returns Promise resolving to connection details
*/
getByID(
connectionID: string,
options?: RequestOptions
): APIPromise<ConnectionGetByIDResponse>;
interface ConnectionGetByIDResponse {
id: string;
createdAt: string;
provider: string;
documentLimit?: number;
email?: string;
expiresAt?: string;
metadata?: { [key: string]: unknown };
}Usage Example:
const connection = await client.connections.getByID("connection-id-123");
console.log(`Connection: ${connection.provider} (${connection.email})`);
console.log(`Created: ${connection.createdAt}`);
console.log(`Document limit: ${connection.documentLimit || "unlimited"}`);Finds a connection for a specific provider filtered by container tags.
/**
* Get connection details with provider and container tags
* @param provider - Service provider to search for
* @param params - Container tags for filtering
* @param options - Optional request configuration
* @returns Promise resolving to matching connection
*/
getByTags(
provider: ConnectionProvider,
params: ConnectionGetByTagsParams,
options?: RequestOptions
): APIPromise<ConnectionGetByTagsResponse>;
interface ConnectionGetByTagsParams {
/** Container tags to match (required) */
containerTags: string[];
}
interface ConnectionGetByTagsResponse {
id: string;
createdAt: string;
provider: string;
documentLimit?: number;
email?: string;
expiresAt?: string;
metadata?: { [key: string]: unknown };
}Usage Examples:
// Find Notion connection for specific workspace
const workspaceNotion = await client.connections.getByTags("notion", {
containerTags: ["team-workspace", "engineering"],
});
// Find Google Drive connection for user
const userDrive = await client.connections.getByTags("google-drive", {
containerTags: ["user_123", "personal"],
});Permanently removes a connection using its unique identifier.
/**
* Delete a specific connection by ID
* @param connectionID - Connection identifier to delete
* @param options - Optional request configuration
* @returns Promise resolving to deletion confirmation
*/
deleteByID(
connectionID: string,
options?: RequestOptions
): APIPromise<ConnectionDeleteByIDResponse>;
interface ConnectionDeleteByIDResponse {
/** Deleted connection ID */
id: string;
/** Service provider of deleted connection */
provider: string;
}Removes connections for a specific provider filtered by container tags.
/**
* Delete connection for a specific provider and container tags
* @param provider - Service provider
* @param params - Container tags for targeting specific connections
* @param options - Optional request configuration
* @returns Promise resolving to deletion confirmation
*/
deleteByProvider(
provider: ConnectionProvider,
params: ConnectionDeleteByProviderParams,
options?: RequestOptions
): APIPromise<ConnectionDeleteByProviderResponse>;
interface ConnectionDeleteByProviderParams {
/** Container tags to identify connections to delete (required) */
containerTags: string[];
}
interface ConnectionDeleteByProviderResponse {
/** Deleted connection ID */
id: string;
/** Service provider of deleted connection */
provider: string;
}Usage Examples:
// Delete specific connection
const deletedConnection = await client.connections.deleteByID("connection-id-123");
console.log(`Deleted ${deletedConnection.provider} connection: ${deletedConnection.id}`);
// Delete all Notion connections for a workspace
const deletedNotion = await client.connections.deleteByProvider("notion", {
containerTags: ["old-workspace", "deprecated"],
});Initiates manual synchronization of content from a connected service.
/**
* Initiate a manual sync of connections
* @param provider - Service provider to sync
* @param params - Optional filtering for which connections to sync
* @param options - Optional request configuration
* @returns Promise resolving to sync status message
*/
import(
provider: ConnectionProvider,
params?: ConnectionImportParams,
options?: RequestOptions
): APIPromise<string>;
interface ConnectionImportParams {
/** Filter connections to sync by container tags */
containerTags?: string[];
}Usage Examples:
// Sync all Notion connections
const notionSync = await client.connections.import("notion");
console.log("Notion sync result:", notionSync);
// Sync specific Google Drive connections
const driveSync = await client.connections.import("google-drive", {
containerTags: ["active-projects"],
});
// Sync all OneDrive connections
const onedriveSync = await client.connections.import("onedrive");Retrieves documents that have been indexed from a specific provider's connections.
/**
* List documents indexed for a provider and container tags
* @param provider - Service provider
* @param params - Optional filtering parameters
* @param options - Optional request configuration
* @returns Promise resolving to indexed documents list
*/
listDocuments(
provider: ConnectionProvider,
params?: ConnectionListDocumentsParams,
options?: RequestOptions
): APIPromise<ConnectionListDocumentsResponse>;
interface ConnectionListDocumentsParams {
/** Filter documents by container tags */
containerTags?: string[];
}
type ConnectionListDocumentsResponse = ConnectionDocument[];
interface ConnectionDocument {
/** Document identifier */
id: string;
/** Document creation timestamp */
createdAt: string;
/** Processing status */
status: string;
/** Document summary */
summary: string | null;
/** Document title */
title: string | null;
/** Document type */
type: string;
/** Last update timestamp */
updatedAt: string;
}Usage Examples:
// List all Google Drive documents
const driveDocuments = await client.connections.listDocuments("google-drive");
console.log(`Found ${driveDocuments.length} Google Drive documents`);
// List Notion documents for specific workspace
const workspaceDocuments = await client.connections.listDocuments("notion", {
containerTags: ["team-workspace"],
});
// Process documents
driveDocuments.forEach((doc) => {
console.log(`${doc.type}: ${doc.title} (${doc.status})`);
if (doc.summary) {
console.log(`Summary: ${doc.summary.substring(0, 100)}...`);
}
});const setupNotionConnection = async () => {
try {
// Step 1: Ensure custom OAuth keys are configured in settings
await client.settings.update({
notionCustomKeyEnabled: true,
notionClientId: process.env.NOTION_CLIENT_ID,
notionClientSecret: process.env.NOTION_CLIENT_SECRET,
});
// Step 2: Create connection
const connection = await client.connections.create("notion", {
containerTags: ["team-docs", "engineering"],
documentLimit: 1000,
redirectUrl: "https://your-app.com/oauth/notion/callback",
metadata: {
team: "engineering",
purpose: "team-documentation",
setupBy: "admin",
},
});
console.log("Authorization URL:", connection.authLink);
console.log("Connection ID:", connection.id);
// Step 3: User completes OAuth flow (external process)
// Your application handles the OAuth callback
// Step 4: Verify connection was established
const verifiedConnection = await client.connections.getByID(connection.id);
console.log("Connection verified:", verifiedConnection.email);
// Step 5: Initial sync
const syncResult = await client.connections.import("notion", {
containerTags: ["team-docs"],
});
console.log("Initial sync:", syncResult);
return connection;
} catch (error) {
console.error("Connection setup failed:", error.message);
throw error;
}
};const manageMultipleConnections = async () => {
// Get all connections
const connections = await client.connections.list();
// Group by provider
const byProvider = connections.reduce((acc, conn) => {
acc[conn.provider] = acc[conn.provider] || [];
acc[conn.provider].push(conn);
return acc;
}, {} as Record<string, typeof connections>);
// Check for expiring connections
const expiringConnections = connections.filter((conn) => {
if (!conn.expiresAt) return false;
const expiry = new Date(conn.expiresAt);
const daysUntilExpiry = (expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24);
return daysUntilExpiry < 30; // Expiring in 30 days
});
console.log("Connections by provider:", Object.keys(byProvider));
console.log("Expiring connections:", expiringConnections.length);
// Sync all connections
for (const provider of Object.keys(byProvider)) {
try {
const syncResult = await client.connections.import(provider as ConnectionProvider);
console.log(`${provider} sync:`, syncResult);
} catch (error) {
console.error(`${provider} sync failed:`, error.message);
}
}
};const monitorConnections = async () => {
const connections = await client.connections.list();
for (const connection of connections) {
console.log(`\n${connection.provider.toUpperCase()} Connection: ${connection.id}`);
console.log(`Email: ${connection.email || "N/A"}`);
console.log(`Created: ${new Date(connection.createdAt).toLocaleDateString()}`);
if (connection.expiresAt) {
const expiry = new Date(connection.expiresAt);
const daysLeft = Math.ceil((expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
console.log(`Expires: ${expiry.toLocaleDateString()} (${daysLeft} days)`);
if (daysLeft < 7) {
console.log("⚠️ Connection expires soon!");
}
}
// Check document count
try {
const documents = await client.connections.listDocuments(
connection.provider as ConnectionProvider,
{ containerTags: connection.metadata?.containerTags as string[] }
);
console.log(`Documents: ${documents.length}`);
// Check processing status
const statusCounts = documents.reduce((acc, doc) => {
acc[doc.status] = (acc[doc.status] || 0) + 1;
return acc;
}, {} as Record<string, number>);
console.log("Status breakdown:", statusCounts);
} catch (error) {
console.log("Could not fetch documents:", error.message);
}
}
};const handleConnectionErrors = async (provider: ConnectionProvider) => {
try {
const syncResult = await client.connections.import(provider);
return { success: true, result: syncResult };
} catch (error) {
if (error instanceof AuthenticationError) {
console.error(`${provider} authentication failed - OAuth token may have expired`);
// Find connections for this provider
const connections = await client.connections.list();
const providerConnections = connections.filter(c => c.provider === provider);
for (const connection of providerConnections) {
console.log(`Connection ${connection.id} may need re-authorization`);
// In a real application, you might trigger a re-authorization flow
}
} else if (error instanceof RateLimitError) {
console.error(`${provider} rate limit exceeded - will retry later`);
// Implement exponential backoff retry
const delay = 60000; // 1 minute
console.log(`Retrying ${provider} sync in ${delay / 1000} seconds`);
return new Promise((resolve) => {
setTimeout(async () => {
try {
const retryResult = await client.connections.import(provider);
resolve({ success: true, result: retryResult });
} catch (retryError) {
resolve({ success: false, error: retryError.message });
}
}, delay);
});
} else if (error instanceof BadRequestError) {
console.error(`${provider} sync failed - invalid configuration:`, error.message);
} else {
console.error(`${provider} sync failed:`, error.message);
}
return { success: false, error: error.message };
}
};
// Usage
const syncAllProvidersWithErrorHandling = async () => {
const providers: ConnectionProvider[] = ["notion", "google-drive", "onedrive"];
const results = await Promise.all(
providers.map(provider => handleConnectionErrors(provider))
);
results.forEach((result, index) => {
const provider = providers[index];
if (result.success) {
console.log(`✅ ${provider}: ${result.result}`);
} else {
console.log(`❌ ${provider}: ${result.error}`);
}
});
};Install with Tessl CLI
npx tessl i tessl/npm-supermemory