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 athena-intelligence
2

Set Up Client

1import type { AthenaIntelligence } from 'athena-intelligence';
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'athena-intelligence';
3
4// Production client setup
5const client = new AthenaIntelligenceClient({
6 apiKey: process.env.ATHENA_API_KEY,
7});
8
9// Custom API endpoint (if needed)
10const customClient = new AthenaIntelligenceClient({
11 apiKey: process.env.ATHENA_API_KEY,
12 baseUrl: 'https://your-custom-api.example.com',
13});
14
15// Local development
16const devClient = new AthenaIntelligenceClient({
17 apiKey: process.env.ATHENA_API_KEY,
18 baseUrl: 'http://localhost:8000',
19});
3

TypeScript Type Definitions

Define proper interfaces for type safety:

1// Asset creation request
2interface CreateAssetRequest {
3 asset_type: string;
4 parent_folder_id?: string;
5 title?: string;
6}
7
8// Asset creation result
9interface AssetCreationResult {
10 asset_id: string;
11 title: string;
12 asset_type: string;
13 created_at: string;
14 parent_folder_id?: string;
15 success: boolean;
16 error?: string;
17}
18
19// Batch asset creation result
20interface BatchAssetResult {
21 successful: AssetCreationResult[];
22 failed: Array<{
23 request: CreateAssetRequest;
24 error: string;
25 }>;
26 totalCreated: number;
27 totalFailed: number;
28}
29
30// Supported asset types
31type AssetType =
32 | 'spreadsheet'
33 | 'document'
34 | 'folder';
4

Basic Asset Creation

Create a single asset with proper error handling:

1async function createAsset(
2 assetType: AssetType,
3 title?: string,
4 parentFolderId?: string
5): Promise<AssetCreationResult> {
6 try {
7 console.log(`📝 Creating ${assetType}...`);
8
9 const response = await client.assets.create({
10 asset_type: assetType,
11 title: title,
12 parent_folder_id: parentFolderId,
13 });
14
15 console.log('✅ Asset created successfully');
16 console.log('Asset ID:', response.asset_id);
17 console.log('Title:', response.title);
18 console.log('Created at:', response.created_at);
19
20 return {
21 ...response,
22 success: true,
23 };
24 } catch (error) {
25 const errorMessage = error instanceof Error ? error.message : 'Unknown error';
26 console.error('❌ Asset creation failed:', errorMessage);
27
28 if (error instanceof AthenaIntelligenceError) {
29 throw new Error(`API Error (${error.statusCode}): ${errorMessage}`);
30 }
31
32 throw new Error(`Asset creation failed: ${errorMessage}`);
33 }
34}
35
36// Usage examples
37async function basicExamples() {
38 // Create a spreadsheet
39 const spreadsheet = await createAsset('spreadsheet', 'Q1 2024 Sales Report');
40
41 // Create a document
42 const document = await createAsset('document', 'Meeting Notes');
43
44 // Create a folder
45 const folder = await createAsset('folder', 'Project Alpha');
46}
5

Create Assets in Folders

Organize assets hierarchically with folders:

1async function createAssetInFolder(
2 assetType: AssetType,
3 title: string,
4 parentFolderId: string
5): Promise<AssetCreationResult> {
6 try {
7 const response = await client.assets.create({
8 asset_type: assetType,
9 title: title,
10 parent_folder_id: parentFolderId,
11 });
12
13 console.log(`✅ Created ${assetType} "${title}" in folder ${parentFolderId}`);
14
15 return {
16 ...response,
17 success: true,
18 };
19 } catch (error) {
20 const errorMessage = error instanceof Error ? error.message : 'Unknown error';
21 return {
22 asset_id: '',
23 title: title,
24 asset_type: assetType,
25 created_at: '',
26 parent_folder_id: parentFolderId,
27 success: false,
28 error: errorMessage,
29 };
30 }
31}
32
33// Create organized folder structure
34async function createProjectStructure(projectName: string) {
35 console.log(`📁 Creating project structure for "${projectName}"...`);
36
37 // Create main project folder
38 const projectFolder = await createAsset('folder', projectName);
39
40 if (!projectFolder.success) {
41 throw new Error(`Failed to create project folder: ${projectFolder.error}`);
42 }
43
44 console.log(`✅ Created project folder: ${projectFolder.asset_id}`);
45
46 // Create subfolders
47 const subfoldersToCreate = [
48 { name: 'Documents', type: 'folder' as const },
49 { name: 'Spreadsheets', type: 'folder' as const },
50 { name: 'Reports', type: 'folder' as const },
51 ];
52
53 const subfolders = await Promise.all(
54 subfoldersToCreate.map(subfolder =>
55 createAssetInFolder(subfolder.type, subfolder.name, projectFolder.asset_id)
56 )
57 );
58
59 console.log(`✅ Created ${subfolders.filter(f => f.success).length} subfolders`);
60
61 return {
62 projectFolder,
63 subfolders,
64 };
65}
6

