Skip to main content
Connect Gmail to automatically sync email threads into your supermemory knowledge base. Supports real-time updates via Google Cloud Pub/Sub webhooks and incremental synchronization.
Scale Plan Required: The Gmail connector is available on Scale and Enterprise plans only.

Quick Setup

1. Create Gmail Connection

import Supermemory from 'supermemory';

const client = new Supermemory({
  apiKey: process.env.SUPERMEMORY_API_KEY!
});

const connection = await client.connections.create('gmail', {
  redirectUrl: 'https://yourapp.com/auth/gmail/callback',
  containerTags: ['user-123', 'gmail-sync'],
  documentLimit: 5000,
  metadata: {
    source: 'gmail',
    department: 'support'
  }
});

// Redirect user to Google OAuth
window.location.href = connection.authLink;
console.log('Auth expires in:', connection.expiresIn);

2. Handle OAuth Callback

After user grants permissions, Google redirects to your callback URL. The connection is automatically established and the initial sync begins.

3. Check Connection Status

// Get connection details
const connection = await client.connections.getByTags('gmail', {
  containerTags: ['user-123', 'gmail-sync']
});

console.log('Connected email:', connection.email);
console.log('Connection created:', connection.createdAt);

// List synced email threads
const documents = await client.documents.list({
  containerTags: ['user-123', 'gmail-sync']
});

console.log(`Synced ${documents.memories.length} email threads`);

What Gets Synced

Email Threads

Gmail threads (conversations) are synced as individual documents with all messages included:
  • Thread content converted to structured markdown
  • All messages within each thread preserved in order
  • Message metadata: subject, from, to, cc, bcc, date
  • HTML content converted to clean markdown
  • Attachment metadata: filename, mime type, size (attachments are referenced, not stored)

Document Metadata

Each synced thread includes searchable metadata:
FieldDescription
typeAlways gmail_thread
subjectEmail subject line
threadIdGmail thread ID
fromSender email address
toRecipient email addresses
dateDate of first message
messageCountNumber of messages in thread
attachmentCountNumber of attachments (if any)
attachmentNamesList of attachment filenames
You can filter searches using these metadata fields:
const results = await client.search.documents({
  q: "project update",
  containerTags: ['user-123'],
  filters: JSON.stringify({
    AND: [
      { key: "type", value: "gmail_thread", negate: false },
      { key: "from", value: "[email protected]", negate: false }
    ]
  })
});

Connection Management

List All Connections

// List all connections for specific container tags
const connections = await client.connections.list({
  containerTags: ['user-123']
});

connections.forEach(conn => {
  console.log(`Provider: ${conn.provider}`);
  console.log(`ID: ${conn.id}`);
  console.log(`Email: ${conn.email}`);
  console.log(`Created: ${conn.createdAt}`);
  console.log(`Document limit: ${conn.documentLimit}`);
  console.log('---');
});

Delete Connection

// Delete by connection ID
const result = await client.connections.deleteByID('connection_id_123');
console.log('Deleted connection:', result.id);

// Delete by provider and container tags
const providerResult = await client.connections.deleteByProvider('gmail', {
  containerTags: ['user-123']
});
console.log('Deleted Gmail connection:', providerResult.id);
Deleting a connection will:
  • Stop all future syncs from Gmail
  • Remove the OAuth authorization
  • Keep existing synced documents in supermemory (they won’t be deleted)

Manual Sync

Trigger a manual synchronization:
// Trigger sync for Gmail connections
await client.connections.import('gmail');

// Trigger sync for specific container tags
await client.connections.import('gmail', {
  containerTags: ['user-123']
});

console.log('Manual sync initiated');

Sync Mechanism

Gmail connector supports multiple sync methods:
FeatureBehavior
Real-time syncVia Google Cloud Pub/Sub webhooks (7-day expiry, auto-renewed)
Scheduled syncEvery 4 hours
Manual syncOn-demand via API
Incremental syncUses Gmail historyId to fetch only changed threads

How Real-time Sync Works

  1. When a connection is created, supermemory registers a Gmail API “watch” subscription
  2. Gmail sends notifications to a Google Cloud Pub/Sub topic when emails change
  3. supermemory receives these notifications and fetches updated threads
  4. Watch subscriptions expire after 7 days and are automatically renewed
Real-time sync monitors the INBOX label. Emails in other labels are synced via scheduled/manual sync.

Permissions & Scopes

The Gmail connector requests the following OAuth scopes:
ScopePurpose
gmail.readonlyRead-only access to Gmail messages and threads
userinfo.emailAccess to user’s email address for connection identification
Read-only Access: The Gmail connector only reads emails. It cannot send, delete, or modify any emails in the user’s account.

Limitations

Important Limitations:
  • Plan requirement: Requires Scale Plan or Enterprise Plan
  • INBOX only for real-time sync: Only INBOX label triggers real-time updates; other labels sync via scheduled sync
  • Watch expiration: Gmail watch subscriptions expire after 7 days (automatically renewed by supermemory)
  • Document limit: Default limit is 10,000 threads per connection (configurable via documentLimit parameter)
  • Attachments: Attachment metadata is stored, but attachment content is not downloaded
  • Rate limits: Gmail API rate limits may affect sync speed for accounts with many emails

Troubleshooting

OAuth Fails or Missing Refresh Token

If OAuth fails or the connection stops syncing:
  1. Delete the existing connection
  2. Create a new connection
  3. Ensure the user completes the full OAuth flow with consent
// Re-create connection to get fresh tokens
await client.connections.deleteByProvider('gmail', {
  containerTags: ['user-123']
});

const newConnection = await client.connections.create('gmail', {
  redirectUrl: 'https://yourapp.com/auth/gmail/callback',
  containerTags: ['user-123']
});

// User must re-authenticate
window.location.href = newConnection.authLink;

Emails Not Syncing in Real-time

If real-time sync isn’t working:
  • Scheduled sync (every 4 hours) and manual sync still work
  • Real-time sync requires supermemory’s Pub/Sub infrastructure
  • Check if the connection was created recently (watch registration happens on creation)
  • Trigger a manual sync to verify the connection is working

Permission Denied Errors

If you see permission errors:
  • Ensure the user granted the required Gmail scopes during OAuth
  • Verify your organization has Scale Plan or Enterprise Plan access
  • Check if the user revoked app access in their Google Account settings