Skip to main content
Connectors let you link external data sources to a Nebula collection. Once connected, files and messages sync automatically into your memories on a recurring schedule.
Connectors use OAuth, so users authorize access through the provider’s consent screen. Nebula never sees raw passwords.
For self-hosted and enterprise deployments, each Nebula deployment uses one OAuth application per provider. Tenants and users authorize through that deployment-level app, and Nebula stores each connection’s user- or workspace-scoped refresh credentials separately. Use separate OAuth apps only when you intentionally want separate redirect domains, consent screens, or provider-side policy boundaries for different deployments.

Supported Providers

ProviderWhat SyncsConfigSetup Flow
Google DriveDocuments from selected folders or filesfolder_ids, file_idsTwo-phase (pick folders/files after connecting)
SlackMessages from selected channelschannel_idsTwo-phase (pick channels after connecting)
GmailEmails from the authorized inboxOne-phase (syncs immediately)
NotionPages from the authorized workspaceOne-phase (syncs immediately)
OutlookEmails from Microsoft 365 Outlookfolder_idsOne-phase (syncs immediately)
OneDriveDocuments from selected folders or filesfolder_ids, file_idsTwo-phase (pick folders/files after connecting)
SharePointFiles from selected document librariesdrive_ids, folder_ids, file_idsTwo-phase (pick libraries after connecting)
TeamsMessages from selected Teams channels and chatsteam_channel_ids, chat_ids, include_channel_repliesTwo-phase (pick sources after connecting)
Use the List Providers endpoint to check which connectors are enabled on your Nebula instance.
from nebula import Nebula

client = Nebula(api_key="YOUR_API_KEY")
providers = client.connectors.list_providers().results
print(providers)  # ["gmail", "google_drive", "notion", "onedrive", "outlook", "sharepoint", "slack", "teams"]

Connecting a Data Source

Step 1: Start the OAuth Flow

Provide the collection_id where synced content should land. For Google Drive and Slack, you can optionally include config with pre-selected folder, file, or channel IDs. If omitted, you’ll select them after authorization.
result = client.connectors.connect("google_drive", collection_id="YOUR_COLLECTION_ID").results
print(result.auth_url)  # Redirect user here
Response:
{
  "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?...",
  "state": "signed-state-token"
}

Step 2: User Authorizes

Redirect the user to the auth_url from the response. After they approve access on the provider’s consent screen, Nebula handles the OAuth callback automatically.
  • Gmail, Notion, and Outlook: Becomes active and syncing starts immediately. Outlook syncs Inbox, Sent Items, and Archive by default; pass folder_ids at connect time to use a custom folder set.
  • Google Drive, Slack, OneDrive, SharePoint, and Teams: Created with status pending. Proceed to step 3.

Step 3: Complete Provider Selection

Google Drive, Slack, OneDrive, SharePoint, and Teams connections require a folder, file, library, channel, or chat selection before syncing. Complete that selection in the Nebula app’s connector settings UI after OAuth returns. Once the selection is saved, the connection becomes active and the initial sync starts automatically.

Listing Connections

View all connections for a collection. Connections with status revoked are excluded.
connections = client.connectors.list(collection_id="YOUR_COLLECTION_ID").results
for conn in connections:
    print(conn.provider, conn.status, conn.health)
Response:
[
  {
    "id": "CONNECTION_UUID",
    "provider": "google_drive",
    "external_account_id": "user@gmail.com",
    "status": "active",
    "collection_id": "COLLECTION_UUID",
    "items_synced": 47,
    "last_synced_at": "2025-06-15T10:30:00Z",
    "last_error": null,
    "config": {"folder_ids": ["1ABC..."], "file_ids": ["1XYZ..."]},
    "created_at": "2025-06-01T08:00:00Z",
    "health": "ok",
    "error_detail": null,
    "next_sync_at": "2025-06-15T14:30:00Z"
  }
]

Connection Statuses

StatusMeaning
pendingOAuth complete, waiting for required content selection (for example Google Drive, OneDrive, SharePoint, Slack, or Teams)
activeConnected and syncing on schedule
revokedDisconnected, hidden from list results

Enriched Fields

FieldTypeDescription
health"ok" | "error" | null"ok" if active with no errors, "error" if active with last_error, null for non-active statuses
error_detail{message, retryable} | nullStructured version of last_error. retryable is true for all current error types
next_sync_atstring | nullEstimated next sync time. null for non-active connections. Equal to created_at if never synced