Batch Asset Creation

Create multiple assets efficiently with error handling:

1async function createMultipleAssets(
2 requests: CreateAssetRequest[]
3): Promise<BatchAssetResult> {
4 console.log(`🔄 Creating ${requests.length} assets...`);
5
6 const results = await Promise.allSettled(
7 requests.map(async (req) => {
8 try {
9 const response = await client.assets.create({
10 asset_type: req.asset_type,
11 title: req.title,
12 parent_folder_id: req.parent_folder_id,
13 });
14
15 return {
16 ...response,
17 success: true,
18 };
19 } catch (error) {
20 throw {
21 request: req,
22 error: error instanceof Error ? error.message : 'Unknown error',
23 };
24 }
25 })
26 );
27
28 const successful: AssetCreationResult[] = [];
29 const failed: Array<{ request: CreateAssetRequest; error: string }> = [];
30
31 results.forEach((result) => {
32 if (result.status === 'fulfilled') {
33 successful.push(result.value);
34 } else {
35 failed.push(result.reason);
36 }
37 });
38
39 console.log(`✅ Successfully created: ${successful.length}`);
40 console.log(`❌ Failed: ${failed.length}`);
41
42 return {
43 successful,
44 failed,
45 totalCreated: successful.length,
46 totalFailed: failed.length,
47 };
48}
49
50// Example: Create multiple reports
51async function createQuarterlyReports() {
52 const quarters = ['Q1', 'Q2', 'Q3', 'Q4'];
53 const year = '2024';
54
55 const requests: CreateAssetRequest[] = quarters.map(quarter => ({
56 asset_type: 'spreadsheet',
57 title: `${quarter} ${year} Sales Report`,
58 }));
59
60 const result = await createMultipleAssets(requests);
61
62 console.log('\n=== Batch Creation Results ===');
63 console.log(`Total created: ${result.totalCreated}`);
64 console.log(`Total failed: ${result.totalFailed}`);
65
66 if (result.failed.length > 0) {
67 console.log('\nFailed creations:');
68 result.failed.forEach(({ request, error }) => {
69 console.log(` - ${request.title}: ${error}`);
70 });
71 }
72
73 return result;
74}
7

Advanced Folder Organization

Create complex folder hierarchies:

