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 collaboration
  • document - Athena document for rich text editing
  • folder - 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
1

Install Package

pnpm add @athenaintel/sdk
2

Set Up Client

import type { AthenaIntelligence } from '@athenaintel/sdk';
import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk';
// Production client setup
const 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 development
const devClient = new AthenaIntelligenceClient({
apiKey: process.env.ATHENA_API_KEY,
baseUrl: 'http://localhost:8000',
});
3

TypeScript Type Definitions

Define proper interfaces for type safety:

// Asset creation request
interface CreateAssetRequest {
asset_type: string;
parent_folder_id?: string;
title?: string;
}
// Asset creation result
interface AssetCreationResult {
asset_id: string;
title: string;
asset_type: string;
created_at: string;
parent_folder_id?: string;
success: boolean;
error?: string;
}
// Batch asset creation result
interface BatchAssetResult {
successful: AssetCreationResult[];
failed: Array<{
request: CreateAssetRequest;
error: string;
}>;
totalCreated: number;
totalFailed: number;
}
// Supported asset types
type AssetType =
| 'spreadsheet'
| 'document'
| 'folder';
4

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 examples
async function basicExamples() {
// Create a spreadsheet
const spreadsheet = await createAsset('spreadsheet', 'Q1 2024 Sales Report');
// Create a document
const document = await createAsset('document', 'Meeting Notes');
// Create a folder
const folder = await createAsset('folder', 'Project Alpha');
}
5

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 structure
async function createProjectStructure(projectName: string) {
console.log(`📁 Creating project structure for "${projectName}"...`);
// Create main project folder
const 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 subfolders
const 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,
};
}
6

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 reports
async 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;
}
7

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/asset
const 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 children
if (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 structure
async 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;
}
8

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 issues
if (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',
};
}
9

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,
};
}
}
// Usage
async function factoryExample() {
const factory = new AssetFactory(process.env.ATHENA_API_KEY!);
// Create individual assets
const spreadsheet = await factory.createSpreadsheet('Sales Dashboard');
const document = await factory.createDocument('Product Requirements');
const folder = await factory.createFolder('Marketing Campaign');
// Create batch of assets
const batchResult = await factory.createBatch([
{ type: 'spreadsheet', title: 'Budget 2024' },
{ type: 'document', title: 'Project Brief' },
{ type: 'folder', title: 'Assets' },
]);
console.log(`Created ${batchResult.totalCreated} assets`);
}
10

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 cases
if (error instanceof AthenaIntelligenceError) {
// Don't retry on client errors
if (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 backoff
if (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 example
async function productionExample() {
const manager = new AssetManager(process.env.ATHENA_API_KEY!);
try {
// Create a single asset with retry
const document = await manager.create(
'document',
'Important Document',
{ retries: 5 }
);
if (document.success) {
console.log('✅ Document created:', document.asset_id);
}
// Create from template
const 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 progress
const 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 example
productionExample().catch(console.error);
11

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 inputs
validateAssetType(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 asset
return client.assets.create({
asset_type: assetType,
title: title,
parent_folder_id: parentFolderId,
});
}
12

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 folder
console.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 requested
let 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 documents
console.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 spreadsheets
console.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 workflow
async 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);
13

Key Recommendations

  1. Use proper TypeScript types - Define interfaces instead of using any
  2. Implement retry logic - Use exponential backoff for resilient operations
  3. Validate inputs - Check asset types and titles before API calls
  4. Handle errors gracefully - Distinguish between client and server errors
  5. Organize with folders - Create hierarchical structures for better organization
  6. Batch when possible - Use Promise.all for parallel creation
  7. Log progress - Provide visibility into long-running operations
  8. Set reasonable timeouts - Prevent hanging operations

Asset Types Supported: This endpoint currently supports three core asset types:

  • spreadsheet - Create Athena spreadsheets with real-time collaboration
  • document - Create Athena documents for rich text editing
  • folder - Create folders for organizing your workspace