Get Connection Details

Fetch a single connection by ID.
conn = client.connectors.retrieve("CONNECTION_ID").results
print(conn.health, conn.next_sync_at)
Response:
{
  "id": "CONNECTION_UUID",
  "provider": "google_drive",
  "external_account_id": "user@gmail.com",
  "status": "active",
  "collection_id": "COLLECTION_UUID",
  "items_synced": 47,
  "last_synced_at": "2025-06-15T10:30:00Z",
  "last_error": null,
  "config": {"folder_ids": ["1ABC..."], "file_ids": ["1XYZ..."]},
  "created_at": "2025-06-01T08:00:00Z",
  "health": "ok",
  "error_detail": null,
  "next_sync_at": "2025-06-15T14:30:00Z"
}

Disconnecting

Remove a connection and stop syncing. Nebula attempts to revoke the OAuth token with the provider. Previously synced memories remain in the collection unless delete_memories is set to true.
# Simple disconnect (keep memories)
client.connectors.disconnect("CONNECTION_ID")

# Disconnect and delete synced memories
result = client.connectors.disconnect("CONNECTION_ID", delete_memories=True).results
print(result.warnings)  # [] on success
Success response:
{
  "message": "Connection CONNECTION_UUID disconnected",
  "warnings": []
}
Partial cleanup response:
{
  "message": "Connection CONNECTION_UUID disconnected",
  "warnings": [
    {
      "code": "cleanup_partial",
      "message": "Some memories could not be deleted. For guaranteed cleanup, delete the entire collection."
    }
  ]
}
Memory deletion is best-effort. Memories created before connection tracking was added, or whose mapping was overwritten by content updates, may not be captured. If a lock is held (for example, sync or config update in progress), memory cleanup is skipped. In rare cases, an unusually slow deletion operation may cause the internal lock to expire, allowing concurrent operations to proceed before cleanup finishes. Metadata-based attribution may also affect engrams with manually crafted matching metadata in the same collection. For guaranteed cleanup, delete the entire collection.

Sync Behavior

  • Schedule: Active connections sync automatically every 4 hours (configurable by the instance admin).
  • Incremental: After the initial full sync, only new or changed items are fetched.
  • Deduplication: Items are tracked by their provider-specific ID and content hash. Unchanged items are skipped.
  • Retries: Failed items are retried up to 3 times. After that, they enter a cooldown period before being re-attempted.

Manual Sync

Trigger an immediate sync for a connection without waiting for the next scheduled run.
result = client.connectors.sync("CONNECTION_ID").results
print(result.message)  # "Sync triggered"
The endpoint returns immediately. The sync runs asynchronously in the background. Error responses:
StatusCondition
400Connection is not active (e.g. pending or revoked)
403User lacks EDIT permission on the collection
409Sync already in progress for this connection

Config Reference

Google Drive

KeyTypeConstraintsDescription
folder_idsstring[]Max 10 items, 64 chars each, alphanumeric onlyDrive folder IDs to sync
file_idsstring[]Max 20 items, 128 chars each, alphanumeric plus _ and -Drive file IDs to sync

Slack

KeyTypeConstraintsDescription
channel_idsstring[]Max 50 items, must start with C or G, uppercase alphanumericSlack channel IDs to sync

Outlook

KeyTypeConstraintsDescription
folder_idsstring[]Max 100 items, 512 chars eachOptional Microsoft Graph mail folder IDs to sync instead of Inbox, Sent Items, and Archive

API Reference

MethodEndpointDescription
GET/v1/connectors/providersList available connector providers
POST/v1/connectors/{provider}/connectStart OAuth flow
GET/v1/connectorsList connections for a collection
GET/v1/connectors/{connection_id}Get a single connection
POST/v1/connectors/{connection_id}/syncTrigger manual sync
DELETE/v1/connectors/{connection_id}Disconnect a data source
All endpoints require authentication via Authorization: Bearer YOUR_API_KEY.

Permissions

EndpointPermission
GET /connectors/providersAuthenticated (no collection check)
GET /connectorsRead access to collection
GET /connectors/{connection_id}Read access to collection
POST /connectors/{provider}/connectEDIT on collection
POST /connectors/{connection_id}/syncEDIT on collection
DELETE /connectors/{connection_id}EDIT on collection

Next Steps