1interface FolderStructure {
2 name: string;
3 type: AssetType;
4 children?: FolderStructure[];
5}
6
7interface CreatedAssetNode {
8 asset_id: string;
9 title: string;
10 asset_type: string;
11 children?: CreatedAssetNode[];
12}
13
14async function createFolderHierarchy(
15 structure: FolderStructure,
16 parentFolderId?: string
17): Promise<CreatedAssetNode> {
18 // Create the current folder/asset
19 const response = await client.assets.create({
20 asset_type: structure.type,
21 title: structure.name,
22 parent_folder_id: parentFolderId,
23 });
24
25 console.log(`✅ Created ${structure.type}: ${structure.name}`);
26
27 const node: CreatedAssetNode = {
28 asset_id: response.asset_id,
29 title: response.title,
30 asset_type: response.asset_type,
31 };
32
33 // Recursively create children
34 if (structure.children && structure.children.length > 0) {
35 const childNodes = await Promise.all(
36 structure.children.map(child =>
37 createFolderHierarchy(child, response.asset_id)
38 )
39 );
40 node.children = childNodes;
41 }
42
43 return node;
44}
45
46// Example: Create a complete project structure
47async function createCompleteProjectStructure() {
48 const projectStructure: FolderStructure = {
49 name: 'Product Launch 2024',
50 type: 'folder',
51 children: [
52 {
53 name: 'Research',
54 type: 'folder',
55 children: [
56 { name: 'Market Analysis', type: 'spreadsheet' },
57 { name: 'Competitor Research', type: 'document' },
58 { name: 'User Survey Results', type: 'spreadsheet' },
59 ],
60 },
61 {
62 name: 'Planning',
63 type: 'folder',
64 children: [
65 { name: 'Timeline', type: 'spreadsheet' },
66 { name: 'Budget', type: 'spreadsheet' },
67 { name: 'Strategy Doc', type: 'document' },
68 ],
69 },
70 {
71 name: 'Deliverables',
72 type: 'folder',
73 children: [
74 { name: 'Launch Plan', type: 'document' },
75 { name: 'Marketing Materials', type: 'folder' },
76 ],
77 },
78 ],
79 };
80
81 console.log('🏗️ Creating complete project structure...');
82 const result = await createFolderHierarchy(projectStructure);
83 console.log('🎉 Project structure created successfully!');
84
85 return result;
86}
8

Error Handling and Retry Logic

Implement comprehensive error handling for production:

1async function createAssetWithRetry(
2 assetType: AssetType,
3 title: string,
4 parentFolderId?: string,
5 maxRetries: number = 3
6): Promise<AssetCreationResult> {
7 let lastError: Error | null = null;
8
9 for (let attempt = 1; attempt <= maxRetries; attempt++) {
10 try {
11 console.log(`🔄 Attempt ${attempt}/${maxRetries} to create ${assetType}`);
12
13 const response = await client.assets.create({
14 asset_type: assetType,
15 title: title,
16 parent_folder_id: parentFolderId,
17 });
18
19 console.log(`✅ Asset created successfully on attempt ${attempt}`);
20
21 return {
22 ...response,
23 success: true,
24 };
25 } catch (error) {
26 lastError = error as Error;
27
28 // Don't retry on client errors (4xx)
29 if (error instanceof AthenaIntelligenceError) {
30 if (error.statusCode >= 400 && error.statusCode < 500) {
31 console.error(`❌ Client error (${error.statusCode}): ${error.message}`);
32 return {
33 asset_id: '',
34 title: title,
35 asset_type: assetType,
36 created_at: '',
37 parent_folder_id: parentFolderId,
38 success: false,
39 error: `Client error (${error.statusCode}): ${error.message}`,
40 };
41 }
42 }
43
44 // Retry on server errors or network issues
45 if (attempt < maxRetries) {
46 const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
47 console.log(`⏳ Waiting ${delay}ms before retry...`);
48 await new Promise(resolve => setTimeout(resolve, delay));
49 }
50 }
51 }
52
53 console.error('❌ Asset creation failed after all retry attempts');
54
55 return {
56 asset_id: '',
57 title: title,
58 asset_type: assetType,
59 created_at: '',
60 parent_folder_id: parentFolderId,
61 success: false,
62 error: lastError?.message || 'Creation failed after all retries',
63 };
64}
9

Type-Safe Asset Factory

Create a factory class for managing asset creation:

