Appearance
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
- Batch Processing - Learn how to process data at scale
- API Reference - Browse all available export methods
- Quick Start - Review the basic workflow