> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.athenaintel.com/type-script-guides/upload-files/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server. # Upload Files > Upload and manage files using the TypeScript SDK This example shows how to upload files to your Athena workspace and manage them using the Tools API. You can upload various file types including PDFs, Excel files, CSVs, and images. Key features: * Upload files from Node.js filesystem or browser * Support for multiple file types (PDF, Excel, CSV, images) * File management with workspace browsing * Retrieve file content and metadata * Full TypeScript support with proper error handling ### Install Package #### pnpm ```bash pnpm add @athenaintel/sdk ``` #### bun ```bash bun add @athenaintel/sdk ``` #### yarn ```bash yarn add @athenaintel/sdk ``` #### npm ```bash npm install @athenaintel/sdk ``` ### Set Up Client ```typescript import { readFileSync } from 'node:fs'; import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk'; // Basic client setup (uses default production API) const client = new AthenaIntelligenceClient({ apiKey: process.env.ATHENA_API_KEY, }); // Override baseUrl for custom API endpoints const customClient = new AthenaIntelligenceClient({ apiKey: process.env.ATHENA_API_KEY, baseUrl: 'https://your-custom-api.example.com', // Custom API endpoint }); ``` ### Browse Workspace Contents Before uploading, you can list existing files and folders in your workspace. The `listContents` method provides a comprehensive view of your workspace structure: ```typescript // List entire workspace contents try { console.log('📂 Listing workspace contents…'); const workspaceContents = await client.tools.listContents(); // The response includes both structured data and a visual tree console.log('Workspace structure (ASCII tree):'); console.log(workspaceContents.structure_tree_ascii); console.log('Detailed tree data:'); console.log(JSON.stringify(workspaceContents.tree_data, null, 2)); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Failed to list workspace contents: ${error.statusCode} - ${error.message}`); } else { console.error('Unexpected error:', error); } } ``` #### Advanced Listing Options You can customize the listing behavior with optional parameters: ```typescript // List contents of a specific folder with detailed asset information const folderContents = await client.tools.listContents({ folder_id: 'your-folder-id', // Optional: specific folder to browse include_asset_details: true, // Optional: include detailed asset metadata include_system_files: false, // Optional: exclude system files from results }); // List workspace with all details and system files const detailedContents = await client.tools.listContents({ include_asset_details: true, include_system_files: true, }); ``` #### Response Structure The `listContents` method returns a `FolderResponse` object with: * **`structure_tree_ascii`**: A visual ASCII tree representation of the folder structure * **`tree_data`**: Detailed information about each asset and folder, organized as a tree structure ```typescript interface FolderResponse { structure_tree_ascii: string; tree_data: Record; } ``` ### Upload Files from Node.js Upload files from your local filesystem using the `saveAsset` method: ```typescript // Upload a file from the filesystem const FILE_PATH = process.env.FILE_PATH || 'README.md'; console.log(`⬆️ Uploading asset: ${FILE_PATH}`); try { const buffer = readFileSync(FILE_PATH); const file = new File([buffer], FILE_PATH, { type: 'application/octet-stream', }); const uploadResponse = await client.tools.saveAsset({ file, }); console.log('Upload successful:', JSON.stringify(uploadResponse, null, 2)); // Save the asset ID for later use const assetId = uploadResponse.asset_id; console.log(`Asset uploaded with ID: ${assetId}`); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Upload failed: ${error.statusCode} - ${error.message}`); } else { console.error('Unexpected error:', error); } } ``` ### Upload Different File Types Handle various file types with appropriate MIME types: ```typescript // Upload Excel file const excelBuffer = readFileSync('data.xlsx'); const excelFile = new File([excelBuffer], 'data.xlsx', { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const excelResult = await client.tools.saveAsset({ file: excelFile, name: 'Excel Data File' }); // Upload PDF file const pdfBuffer = readFileSync('document.pdf'); const pdfFile = new File([pdfBuffer], 'document.pdf', { type: 'application/pdf' }); const pdfResult = await client.tools.saveAsset({ file: pdfFile, name: 'PDF Document' }); // Upload CSV file const csvBuffer = readFileSync('data.csv'); const csvFile = new File([csvBuffer], 'data.csv', { type: 'text/csv' }); const csvResult = await client.tools.saveAsset({ file: csvFile, name: 'CSV Data' }); // Upload image file const imageBuffer = readFileSync('image.png'); const imageFile = new File([imageBuffer], 'image.png', { type: 'image/png' }); const imageResult = await client.tools.saveAsset({ file: imageFile, name: 'Image File' }); ``` ### Retrieve File Metadata After uploading, you can retrieve chunk metadata for your files: ```typescript if (assetId) { try { console.log('📑 Fetching chunk metadata…'); const chunkMetadata = await client.tools.getAssetChunks({ asset_ids: [assetId], }); console.log('Chunk metadata:', JSON.stringify(chunkMetadata, null, 2)); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Failed to retrieve chunk metadata: ${error.statusCode} - ${error.message}`); } else { console.error('Unexpected error:', error); } } } ``` ### Download File Content Retrieve the processed content of uploaded files: ```typescript if (assetId) { try { console.log('📥 Downloading asset content…'); const contentResponse = await client.tools.getAssetContent({ asset_id: assetId, }); console.log('Asset content:', JSON.stringify(contentResponse, null, 2)); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Failed to download asset content: ${error.statusCode} - ${error.message}`); } else { console.error('Unexpected error:', error); } } } ``` ### Upload from Browser When working in a browser environment with file inputs: ```typescript // HTML: const fileInput = document.getElementById('fileInput') as HTMLInputElement; fileInput.addEventListener('change', async (event) => { const file = (event.target as HTMLInputElement).files?.[0]; if (file) { try { const result = await client.tools.saveAsset({ file: file, name: file.name }); console.log('Upload successful:', result); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Upload failed: ${error.statusCode} - ${error.message}`); } else { console.error('Unexpected error:', error); } } } }); ``` ### Upload to Specific Folder You can organize files by uploading to specific folders: ```typescript const result = await client.tools.saveAsset({ file: file, name: "My Document", parent_folder_id: "folder_123456" }); ``` ### Complete File Management Example Here's a complete example that demonstrates the full file management workflow: ```typescript import { readFileSync } from 'node:fs'; import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk'; async function runFileManagementExample() { try { const client = new AthenaIntelligenceClient({ apiKey: process.env.ATHENA_API_KEY, // Optional: override baseUrl for custom environments // baseUrl: 'https://your-custom-api.example.com', }); let assetId: string | undefined; // Step 1: List workspace contents console.log('📂 Listing workspace contents…'); const listResponse = await client.tools.listContents(); console.log('Workspace contents:', JSON.stringify(listResponse, null, 2)); // Step 2: Upload a file const FILE_PATH = process.env.FILE_PATH || 'README.md'; console.log(`⬆️ Uploading asset: ${FILE_PATH}`); const buffer = readFileSync(FILE_PATH); const file = new File([buffer], FILE_PATH, { type: 'application/octet-stream', }); const uploadResponse = await client.tools.saveAsset({ file, }); console.log('Upload successful:', JSON.stringify(uploadResponse, null, 2)); assetId = uploadResponse.asset_id; if (!assetId) { console.warn('Could not determine asset_id from upload response'); return; } // Step 3: Retrieve chunk metadata console.log('📑 Fetching chunk metadata…'); const chunkMetadata = await client.tools.getAssetChunks({ asset_ids: [assetId], }); console.log('Chunk metadata:', JSON.stringify(chunkMetadata, null, 2)); // Step 4: Download asset content console.log('📥 Downloading asset content…'); const contentResponse = await client.tools.getAssetContent({ asset_id: assetId, }); console.log('Asset content:', JSON.stringify(contentResponse, null, 2)); console.log('✅ File management example completed'); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Athena API error (${error.statusCode}): ${error.message}`); } else { console.error('Unexpected error:', error); } } } runFileManagementExample(); ``` ### Using with Express.js If you're building a web application with Express.js and multer: ```typescript import express from 'express'; import multer from 'multer'; import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk'; const app = express(); const upload = multer(); const client = new AthenaIntelligenceClient({ apiKey: process.env.ATHENA_API_KEY, // Optional: override baseUrl for custom environments // baseUrl: 'https://your-custom-api.example.com', }); app.post('/upload', upload.single('file'), async (req, res) => { if (!req.file) { return res.status(400).json({ error: 'No file provided' }); } try { const file = new File([req.file.buffer], req.file.originalname, { type: req.file.mimetype }); const result = await client.tools.saveAsset({ file: file, name: req.file.originalname }); res.json({ message: 'File uploaded successfully', asset_id: result.asset_id, result }); } catch (error) { if (error instanceof AthenaIntelligenceError) { console.error(`Upload error: ${error.statusCode} - ${error.message}`); res.status(error.statusCode || 500).json({ error: 'Upload failed', message: error.message }); } else { console.error('Unexpected upload error:', error); res.status(500).json({ error: 'Upload failed' }); } } }); app.listen(3000, () => { console.log('Server running on port 3000'); }); ``` > Upload and manage files using the TypeScript SDK