1class AssetFactory {
2 private client: AthenaIntelligenceClient;
3
4 constructor(apiKey: string, baseUrl?: string) {
5 this.client = new AthenaIntelligenceClient({
6 apiKey,
7 baseUrl,
8 });
9 }
10
11 async createSpreadsheet(
12 title: string,
13 parentFolderId?: string
14 ): Promise<AthenaIntelligence.CreateAssetResponseOut> {
15 return this.createAsset('spreadsheet', title, parentFolderId);
16 }
17
18 async createDocument(
19 title: string,
20 parentFolderId?: string
21 ): Promise<AthenaIntelligence.CreateAssetResponseOut> {
22 return this.createAsset('document', title, parentFolderId);
23 }
24
25 async createFolder(
26 title: string,
27 parentFolderId?: string
28 ): Promise<AthenaIntelligence.CreateAssetResponseOut> {
29 return this.createAsset('folder', title, parentFolderId);
30 }
31
32 private async createAsset(
33 assetType: AssetType,
34 title: string,
35 parentFolderId?: string
36 ): Promise<AthenaIntelligence.CreateAssetResponseOut> {
37 try {
38 const response = await this.client.assets.create({
39 asset_type: assetType,
40 title: title,
41 parent_folder_id: parentFolderId,
42 });
43
44 console.log(`✅ Created ${assetType}: ${response.title} (${response.asset_id})`);
45
46 return response;
47 } catch (error) {
48 if (error instanceof AthenaIntelligenceError) {
49 throw new Error(
50 `Failed to create ${assetType}: ${error.statusCode} - ${error.message}`
51 );
52 }
53 throw error;
54 }
55 }
56
57 async createBatch(
58 requests: Array<{
59 type: AssetType;
60 title: string;
61 parentFolderId?: string;
62 }>
63 ): Promise<BatchAssetResult> {
64 console.log(`🔄 Creating ${requests.length} assets in batch...`);
65
66 const results = await Promise.allSettled(
67 requests.map(req =>
68 this.createAsset(req.type, req.title, req.parentFolderId)
69 )
70 );
71
72 const successful: AssetCreationResult[] = [];
73 const failed: Array<{ request: CreateAssetRequest; error: string }> = [];
74
75 results.forEach((result, index) => {
76 if (result.status === 'fulfilled') {
77 successful.push({
78 ...result.value,
79 success: true,
80 });
81 } else {
82 failed.push({
83 request: {
84 asset_type: requests[index].type,
85 title: requests[index].title,
86 parent_folder_id: requests[index].parentFolderId,
87 },
88 error: result.reason instanceof Error ? result.reason.message : 'Unknown error',
89 });
90 }
91 });
92
93 return {
94 successful,
95 failed,
96 totalCreated: successful.length,
97 totalFailed: failed.length,
98 };
99 }
100}
101
102// Usage
103async function factoryExample() {
104 const factory = new AssetFactory(process.env.ATHENA_API_KEY!);
105
106 // Create individual assets
107 const spreadsheet = await factory.createSpreadsheet('Sales Dashboard');
108 const document = await factory.createDocument('Product Requirements');
109 const folder = await factory.createFolder('Marketing Campaign');
110
111 // Create batch of assets
112 const batchResult = await factory.createBatch([
113 { type: 'spreadsheet', title: 'Budget 2024' },
114 { type: 'document', title: 'Project Brief' },
115 { type: 'folder', title: 'Assets' },
116 ]);
117
118 console.log(`Created ${batchResult.totalCreated} assets`);
119}
10

Complete Production Example

Here’s a production-ready asset management class:

