Skip to content

Export Pipeline

Learn how to export research data, download reports, and build automated data pipelines.

Overview

The SDK provides several ways to export and download your research data:

  • Export summaries with all related data
  • Download study and report PDFs
  • Get file download URLs
  • Build automated export workflows

This guide covers best practices for exporting and integrating with your data pipeline.

Exporting Summaries

Export summaries with all related inputs and data.

Basic Summary Export

typescript
import { Configuration, SummariesApi } from '@syntheticusers/sdk'
import fs from 'fs'

const configuration = new Configuration({
  basePath: 'https://api.syntheticusers.com/api/v1',
  accessToken: 'your-access-token'
})

const summariesApi = new SummariesApi(configuration)

async function exportSummary(summaryId: string) {
  // Export a summary as text
  const exportData = await summariesApi.exportSummaryV1({ summaryId })
  
  // Save to file
  fs.writeFileSync('summary_export.txt', exportData)
  
  console.log('✓ Summary exported successfully')
}

await exportSummary('your-summary-id')

Export All Summaries in a Study

typescript
import { SummariesApi } from '@syntheticusers/sdk'
import fs from 'fs'
import path from 'path'

async function exportAllStudySummaries(
  summariesApi: SummariesApi,
  studyId: string,
  outputDir: string = 'exports'
) {
  // Create output directory
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true })
  }
  
  // Get all summaries for the study
  let page = 1
  let exportedCount = 0
  
  while (true) {
    const response = await summariesApi.listSummariesV1({
      studyId,
      page,
      pageSize: 50
    })
    
    for (const summary of response.items) {
      try {
        // Export each summary
        const exportData = await summariesApi.exportSummaryV1({
          summaryId: summary.id
        })
        
        // Save to file
        const filename = path.join(outputDir, `summary_${summary.id}.txt`)
        fs.writeFileSync(filename, exportData)
        
        exportedCount++
        console.log(`✓ Exported summary ${summary.id}`)
      } catch (error) {
        console.error(`✗ Failed to export ${summary.id}:`, error)
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  console.log(`\nExported ${exportedCount} summaries to ${outputDir}/`)
  return exportedCount
}

// Usage
await exportAllStudySummaries(
  summariesApi,
  'your-study-id',
  'study_exports'
)

Downloading PDF Reports

Download study and report PDFs for sharing and archiving.

Download Study PDF

typescript
import { StudiesApi } from '@syntheticusers/sdk'
import fs from 'fs'

const studiesApi = new StudiesApi(configuration)

async function downloadStudyPDF(studyId: string) {
  // Get PDF as Buffer
  const pdfBuffer = await studiesApi.getStudyPdfV1({ studyId })
  
  // Save to file
  fs.writeFileSync('study_report.pdf', pdfBuffer)
  
  console.log('✓ Study PDF downloaded')
}

await downloadStudyPDF('your-study-id')

Download Report PDF

typescript
import { ReportsApi } from '@syntheticusers/sdk'

const reportsApi = new ReportsApi(configuration)

async function downloadReportPDF(reportId: string) {
  const pdfBuffer = await reportsApi.getReportPdfV1({ reportId })
  
  fs.writeFileSync('report.pdf', pdfBuffer)
  
  console.log('✓ Report PDF downloaded')
}

await downloadReportPDF('your-report-id')

Batch Download All Study PDFs

typescript
import { StudiesApi } from '@syntheticusers/sdk'
import fs from 'fs'
import path from 'path'

async function downloadAllStudyPDFs(
  studiesApi: StudiesApi,
  projectId: string,
  outputDir: string = 'pdfs'
) {
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true })
  }
  
  let page = 1
  let downloadedCount = 0
  
  while (true) {
    const response = await studiesApi.listStudiesV1({
      projectId,
      page,
      pageSize: 50
    })
    
    for (const study of response.items) {
      try {
        // Download PDF
        const pdfBuffer = await studiesApi.getStudyPdfV1({ studyId: study.id })
        
        // Save with meaningful filename
        const safeName = study.description?.slice(0, 50).replace(/\//g, '_') || study.id
        const filename = path.join(outputDir, `${safeName}_${study.id}.pdf`)
        
        fs.writeFileSync(filename, pdfBuffer)
        
        downloadedCount++
        console.log(`✓ Downloaded ${study.id}`)
      } catch (error) {
        console.error(`✗ Failed to download ${study.id}:`, error)
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  console.log(`\nDownloaded ${downloadedCount} PDFs to ${outputDir}/`)
  return downloadedCount
}

await downloadAllStudyPDFs(studiesApi, 'your-project-id')

Working with Files

Download uploaded files and manage file downloads.

Get File Download URL

typescript
import { FilesApi } from '@syntheticusers/sdk'

const filesApi = new FilesApi(configuration)

async function getFileURL(fileId: string) {
  // Get presigned download URL
  const fileWithUrl = await filesApi.getFileDownloadUrlV1({ fileId })
  
  console.log(`Download URL: ${fileWithUrl.downloadUrl}`)
  console.log(`URL expires at: ${fileWithUrl.expiresAt}`)
  
  return fileWithUrl
}

await getFileURL('your-file-id')

Download a File

typescript
import fetch from 'node-fetch'
import { FilesApi } from '@syntheticusers/sdk'

async function downloadFile(filesApi: FilesApi, fileId: string) {
  // Get file metadata and download URL
  const fileWithUrl = await filesApi.getFileDownloadUrlV1({ fileId })
  
  // Download the file
  const response = await fetch(fileWithUrl.downloadUrl!)
  
  if (response.ok) {
    const buffer = await response.buffer()
    
    // Save to disk
    fs.writeFileSync(fileWithUrl.name!, buffer)
    console.log(`✓ Downloaded ${fileWithUrl.name}`)
  } else {
    console.error(`✗ Download failed: ${response.status}`)
  }
}

await downloadFile(filesApi, 'your-file-id')

Download All Project Files

typescript
import fetch from 'node-fetch'
import { FilesApi } from '@syntheticusers/sdk'
import fs from 'fs'
import path from 'path'

async function downloadAllProjectFiles(
  filesApi: FilesApi,
  projectId: string,
  outputDir: string = 'files'
) {
  if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true })
  }
  
  let page = 1
  let downloadedCount = 0
  
  while (true) {
    const response = await filesApi.listFilesV1({
      projectId,
      page,
      pageSize: 50
    })
    
    for (const file of response.items) {
      try {
        // Get download URL
        const fileWithUrl = await filesApi.getFileDownloadUrlV1({
          fileId: file.id
        })
        
        // Download
        const downloadResponse = await fetch(fileWithUrl.downloadUrl!)
        
        if (downloadResponse.ok) {
          const buffer = await downloadResponse.buffer()
          const filepath = path.join(outputDir, fileWithUrl.name!)
          fs.writeFileSync(filepath, buffer)
          downloadedCount++
          console.log(`✓ Downloaded ${fileWithUrl.name}`)
        } else {
          console.error(`✗ Failed to download ${file.id}`)
        }
      } catch (error) {
        console.error(`✗ Error downloading ${file.id}:`, error)
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  console.log(`\nDownloaded ${downloadedCount} files to ${outputDir}/`)
  return downloadedCount
}

await downloadAllProjectFiles(filesApi, 'your-project-id')

Building Export Pipelines

Create automated export workflows for regular data exports.

Complete Export Pipeline

typescript
import fs from 'fs'
import path from 'path'
import {
  Configuration,
  StudiesApi,
  SummariesApi,
  ReportsApi,
  FilesApi
} from '@syntheticusers/sdk'

async function exportProjectData(
  projectId: string,
  accessToken: string,
  baseDir: string = 'exports'
) {
  const configuration = new Configuration({
    basePath: 'https://api.syntheticusers.com/api/v1',
    accessToken
  })
  
  // Create timestamped export directory
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
  const exportDir = path.join(baseDir, `project_${projectId}_${timestamp}`)
  fs.mkdirSync(exportDir, { recursive: true })
  
  console.log(`Starting export to ${exportDir}/`)
  
  const studiesApi = new StudiesApi(configuration)
  const summariesApi = new SummariesApi(configuration)
  const reportsApi = new ReportsApi(configuration)
  const filesApi = new FilesApi(configuration)
  
  // 1. Export all studies as PDFs
  console.log('\n📄 Exporting studies...')
  const studiesDir = path.join(exportDir, 'studies')
  fs.mkdirSync(studiesDir, { recursive: true })
  
  let page = 1
  let studyCount = 0
  
  while (true) {
    const response = await studiesApi.listStudiesV1({
      projectId,
      page,
      pageSize: 50
    })
    
    for (const study of response.items) {
      try {
        const pdfBuffer = await studiesApi.getStudyPdfV1({ studyId: study.id })
        const filename = path.join(studiesDir, `study_${study.id}.pdf`)
        fs.writeFileSync(filename, pdfBuffer)
        studyCount++
      } catch (error) {
        console.error(`  ✗ Failed to export study ${study.id}:`, error)
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  console.log(`  ✓ Exported ${studyCount} studies`)
  
  // 2. Export all summaries
  console.log('\n📝 Exporting summaries...')
  const summariesDir = path.join(exportDir, 'summaries')
  fs.mkdirSync(summariesDir, { recursive: true })
  
  page = 1
  let summaryCount = 0
  
  while (true) {
    const response = await summariesApi.listSummariesV1({
      projectId,
      page,
      pageSize: 50
    })
    
    for (const summary of response.items) {
      try {
        const exportData = await summariesApi.exportSummaryV1({
          summaryId: summary.id
        })
        const filename = path.join(summariesDir, `summary_${summary.id}.txt`)
        fs.writeFileSync(filename, exportData)
        summaryCount++
      } catch (error) {
        console.error(`  ✗ Failed to export summary ${summary.id}:`, error)
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  console.log(`  ✓ Exported ${summaryCount} summaries`)
  
  // 3. Download all files
  console.log('\n📎 Downloading files...')
  const filesCount = await downloadAllProjectFiles(
    filesApi,
    projectId,
    path.join(exportDir, 'files')
  )
  
  console.log(`\n✅ Export complete!`)
  console.log(`   Location: ${exportDir}/`)
  console.log(`   Studies: ${studyCount}`)
  console.log(`   Summaries: ${summaryCount}`)
  console.log(`   Files: ${filesCount}`)
  
  return exportDir
}

// Usage
const exportDir = await exportProjectData(
  'your-project-id',
  'your-access-token'
)

Scheduled Export Job

typescript
import schedule from 'node-schedule' // npm install node-schedule

function setupScheduledExport() {
  // Schedule export to run daily at 2 AM
  const job = schedule.scheduleJob('0 2 * * *', async () => {
    console.log(`Running scheduled export at ${new Date()}`)
    try {
      await exportProjectData(
        'your-project-id',
        'your-access-token',
        '/backups/exports'
      )
    } catch (error) {
      console.error('Export job failed:', error)
    }
  })
  
  console.log('Export scheduler started. Press Ctrl+C to exit.')
  return job
}

setupScheduledExport()

Exporting to Different Formats

Convert exported data to various formats for analysis.

Export to JSON

typescript
import { InterviewsApi, SyntheticUsersApi } from '@syntheticusers/sdk'
import fs from 'fs'

async function exportInterviewsToJSON(
  interviewsApi: InterviewsApi,
  studyId: string,
  outputFile: string = 'interviews.json'
) {
  const interviews = []
  let page = 1
  
  while (true) {
    const response = await interviewsApi.listInterviewsV1({
      studyId,
      page,
      pageSize: 50
    })
    
    for (const interview of response.items) {
      // Get full interview details
      const fullInterview = await interviewsApi.getInterviewV1({
        interviewId: interview.id
      })
      
      interviews.push({
        id: fullInterview.id,
        syntheticUserId: fullInterview.syntheticUserId,
        status: fullInterview.status,
        createdAt: fullInterview.createdAt,
        // Add other fields as needed
      })
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  // Save as JSON
  fs.writeFileSync(outputFile, JSON.stringify(interviews, null, 2))
  
  console.log(`✓ Exported ${interviews.length} interviews to ${outputFile}`)
}

await exportInterviewsToJSON(interviewsApi, 'your-study-id')

Export to CSV

typescript
import { ConversationsApi } from '@syntheticusers/sdk'
import { createObjectCsvWriter } from 'csv-writer' // npm install csv-writer

async function exportConversationsToCSV(
  conversationsApi: ConversationsApi,
  studyId: string,
  outputFile: string = 'conversations.csv'
) {
  const csvWriter = createObjectCsvWriter({
    path: outputFile,
    header: [
      { id: 'conversationId', title: 'conversation_id' },
      { id: 'interviewId', title: 'interview_id' },
      { id: 'syntheticUserId', title: 'synthetic_user_id' },
      { id: 'message', title: 'message' },
      { id: 'role', title: 'role' },
      { id: 'timestamp', title: 'timestamp' }
    ]
  })
  
  const records = []
  let page = 1
  
  while (true) {
    const response = await conversationsApi.listConversationsV1({
      studyId,
      page,
      pageSize: 50
    })
    
    for (const conv of response.items) {
      // Get full conversation details
      const fullConv = await conversationsApi.getConversationV1({
        conversationId: conv.id
      })
      
      // Add each message as a row
      for (const message of fullConv.messages || []) {
        records.push({
          conversationId: conv.id,
          interviewId: conv.interviewId,
          syntheticUserId: conv.syntheticUserId,
          message: message.content || '',
          role: message.role || '',
          timestamp: message.timestamp || ''
        })
      }
    }
    
    if (response.items.length < 50) {
      break
    }
    page++
  }
  
  await csvWriter.writeRecords(records)
  console.log(`✓ Exported ${records.length} messages to ${outputFile}`)
}

await exportConversationsToCSV(conversationsApi, 'your-study-id')

Next Steps

Released under the MIT License.