Integrations
Connect your users' third-party apps with the Unified API. Access CRM, storage, communication, and productivity data through a single consistent interface.
Available Categories
CRM
HubSpot, Salesforce, Pipedrive
Contacts, Companies, Deals, Notes
Storage
Google Drive, Dropbox, OneDrive
Files, Folders, Upload, Download
Communication
Slack, Discord
Channels, Messages, Users
Productivity
Notion, Google Sheets, Airtable
Documents, Tables, Records
Quick Start
Initialize the SDK and start working with your users' connected accounts:
import { Stack0 } from '@stack0/sdk'const stack0 = new Stack0({apiKey: process.env.STACK0_API_KEY!})// List contacts from a user's connected CRMconst contacts = await stack0.integrations.crm.listContacts('conn_abc123')// Upload a file to a user's cloud storageawait stack0.integrations.storage.uploadFile('conn_xyz789', {name: 'report.pdf',mimeType: 'application/pdf',data: fileBuffer,})// Send a message to a user's Slackawait stack0.integrations.communication.sendMessage('conn_slack123', {channelId: 'C0123456',content: 'Hello from your app!',})
Managing Connections
Connections represent authenticated links between your users and their third-party accounts:
// List all connections for a userconst connections = await stack0.integrations.listConnections()// Filter by connectorconst crmConnections = await stack0.integrations.listConnections({connectorId: 'hubspot',status: 'connected',})// Get a specific connectionconst connection = await stack0.integrations.getConnection('conn_abc123')console.log(connection.connectorSlug) // 'hubspot'console.log(connection.status) // 'connected'// Test if a connection is still validconst result = await stack0.integrations.testConnection('conn_abc123')if (!result.success) {console.log('Connection needs re-authentication:', result.error)}// Delete a connectionawait stack0.integrations.deleteConnection('conn_abc123')
CRM Operations
Work with contacts, companies, and deals from any CRM:
const connectionId = 'conn_abc123'// === CONTACTS ===// List contacts with paginationconst { data: contacts, nextCursor } = await stack0.integrations.crm.listContacts(connectionId,{ limit: 50 })// Create a new contactconst newContact = await stack0.integrations.crm.createContact(connectionId, {firstName: 'John',lastName: 'Doe',email: 'john@example.com',phone: '+1234567890',})// Update a contactawait stack0.integrations.crm.updateContact(connectionId, newContact.id, {title: 'Senior Engineer',})// === COMPANIES ===const { data: companies } = await stack0.integrations.crm.listCompanies(connectionId)const company = await stack0.integrations.crm.createCompany(connectionId, {name: 'Acme Corp',domain: 'acme.com',industry: 'Technology',})// === DEALS ===const { data: deals } = await stack0.integrations.crm.listDeals(connectionId)const deal = await stack0.integrations.crm.createDeal(connectionId, {name: 'Enterprise License',amount: 50000,stage: 'proposal',companyId: company.id,})
Storage Operations
Upload, download, and manage files in any cloud storage:
const connectionId = 'conn_storage123'// List files in root folderconst { data: files } = await stack0.integrations.storage.listFiles(connectionId)// List files in a specific folderconst { data: folderFiles } = await stack0.integrations.storage.listFiles(connectionId,'folder_id_123')// Upload a fileconst uploadedFile = await stack0.integrations.storage.uploadFile(connectionId, {name: 'document.pdf',mimeType: 'application/pdf',data: fileBuffer, // ArrayBuffer or Uint8ArrayfolderId: 'folder_id_123', // optional})// Download a fileconst { data, mimeType, filename } = await stack0.integrations.storage.downloadFile(connectionId,'file_id_456')// List foldersconst { data: folders } = await stack0.integrations.storage.listFolders(connectionId)// Create a folderconst folder = await stack0.integrations.storage.createFolder(connectionId, {name: 'New Folder',parentId: 'parent_folder_id', // optional})// Delete a fileawait stack0.integrations.storage.deleteFile(connectionId, 'file_id_456')
Communication Operations
Send messages and interact with channels in Slack or Discord:
const connectionId = 'conn_slack123'// List available channelsconst { data: channels } = await stack0.integrations.communication.listChannels(connectionId)// Get a specific channelconst channel = await stack0.integrations.communication.getChannel(connectionId,'C0123456')// List messages in a channelconst { data: messages } = await stack0.integrations.communication.listMessages(connectionId,'C0123456',{ limit: 20 })// Send a messageconst message = await stack0.integrations.communication.sendMessage(connectionId, {channelId: 'C0123456',content: 'Hello from Stack0!',})// List workspace usersconst { data: users } = await stack0.integrations.communication.listUsers(connectionId)
Productivity Operations
Work with documents and tables in Notion, Google Sheets, or Airtable:
const connectionId = 'conn_notion123'// === DOCUMENTS (Notion pages, etc.) ===const { data: documents } = await stack0.integrations.productivity.listDocuments(connectionId)const doc = await stack0.integrations.productivity.createDocument(connectionId, {title: 'Meeting Notes',content: '## Agenda\n- Item 1\n- Item 2',})await stack0.integrations.productivity.updateDocument(connectionId, doc.id, {content: '## Updated Agenda\n- New item',})// === TABLES (Sheets, Airtable bases, Notion databases) ===const { data: tables } = await stack0.integrations.productivity.listTables(connectionId)// List rows in a tableconst { data: rows } = await stack0.integrations.productivity.listTableRows(connectionId,'table_id')// Add a rowconst row = await stack0.integrations.productivity.createTableRow(connectionId,'table_id',{fields: {Name: 'John Doe',Email: 'john@example.com',Status: 'Active',},})// Update a rowawait stack0.integrations.productivity.updateTableRow(connectionId,'table_id',row.id,{fields: { Status: 'Completed' },})
Passthrough Requests
For advanced use cases, make raw API calls to the underlying provider:
// Make a raw request to the provider's APIconst response = await stack0.integrations.passthrough({connectionId: 'conn_abc123',method: 'GET',path: '/crm/v3/objects/custom_objects',query: { limit: '10' },})// POST with bodyconst createResponse = await stack0.integrations.passthrough({connectionId: 'conn_abc123',method: 'POST',path: '/crm/v3/objects/custom_objects',body: {properties: {custom_field: 'value',},},})
Error Handling
Handle integration-specific errors gracefully:
import { Stack0Error } from '@stack0/sdk'try {const contacts = await stack0.integrations.crm.listContacts('conn_abc123')} catch (error) {if (error instanceof Stack0Error) {switch (error.code) {case 'connection_expired':// Token expired, prompt user to re-authenticateconsole.log('Connection expired, re-auth required')breakcase 'rate_limited':// Provider rate limit hitconsole.log('Rate limited, retry after:', error.retryAfter)breakcase 'provider_error':// Error from the underlying providerconsole.log('Provider error:', error.providerMessage)breakdefault:console.log('Integration error:', error.message)}}}
Pagination
All list operations support cursor-based pagination:
// Fetch all contacts with paginationlet allContacts: Contact[] = []let cursor: string | undefineddo {const { data, nextCursor } = await stack0.integrations.crm.listContacts('conn_abc123',{ limit: 100, cursor })allContacts = [...allContacts, ...data]cursor = nextCursor} while (cursor)console.log('Total contacts:', allContacts.length)