1import type { AthenaIntelligence } from 'athena-intelligence';
2import { AthenaIntelligenceClient, AthenaIntelligenceError } from 'athena-intelligence';
3
4interface AssetCreationOptions {
5 retries?: number;
6 timeout?: number;
7 throwOnError?: boolean;
8}
9
10class AssetManager {
11 private client: AthenaIntelligenceClient;
12 private defaultRetries: number = 3;
13
14 constructor(apiKey: string, baseUrl?: string) {
15 this.client = new AthenaIntelligenceClient({
16 apiKey,
17 baseUrl,
18 });
19 }
20
21 /**
22 * Create an asset with comprehensive error handling
23 */
24 async create(
25 assetType: AssetType,
26 title: string,
27 options: AssetCreationOptions & { parentFolderId?: string } = {}
28 ): Promise<AssetCreationResult> {
29 const {
30 retries = this.defaultRetries,
31 parentFolderId,
32 throwOnError = false,
33 } = options;
34
35 let attempt = 0;
36 let lastError: Error | undefined;
37
38 while (attempt < retries) {
39 try {
40 attempt++;
41 console.log(`📝 Creating ${assetType} (attempt ${attempt}/${retries})...`);
42
43 const response = await this.client.assets.create({
44 asset_type: assetType,
45 title: title,
46 parent_folder_id: parentFolderId,
47 });
48
49 console.log(`✅ Asset created: ${response.asset_id}`);
50
51 return {
52 ...response,
53 success: true,
54 };
55 } catch (error) {
56 lastError = error as Error;
57
58 // Handle specific error cases
59 if (error instanceof AthenaIntelligenceError) {
60 // Don't retry on client errors
61 if (error.statusCode >= 400 && error.statusCode < 500) {
62 console.error(`❌ Client error (${error.statusCode}): ${error.message}`);
63
64 if (throwOnError) {
65 throw error;
66 }
67
68 return {
69 asset_id: '',
70 title: title,
71 asset_type: assetType,
72 created_at: '',
73 parent_folder_id: parentFolderId,
74 success: false,
75 error: `Client error (${error.statusCode}): ${error.message}`,
76 };
77 }
78 }
79
80 console.warn(`⚠️ Attempt ${attempt} failed:`, lastError.message);
81
82 // Wait before retry with exponential backoff
83 if (attempt < retries) {
84 const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
85 await new Promise(resolve => setTimeout(resolve, delay));
86 }
87 }
88 }
89
90 const errorMessage = lastError?.message || 'Unknown error';
91
92 if (throwOnError) {
93 throw new Error(`Asset creation failed after ${retries} attempts: ${errorMessage}`);
94 }
95
96 return {
97 asset_id: '',
98 title: title,
99 asset_type: assetType,
100 created_at: '',
101 parent_folder_id: parentFolderId,
102 success: false,
103 error: `Failed after ${retries} attempts: ${errorMessage}`,
104 };
105 }
106
107 /**
108 * Create a workspace structure from a template
109 */
110 async createFromTemplate(
111 template: FolderStructure,
112 parentFolderId?: string
113 ): Promise<CreatedAssetNode> {
114 console.log(`🏗️ Creating structure from template: ${template.name}`);
115
116 const response = await this.create(template.type, template.name, {
117 parentFolderId,
118 throwOnError: true,
119 });
120
121 const node: CreatedAssetNode = {
122 asset_id: response.asset_id,
123 title: response.title,
124 asset_type: response.asset_type,
125 };
126
127 if (template.children && template.children.length > 0) {
128 console.log(`📂 Creating ${template.children.length} children...`);
129
130 const childNodes = await Promise.all(
131 template.children.map(child =>
132 this.createFromTemplate(child, response.asset_id)
133 )
134 );
135
136 node.children = childNodes;
137 }
138
139 return node;
140 }
141
142 /**
143 * Create multiple assets with progress tracking
144 */
145 async createBatchWithProgress(
146 requests: CreateAssetRequest[],
147 onProgress?: (completed: number, total: number) => void
148 ): Promise<BatchAssetResult> {
149 const total = requests.length;
150 console.log(`🔄 Creating ${total} assets with progress tracking...`);
151
152 const successful: AssetCreationResult[] = [];
153 const failed: Array<{ request: CreateAssetRequest; error: string }> = [];
154
155 for (let i = 0; i < requests.length; i++) {
156 const req = requests[i];
157
158 try {
159 const response = await this.client.assets.create({
160 asset_type: req.asset_type,
161 title: req.title,
162 parent_folder_id: req.parent_folder_id,
163 });
164
165 successful.push({
166 ...response,
167 success: true,
168 });
169
170 if (onProgress) {
171 onProgress(successful.length, total);
172 }
173 } catch (error) {
174 const errorMessage = error instanceof Error ? error.message : 'Unknown error';
175 failed.push({
176 request: req,
177 error: errorMessage,
178 });
179 }
180 }
181
182 return {
183 successful,
184 failed,
185 totalCreated: successful.length,
186 totalFailed: failed.length,
187 };
188 }
189}
190
191// Complete usage example
192async function productionExample() {
193 const manager = new AssetManager(process.env.ATHENA_API_KEY!);
194
195 try {
196 // Create a single asset with retry
197 const document = await manager.create(
198 'document',
199 'Important Document',
200 { retries: 5 }
201 );
202
203 if (document.success) {
204 console.log('✅ Document created:', document.asset_id);
205 }
206
207 // Create from template
208 const projectTemplate: FolderStructure = {
209 name: 'Q1 2024 Initiative',
210 type: 'folder',
211 children: [
212 {
213 name: 'Planning',
214 type: 'folder',
215 children: [
216 { name: 'Project Plan', type: 'document' },
217 { name: 'Budget Tracker', type: 'spreadsheet' },
218 ],
219 },
220 {
221 name: 'Execution',
222 type: 'folder',
223 children: [
224 { name: 'Tasks', type: 'spreadsheet' },
225 { name: 'Progress Report', type: 'document' },
226 ],
227 },
228 ],
229 };
230
231 const project = await manager.createFromTemplate(projectTemplate);
232 console.log('✅ Project structure created:', project.asset_id);
233
234 // Batch creation with progress
235 const batchRequests: CreateAssetRequest[] = [
236 { asset_type: 'spreadsheet', title: 'Sales Data' },
237 { asset_type: 'document', title: 'Analysis Report' },
238 { asset_type: 'spreadsheet', title: 'Metrics Dashboard' },
239 { asset_type: 'document', title: 'Executive Summary' },
240 ];
241
242 const batchResult = await manager.createBatchWithProgress(
243 batchRequests,
244 (completed, total) => {
245 console.log(`📊 Progress: ${completed}/${total} assets created`);
246 }
247 );
248
249 console.log('\n=== Batch Results ===');
250 console.log(`✅ Created: ${batchResult.totalCreated}`);
251 console.log(`❌ Failed: ${batchResult.totalFailed}`);
252
253 if (batchResult.failed.length > 0) {
254 console.log('\nFailed assets:');
255 batchResult.failed.forEach(({ request, error }) => {
256 console.log(` - ${request.title}: ${error}`);
257 });
258 }
259 } catch (error) {
260 console.error('💥 Production example failed:', error);
261 throw error;
262 }
263}
264
265// Run the production example
266productionExample().catch(console.error);
11

