Skip to main content
const files = await airstore.fs.list('ws_abc123', { path: '/' })
const content = await airstore.fs.read('ws_abc123', { path: files[0].path })
The virtual filesystem is where everything comes together. Connected integrations and smart folders surface their data as files and directories that you can list, read, and inspect — just like a local filesystem.

List a directory

import Airstore from '@airstore/sdk'

const airstore = new Airstore()

// List the root
const root = await airstore.fs.list('ws_abc123', { path: '/' })
for (const entry of root) {
  const icon = entry.is_folder ? '📁' : '📄'
  console.log(`${icon} ${entry.name}`)
}
Output might look like:
📁 Sources
📁 Smart Folders
Drill into subdirectories by passing a deeper path:
const gmailFiles = await airstore.fs.list('ws_abc123', {
  path: '/Sources/gmail/',
})

Read a file

const content = await airstore.fs.read('ws_abc123', {
  path: '/Sources/gmail/Unread Emails/meeting-notes.eml',
})

console.log(content) // file contents as a string
For large files, use byte-range reads:
// Read the first 1KB
const preview = await airstore.fs.read('ws_abc123', {
  path: '/Sources/gmail/Unread Emails/large-attachment.pdf',
  offset: 0,
  length: 1024,
})

Get a directory tree

tree() returns a recursive listing of all files and directories under a path. Useful for getting a full picture of what’s available:
const tree = await airstore.fs.tree('ws_abc123', { path: '/' })

for (const entry of tree.entries) {
  const indent = entry.path.split('/').length - 1
  console.log(`${'  '.repeat(indent)}${entry.name}`)
}
For large trees, use pagination:
let token: string | undefined

do {
  const page = await airstore.fs.tree('ws_abc123', {
    path: '/',
    maxKeys: 100,
    continuationToken: token,
  })

  for (const entry of page.entries) {
    console.log(entry.path)
  }

  token = page.truncated ? page.continuation_token : undefined
} while (token)

Check file metadata

stat() returns metadata for a single file or directory without reading its contents:
const info = await airstore.fs.stat('ws_abc123', '/Sources/gmail/Unread Emails/invoice.pdf')

console.log(info.name)        // "invoice.pdf"
console.log(info.size)        // 48230
console.log(info.type)        // "application/pdf"
console.log(info.modified_at) // "2025-01-15T10:30:00Z"

Typical pattern: search and read

Combine smart folders with filesystem reads to build search workflows:
// Create a smart folder for a specific query
const folder = await airstore.smartFolders.create('ws_abc123', {
  integration: 'gmail',
  name: 'Q4 Invoices',
  guidance: 'invoices received in Q4 2025',
})

// Wait a moment for sync
await new Promise(r => setTimeout(r, 3000))

// List what matched
const invoices = await airstore.fs.list('ws_abc123', { path: folder.path })

// Read each one
for (const invoice of invoices) {
  const content = await airstore.fs.read('ws_abc123', { path: invoice.path })
  // Process the content...
}

Next steps