Create Assets
This guide shows how to create assets (spreadsheets, documents, and folders) using the TypeScript SDK. Assets are the core building blocks of the Athena Intelligence platform, allowing you to organize and manage your workspace programmatically.
Why Create Assets Programmatically? Automate workspace setup, generate dynamic reports, build custom workflows, and integrate Athena into your applications with proper asset organization.
Supported Asset Types:
spreadsheet- Athena spreadsheet with real-time collaborationdocument- Athena document for rich text editingfolder- Folder for organizing assets
Key features:
- Three core asset types - Create spreadsheets, documents, and folders
- Folder organization - Structure assets hierarchically in folders
- Batch operations - Create multiple assets efficiently
- Full TypeScript support - Complete type safety with proper interfaces
- Error handling - Comprehensive error handling for production use
Set Up Client
import type { AthenaIntelligence } from '@athenaintel/sdk';import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk';// Production client setupconst client = new AthenaIntelligenceClient({apiKey: process.env.ATHENA_API_KEY,});// Custom API endpoint (if needed)const customClient = new AthenaIntelligenceClient({apiKey: process.env.ATHENA_API_KEY,baseUrl: 'https://your-custom-api.example.com',});// Local developmentconst devClient = new AthenaIntelligenceClient({apiKey: process.env.ATHENA_API_KEY,baseUrl: 'http://localhost:8000',});
TypeScript Type Definitions
Define proper interfaces for type safety:
// Asset creation requestinterface CreateAssetRequest {asset_type: string;parent_folder_id?: string;title?: string;}// Asset creation resultinterface AssetCreationResult {asset_id: string;title: string;asset_type: string;created_at: string;parent_folder_id?: string;success: boolean;error?: string;}// Batch asset creation resultinterface BatchAssetResult {successful: AssetCreationResult[];failed: Array<{request: CreateAssetRequest;error: string;}>;totalCreated: number;totalFailed: number;}// Supported asset typestype AssetType =| 'spreadsheet'| 'document'| 'folder';
Basic Asset Creation
Create a single asset with proper error handling:
async function createAsset(assetType: AssetType,title?: string,parentFolderId?: string): Promise<AssetCreationResult> {try {console.log(`📝 Creating ${assetType}...`);const response = await client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});console.log('✅ Asset created successfully');console.log('Asset ID:', response.asset_id);console.log('Title:', response.title);console.log('Created at:', response.created_at);return {...response,success: true,};} catch (error) {const errorMessage = error instanceof Error ? error.message : 'Unknown error';console.error('❌ Asset creation failed:', errorMessage);if (error instanceof AthenaIntelligenceError) {throw new Error(`API Error (${error.statusCode}): ${errorMessage}`);}throw new Error(`Asset creation failed: ${errorMessage}`);}}// Usage examplesasync function basicExamples() {// Create a spreadsheetconst spreadsheet = await createAsset('spreadsheet', 'Q1 2024 Sales Report');// Create a documentconst document = await createAsset('document', 'Meeting Notes');// Create a folderconst folder = await createAsset('folder', 'Project Alpha');}
Create Assets in Folders
Organize assets hierarchically with folders:
async function createAssetInFolder(assetType: AssetType,title: string,parentFolderId: string): Promise<AssetCreationResult> {try {const response = await client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});console.log(`✅ Created ${assetType} "${title}" in folder ${parentFolderId}`);return {...response,success: true,};} catch (error) {const errorMessage = error instanceof Error ? error.message : 'Unknown error';return {asset_id: '',title: title,asset_type: assetType,created_at: '',parent_folder_id: parentFolderId,success: false,error: errorMessage,};}}// Create organized folder structureasync function createProjectStructure(projectName: string) {console.log(`📁 Creating project structure for "${projectName}"...`);// Create main project folderconst projectFolder = await createAsset('folder', projectName);if (!projectFolder.success) {throw new Error(`Failed to create project folder: ${projectFolder.error}`);}console.log(`✅ Created project folder: ${projectFolder.asset_id}`);// Create subfoldersconst subfoldersToCreate = [{ name: 'Documents', type: 'folder' as const },{ name: 'Spreadsheets', type: 'folder' as const },{ name: 'Reports', type: 'folder' as const },];const subfolders = await Promise.all(subfoldersToCreate.map(subfolder =>createAssetInFolder(subfolder.type, subfolder.name, projectFolder.asset_id)));console.log(`✅ Created ${subfolders.filter(f => f.success).length} subfolders`);return {projectFolder,subfolders,};}
Batch Asset Creation
Create multiple assets efficiently with error handling:
async function createMultipleAssets(requests: CreateAssetRequest[]): Promise<BatchAssetResult> {console.log(`🔄 Creating ${requests.length} assets...`);const results = await Promise.allSettled(requests.map(async (req) => {try {const response = await client.assets.create({asset_type: req.asset_type,title: req.title,parent_folder_id: req.parent_folder_id,});return {...response,success: true,};} catch (error) {throw {request: req,error: error instanceof Error ? error.message : 'Unknown error',};}}));const successful: AssetCreationResult[] = [];const failed: Array<{ request: CreateAssetRequest; error: string }> = [];results.forEach((result) => {if (result.status === 'fulfilled') {successful.push(result.value);} else {failed.push(result.reason);}});console.log(`✅ Successfully created: ${successful.length}`);console.log(`❌ Failed: ${failed.length}`);return {successful,failed,totalCreated: successful.length,totalFailed: failed.length,};}// Example: Create multiple reportsasync function createQuarterlyReports() {const quarters = ['Q1', 'Q2', 'Q3', 'Q4'];const year = '2024';const requests: CreateAssetRequest[] = quarters.map(quarter => ({asset_type: 'spreadsheet',title: `${quarter} ${year} Sales Report`,}));const result = await createMultipleAssets(requests);console.log('\n=== Batch Creation Results ===');console.log(`Total created: ${result.totalCreated}`);console.log(`Total failed: ${result.totalFailed}`);if (result.failed.length > 0) {console.log('\nFailed creations:');result.failed.forEach(({ request, error }) => {console.log(` - ${request.title}: ${error}`);});}return result;}
Advanced Folder Organization
Create complex folder hierarchies:
interface FolderStructure {name: string;type: AssetType;children?: FolderStructure[];}interface CreatedAssetNode {asset_id: string;title: string;asset_type: string;children?: CreatedAssetNode[];}async function createFolderHierarchy(structure: FolderStructure,parentFolderId?: string): Promise<CreatedAssetNode> {// Create the current folder/assetconst response = await client.assets.create({asset_type: structure.type,title: structure.name,parent_folder_id: parentFolderId,});console.log(`✅ Created ${structure.type}: ${structure.name}`);const node: CreatedAssetNode = {asset_id: response.asset_id,title: response.title,asset_type: response.asset_type,};// Recursively create childrenif (structure.children && structure.children.length > 0) {const childNodes = await Promise.all(structure.children.map(child =>createFolderHierarchy(child, response.asset_id)));node.children = childNodes;}return node;}// Example: Create a complete project structureasync function createCompleteProjectStructure() {const projectStructure: FolderStructure = {name: 'Product Launch 2024',type: 'folder',children: [{name: 'Research',type: 'folder',children: [{ name: 'Market Analysis', type: 'spreadsheet' },{ name: 'Competitor Research', type: 'document' },{ name: 'User Survey Results', type: 'spreadsheet' },],},{name: 'Planning',type: 'folder',children: [{ name: 'Timeline', type: 'spreadsheet' },{ name: 'Budget', type: 'spreadsheet' },{ name: 'Strategy Doc', type: 'document' },],},{name: 'Deliverables',type: 'folder',children: [{ name: 'Launch Plan', type: 'document' },{ name: 'Marketing Materials', type: 'folder' },],},],};console.log('🏗️ Creating complete project structure...');const result = await createFolderHierarchy(projectStructure);console.log('🎉 Project structure created successfully!');return result;}
Error Handling and Retry Logic
Implement comprehensive error handling for production:
async function createAssetWithRetry(assetType: AssetType,title: string,parentFolderId?: string,maxRetries: number = 3): Promise<AssetCreationResult> {let lastError: Error | null = null;for (let attempt = 1; attempt <= maxRetries; attempt++) {try {console.log(`🔄 Attempt ${attempt}/${maxRetries} to create ${assetType}`);const response = await client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});console.log(`✅ Asset created successfully on attempt ${attempt}`);return {...response,success: true,};} catch (error) {lastError = error as Error;// Don't retry on client errors (4xx)if (error instanceof AthenaIntelligenceError) {if (error.statusCode >= 400 && error.statusCode < 500) {console.error(`❌ Client error (${error.statusCode}): ${error.message}`);return {asset_id: '',title: title,asset_type: assetType,created_at: '',parent_folder_id: parentFolderId,success: false,error: `Client error (${error.statusCode}): ${error.message}`,};}}// Retry on server errors or network issuesif (attempt < maxRetries) {const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);console.log(`⏳ Waiting ${delay}ms before retry...`);await new Promise(resolve => setTimeout(resolve, delay));}}}console.error('❌ Asset creation failed after all retry attempts');return {asset_id: '',title: title,asset_type: assetType,created_at: '',parent_folder_id: parentFolderId,success: false,error: lastError?.message || 'Creation failed after all retries',};}
Type-Safe Asset Factory
Create a factory class for managing asset creation:
class AssetFactory {private client: AthenaIntelligenceClient;constructor(apiKey: string, baseUrl?: string) {this.client = new AthenaIntelligenceClient({apiKey,baseUrl,});}async createSpreadsheet(title: string,parentFolderId?: string): Promise<AthenaIntelligence.CreateAssetResponseOut> {return this.createAsset('spreadsheet', title, parentFolderId);}async createDocument(title: string,parentFolderId?: string): Promise<AthenaIntelligence.CreateAssetResponseOut> {return this.createAsset('document', title, parentFolderId);}async createFolder(title: string,parentFolderId?: string): Promise<AthenaIntelligence.CreateAssetResponseOut> {return this.createAsset('folder', title, parentFolderId);}private async createAsset(assetType: AssetType,title: string,parentFolderId?: string): Promise<AthenaIntelligence.CreateAssetResponseOut> {try {const response = await this.client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});console.log(`✅ Created ${assetType}: ${response.title} (${response.asset_id})`);return response;} catch (error) {if (error instanceof AthenaIntelligenceError) {throw new Error(`Failed to create ${assetType}: ${error.statusCode} - ${error.message}`);}throw error;}}async createBatch(requests: Array<{type: AssetType;title: string;parentFolderId?: string;}>): Promise<BatchAssetResult> {console.log(`🔄 Creating ${requests.length} assets in batch...`);const results = await Promise.allSettled(requests.map(req =>this.createAsset(req.type, req.title, req.parentFolderId)));const successful: AssetCreationResult[] = [];const failed: Array<{ request: CreateAssetRequest; error: string }> = [];results.forEach((result, index) => {if (result.status === 'fulfilled') {successful.push({...result.value,success: true,});} else {failed.push({request: {asset_type: requests[index].type,title: requests[index].title,parent_folder_id: requests[index].parentFolderId,},error: result.reason instanceof Error ? result.reason.message : 'Unknown error',});}});return {successful,failed,totalCreated: successful.length,totalFailed: failed.length,};}}// Usageasync function factoryExample() {const factory = new AssetFactory(process.env.ATHENA_API_KEY!);// Create individual assetsconst spreadsheet = await factory.createSpreadsheet('Sales Dashboard');const document = await factory.createDocument('Product Requirements');const folder = await factory.createFolder('Marketing Campaign');// Create batch of assetsconst batchResult = await factory.createBatch([{ type: 'spreadsheet', title: 'Budget 2024' },{ type: 'document', title: 'Project Brief' },{ type: 'folder', title: 'Assets' },]);console.log(`Created ${batchResult.totalCreated} assets`);}
Complete Production Example
Here’s a production-ready asset management class:
import type { AthenaIntelligence } from '@athenaintel/sdk';import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk';interface AssetCreationOptions {retries?: number;timeout?: number;throwOnError?: boolean;}class AssetManager {private client: AthenaIntelligenceClient;private defaultRetries: number = 3;constructor(apiKey: string, baseUrl?: string) {this.client = new AthenaIntelligenceClient({apiKey,baseUrl,});}/*** Create an asset with comprehensive error handling*/async create(assetType: AssetType,title: string,options: AssetCreationOptions & { parentFolderId?: string } = {}): Promise<AssetCreationResult> {const {retries = this.defaultRetries,parentFolderId,throwOnError = false,} = options;let attempt = 0;let lastError: Error | undefined;while (attempt < retries) {try {attempt++;console.log(`📝 Creating ${assetType} (attempt ${attempt}/${retries})...`);const response = await this.client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});console.log(`✅ Asset created: ${response.asset_id}`);return {...response,success: true,};} catch (error) {lastError = error as Error;// Handle specific error casesif (error instanceof AthenaIntelligenceError) {// Don't retry on client errorsif (error.statusCode >= 400 && error.statusCode < 500) {console.error(`❌ Client error (${error.statusCode}): ${error.message}`);if (throwOnError) {throw error;}return {asset_id: '',title: title,asset_type: assetType,created_at: '',parent_folder_id: parentFolderId,success: false,error: `Client error (${error.statusCode}): ${error.message}`,};}}console.warn(`⚠️ Attempt ${attempt} failed:`, lastError.message);// Wait before retry with exponential backoffif (attempt < retries) {const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);await new Promise(resolve => setTimeout(resolve, delay));}}}const errorMessage = lastError?.message || 'Unknown error';if (throwOnError) {throw new Error(`Asset creation failed after ${retries} attempts: ${errorMessage}`);}return {asset_id: '',title: title,asset_type: assetType,created_at: '',parent_folder_id: parentFolderId,success: false,error: `Failed after ${retries} attempts: ${errorMessage}`,};}/*** Create a workspace structure from a template*/async createFromTemplate(template: FolderStructure,parentFolderId?: string): Promise<CreatedAssetNode> {console.log(`🏗️ Creating structure from template: ${template.name}`);const response = await this.create(template.type, template.name, {parentFolderId,throwOnError: true,});const node: CreatedAssetNode = {asset_id: response.asset_id,title: response.title,asset_type: response.asset_type,};if (template.children && template.children.length > 0) {console.log(`📂 Creating ${template.children.length} children...`);const childNodes = await Promise.all(template.children.map(child =>this.createFromTemplate(child, response.asset_id)));node.children = childNodes;}return node;}/*** Create multiple assets with progress tracking*/async createBatchWithProgress(requests: CreateAssetRequest[],onProgress?: (completed: number, total: number) => void): Promise<BatchAssetResult> {const total = requests.length;console.log(`🔄 Creating ${total} assets with progress tracking...`);const successful: AssetCreationResult[] = [];const failed: Array<{ request: CreateAssetRequest; error: string }> = [];for (let i = 0; i < requests.length; i++) {const req = requests[i];try {const response = await this.client.assets.create({asset_type: req.asset_type,title: req.title,parent_folder_id: req.parent_folder_id,});successful.push({...response,success: true,});if (onProgress) {onProgress(successful.length, total);}} catch (error) {const errorMessage = error instanceof Error ? error.message : 'Unknown error';failed.push({request: req,error: errorMessage,});}}return {successful,failed,totalCreated: successful.length,totalFailed: failed.length,};}}// Complete usage exampleasync function productionExample() {const manager = new AssetManager(process.env.ATHENA_API_KEY!);try {// Create a single asset with retryconst document = await manager.create('document','Important Document',{ retries: 5 });if (document.success) {console.log('✅ Document created:', document.asset_id);}// Create from templateconst projectTemplate: FolderStructure = {name: 'Q1 2024 Initiative',type: 'folder',children: [{name: 'Planning',type: 'folder',children: [{ name: 'Project Plan', type: 'document' },{ name: 'Budget Tracker', type: 'spreadsheet' },],},{name: 'Execution',type: 'folder',children: [{ name: 'Tasks', type: 'spreadsheet' },{ name: 'Progress Report', type: 'document' },],},],};const project = await manager.createFromTemplate(projectTemplate);console.log('✅ Project structure created:', project.asset_id);// Batch creation with progressconst batchRequests: CreateAssetRequest[] = [{ asset_type: 'spreadsheet', title: 'Sales Data' },{ asset_type: 'document', title: 'Analysis Report' },{ asset_type: 'spreadsheet', title: 'Metrics Dashboard' },{ asset_type: 'document', title: 'Executive Summary' },];const batchResult = await manager.createBatchWithProgress(batchRequests,(completed, total) => {console.log(`📊 Progress: ${completed}/${total} assets created`);});console.log('\n=== Batch Results ===');console.log(`✅ Created: ${batchResult.totalCreated}`);console.log(`❌ Failed: ${batchResult.totalFailed}`);if (batchResult.failed.length > 0) {console.log('\nFailed assets:');batchResult.failed.forEach(({ request, error }) => {console.log(` - ${request.title}: ${error}`);});}} catch (error) {console.error('💥 Production example failed:', error);throw error;}}// Run the production exampleproductionExample().catch(console.error);
Validation and Best Practices
Implement validation for asset creation:
const VALID_ASSET_TYPES: AssetType[] = ['spreadsheet','document','folder',];function validateAssetType(assetType: string): asserts assetType is AssetType {if (!VALID_ASSET_TYPES.includes(assetType as AssetType)) {throw new Error(`Invalid asset type: ${assetType}. Valid types: ${VALID_ASSET_TYPES.join(', ')}`);}}function validateTitle(title: string): void {if (!title || title.trim().length === 0) {throw new Error('Asset title cannot be empty');}if (title.length > 255) {throw new Error('Asset title cannot exceed 255 characters');}}async function createValidatedAsset(assetType: string,title: string,parentFolderId?: string): Promise<AthenaIntelligence.CreateAssetResponseOut> {// Validate inputsvalidateAssetType(assetType);validateTitle(title);// If parent folder is specified, verify it exists (optional)if (parentFolderId) {try {await client.assets.get(parentFolderId);} catch (error) {if (error instanceof AthenaIntelligenceError && error.statusCode === 404) {throw new Error(`Parent folder not found: ${parentFolderId}`);}// If it's another error, continue anyway (might be permissions issue)}}// Create the assetreturn client.assets.create({asset_type: assetType,title: title,parent_folder_id: parentFolderId,});}
Workflow Integration Example
Integrate asset creation into a larger workflow:
interface WorkflowConfig {projectName: string;documentCount: number;spreadsheetCount: number;createSubfolders: boolean;}async function createProjectWorkflow(config: WorkflowConfig): Promise<{projectFolder: AssetCreationResult;documents: AssetCreationResult[];spreadsheets: AssetCreationResult[];subfolders?: AssetCreationResult[];}> {console.log(`🚀 Starting project workflow: ${config.projectName}`);// Step 1: Create main project folderconsole.log('📁 Step 1: Creating project folder...');const projectFolder = await createAssetWithRetry('folder',config.projectName);if (!projectFolder.success) {throw new Error(`Failed to create project folder: ${projectFolder.error}`);}console.log(`✅ Project folder created: ${projectFolder.asset_id}`);// Step 2: Create subfolders if requestedlet subfolders: AssetCreationResult[] | undefined;if (config.createSubfolders) {console.log('📂 Step 2: Creating subfolders...');const subfolderRequests: CreateAssetRequest[] = [{ asset_type: 'folder', title: 'Documents', parent_folder_id: projectFolder.asset_id },{ asset_type: 'folder', title: 'Spreadsheets', parent_folder_id: projectFolder.asset_id },{ asset_type: 'folder', title: 'Reports', parent_folder_id: projectFolder.asset_id },];const result = await createMultipleAssets(subfolderRequests);subfolders = result.successful;console.log(`✅ Created ${subfolders.length} subfolders`);}// Step 3: Create documentsconsole.log(`📄 Step 3: Creating ${config.documentCount} documents...`);const documentRequests: CreateAssetRequest[] = Array.from({ length: config.documentCount },(_, i) => ({asset_type: 'document',title: `Document ${i + 1}`,parent_folder_id: projectFolder.asset_id,}));const documentsResult = await createMultipleAssets(documentRequests);// Step 4: Create spreadsheetsconsole.log(`📊 Step 4: Creating ${config.spreadsheetCount} spreadsheets...`);const spreadsheetRequests: CreateAssetRequest[] = Array.from({ length: config.spreadsheetCount },(_, i) => ({asset_type: 'spreadsheet',title: `Spreadsheet ${i + 1}`,parent_folder_id: projectFolder.asset_id,}));const spreadsheetsResult = await createMultipleAssets(spreadsheetRequests);console.log('\n=== Workflow Complete ===');console.log(`Project Folder: ${projectFolder.asset_id}`);console.log(`Documents Created: ${documentsResult.totalCreated}`);console.log(`Spreadsheets Created: ${spreadsheetsResult.totalCreated}`);if (subfolders) {console.log(`Subfolders Created: ${subfolders.length}`);}return {projectFolder,documents: documentsResult.successful,spreadsheets: spreadsheetsResult.successful,subfolders,};}// Run workflowasync function main() {const workflow = await createProjectWorkflow({projectName: 'Product Launch Q1 2024',documentCount: 5,spreadsheetCount: 3,createSubfolders: true,});console.log('🎉 Workflow completed successfully!');console.log(`Total assets created: ${workflow.documents.length +workflow.spreadsheets.length +(workflow.subfolders?.length || 0) +1 // project folder}`);}main().catch(console.error);
Key Recommendations
- Use proper TypeScript types - Define interfaces instead of using
any - Implement retry logic - Use exponential backoff for resilient operations
- Validate inputs - Check asset types and titles before API calls
- Handle errors gracefully - Distinguish between client and server errors
- Organize with folders - Create hierarchical structures for better organization
- Batch when possible - Use
Promise.allfor parallel creation - Log progress - Provide visibility into long-running operations
- Set reasonable timeouts - Prevent hanging operations
Asset Types Supported: This endpoint currently supports three core asset types:
spreadsheet- Create Athena spreadsheets with real-time collaborationdocument- Create Athena documents for rich text editingfolder- Create folders for organizing your workspace