Validation and Best Practices

Implement validation for asset creation:

1const VALID_ASSET_TYPES: AssetType[] = [
2 'spreadsheet',
3 'document',
4 'folder',
5];
6
7function validateAssetType(assetType: string): asserts assetType is AssetType {
8 if (!VALID_ASSET_TYPES.includes(assetType as AssetType)) {
9 throw new Error(
10 `Invalid asset type: ${assetType}. Valid types: ${VALID_ASSET_TYPES.join(', ')}`
11 );
12 }
13}
14
15function validateTitle(title: string): void {
16 if (!title || title.trim().length === 0) {
17 throw new Error('Asset title cannot be empty');
18 }
19
20 if (title.length > 255) {
21 throw new Error('Asset title cannot exceed 255 characters');
22 }
23}
24
25async function createValidatedAsset(
26 assetType: string,
27 title: string,
28 parentFolderId?: string
29): Promise<AthenaIntelligence.CreateAssetResponseOut> {
30 // Validate inputs
31 validateAssetType(assetType);
32 validateTitle(title);
33
34 // If parent folder is specified, verify it exists (optional)
35 if (parentFolderId) {
36 try {
37 await client.assets.get(parentFolderId);
38 } catch (error) {
39 if (error instanceof AthenaIntelligenceError && error.statusCode === 404) {
40 throw new Error(`Parent folder not found: ${parentFolderId}`);
41 }
42 // If it's another error, continue anyway (might be permissions issue)
43 }
44 }
45
46 // Create the asset
47 return client.assets.create({
48 asset_type: assetType,
49 title: title,
50 parent_folder_id: parentFolderId,
51 });
52}
12

Workflow Integration Example

Integrate asset creation into a larger workflow:

1interface WorkflowConfig {
2 projectName: string;
3 documentCount: number;
4 spreadsheetCount: number;
5 createSubfolders: boolean;
6}
7
8async function createProjectWorkflow(config: WorkflowConfig): Promise<{
9 projectFolder: AssetCreationResult;
10 documents: AssetCreationResult[];
11 spreadsheets: AssetCreationResult[];
12 subfolders?: AssetCreationResult[];
13}> {
14 console.log(`🚀 Starting project workflow: ${config.projectName}`);
15
16 // Step 1: Create main project folder
17 console.log('📁 Step 1: Creating project folder...');
18 const projectFolder = await createAssetWithRetry(
19 'folder',
20 config.projectName
21 );
22
23 if (!projectFolder.success) {
24 throw new Error(`Failed to create project folder: ${projectFolder.error}`);
25 }
26
27 console.log(`✅ Project folder created: ${projectFolder.asset_id}`);
28
29 // Step 2: Create subfolders if requested
30 let subfolders: AssetCreationResult[] | undefined;
31 if (config.createSubfolders) {
32 console.log('📂 Step 2: Creating subfolders...');
33 const subfolderRequests: CreateAssetRequest[] = [
34 { asset_type: 'folder', title: 'Documents', parent_folder_id: projectFolder.asset_id },
35 { asset_type: 'folder', title: 'Spreadsheets', parent_folder_id: projectFolder.asset_id },
36 { asset_type: 'folder', title: 'Reports', parent_folder_id: projectFolder.asset_id },
37 ];
38
39 const result = await createMultipleAssets(subfolderRequests);
40 subfolders = result.successful;
41 console.log(`✅ Created ${subfolders.length} subfolders`);
42 }
43
44 // Step 3: Create documents
45 console.log(`📄 Step 3: Creating ${config.documentCount} documents...`);
46 const documentRequests: CreateAssetRequest[] = Array.from(
47 { length: config.documentCount },
48 (_, i) => ({
49 asset_type: 'document',
50 title: `Document ${i + 1}`,
51 parent_folder_id: projectFolder.asset_id,
52 })
53 );
54
55 const documentsResult = await createMultipleAssets(documentRequests);
56
57 // Step 4: Create spreadsheets
58 console.log(`📊 Step 4: Creating ${config.spreadsheetCount} spreadsheets...`);
59 const spreadsheetRequests: CreateAssetRequest[] = Array.from(
60 { length: config.spreadsheetCount },
61 (_, i) => ({
62 asset_type: 'spreadsheet',
63 title: `Spreadsheet ${i + 1}`,
64 parent_folder_id: projectFolder.asset_id,
65 })
66 );
67
68 const spreadsheetsResult = await createMultipleAssets(spreadsheetRequests);
69
70 console.log('\n=== Workflow Complete ===');
71 console.log(`Project Folder: ${projectFolder.asset_id}`);
72 console.log(`Documents Created: ${documentsResult.totalCreated}`);
73 console.log(`Spreadsheets Created: ${spreadsheetsResult.totalCreated}`);
74 if (subfolders) {
75 console.log(`Subfolders Created: ${subfolders.length}`);
76 }
77
78 return {
79 projectFolder,
80 documents: documentsResult.successful,
81 spreadsheets: spreadsheetsResult.successful,
82 subfolders,
83 };
84}
85
86// Run workflow
87async function main() {
88 const workflow = await createProjectWorkflow({
89 projectName: 'Product Launch Q1 2024',
90 documentCount: 5,
91 spreadsheetCount: 3,
92 createSubfolders: true,
93 });
94
95 console.log('🎉 Workflow completed successfully!');
96 console.log(`Total assets created: ${
97 workflow.documents.length +
98 workflow.spreadsheets.length +
99 (workflow.subfolders?.length || 0) +
100 1 // project folder
101 }`);
102}
103
104main().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