> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.athenaintel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server.

# Working with Assets

> Learn how to list, retrieve, and work with assets using the Athena SDK.

This guide covers how to work with assets in the Athena SDK, including listing assets, retrieving asset details, and understanding the tags structure.

## Understanding the Tags Structure

Every asset in Athena has a `tags` object that contains both system-managed fields and custom tags. This is important because **the asset ID is stored in `tags.asset_id`** as an array of strings.

### System Fields in Tags

The `tags` object contains the following system-managed fields:

| Field                   | Type       | Description                                                                                |
| ----------------------- | ---------- | ------------------------------------------------------------------------------------------ |
| `asset_id`              | `string[]` | Array containing the unique asset identifier. This is the primary way to get the asset ID. |
| `title`                 | `string[]` | Array containing the asset title                                                           |
| `media_type`            | `string[]` | Array containing the MIME type or Athena-specific media type                               |
| `athena_original_type`  | `string[]` | Array containing the original asset type                                                   |
| `athena_converted_type` | `string[]` | Array containing the converted asset type                                                  |
| `workspace_visible`     | `string[]` | Array containing visibility setting (`"true"` or `"false"`)                                |
| `shared_with_user_ids`  | `string[]` | Array of user IDs who have access to this asset                                            |
| `custom_tags`           | `string[]` | Array of user-defined custom tags for categorization                                       |

### Example Tags Object

```json
{
  "tags": {
    "asset_id": ["asset_92492920-d118-42d3-95b4-00eccfe0754f"],
    "title": ["Quarterly Report Q1 2024"],
    "media_type": ["application/pdf"],
    "athena_original_type": ["document"],
    "athena_converted_type": ["pdf"],
    "workspace_visible": ["true"],
    "shared_with_user_ids": ["user_123", "user_456"],
    "custom_tags": ["finance", "quarterly-report"]
  }
}
```

### 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 { AthenaIntelligenceClient } from '@athenaintel/sdk';

const client = new AthenaIntelligenceClient({
  apiKey: process.env.ATHENA_API_KEY,
});
```

### List Assets

Retrieve a paginated list of assets with optional filtering:

```typescript
// List all assets (paginated)
const assets = await client.assets.list({
  limit: 50,
  offset: 0,
});

console.log(`Total assets: ${assets.total}`);
console.log(`Has more: ${assets.has_more}`);

// Process each asset
for (const asset of assets.items) {
  // Extract the asset ID from tags
  const assetId = asset.tags?.asset_id?.[0];
  console.log(`Asset: ${asset.title} (ID: ${assetId})`);
}
```

### Filter Assets by Type

Use filters to find specific types of assets:

```typescript
// Find all folders
const folders = await client.assets.list({
  limit: 50,
  filters: JSON.stringify({
    media_type: 'athena/folder',
  }),
});

// Find all PDF documents
const pdfs = await client.assets.list({
  limit: 50,
  filters: JSON.stringify({
    media_type: 'application/pdf',
  }),
});

// Find assets with specific custom tags
const taggedAssets = await client.assets.list({
  limit: 50,
  filters: JSON.stringify({
    tags: {
      custom_tags: ['finance'],
    },
  }),
});
```

### Get Asset by ID

Retrieve a single asset with full metadata:

```typescript
const assetId = 'asset_92492920-d118-42d3-95b4-00eccfe0754f';
const asset = await client.assets.get(assetId);

console.log('Asset details:');
console.log(`  Title: ${asset.title}`);
console.log(`  Media Type: ${asset.media_type}`);
console.log(`  Created: ${asset.created_at}`);
console.log(`  Summary Ready: ${asset.summary_ready}`);

// Access the asset ID from tags
const retrievedAssetId = asset.tags?.asset_id?.[0];
console.log(`  Asset ID (from tags): ${retrievedAssetId}`);

// Access custom tags
const customTags = asset.tags?.custom_tags || [];
console.log(`  Custom Tags: ${customTags.join(', ')}`);
```

### Search for Folders

A common operation is searching for folders to organize assets:

```typescript
async function findFolderByName(folderName: string) {
  const folders = await client.assets.list({
    limit: 100,
    filters: JSON.stringify({
      media_type: 'athena/folder',
      title_substring: folderName,
    }),
  });

  if (folders.items.length === 0) {
    console.log(`No folder found with name containing: ${folderName}`);
    return null;
  }

  const folder = folders.items[0];
  const folderId = folder.tags?.asset_id?.[0];
  
  console.log(`Found folder: ${folder.title}`);
  console.log(`Folder ID: ${folderId}`);
  
  return folderId;
}

// Usage
const folderId = await findFolderByName('Reports');
```

### Extract Asset ID Helper

Create a helper function to safely extract the asset ID:

```typescript
function getAssetId(asset: { tags?: { asset_id?: string[] } }): string | undefined {
  return asset.tags?.asset_id?.[0];
}

// Usage
const assets = await client.assets.list({ limit: 10 });
for (const asset of assets.items) {
  const id = getAssetId(asset);
  if (id) {
    console.log(`Processing asset: ${id}`);
  }
}
```

### Complete Example

Here's a complete working example that demonstrates listing and filtering assets:

```typescript
import { AthenaIntelligenceClient, AthenaIntelligenceError } from '@athenaintel/sdk';

async function workWithAssets() {
  try {
    const client = new AthenaIntelligenceClient({
      apiKey: process.env.ATHENA_API_KEY,
    });

    // List recent assets
    console.log('Listing recent assets...');
    const assets = await client.assets.list({
      limit: 10,
      sort: JSON.stringify([
        { field: 'updated_at', direction: 'desc' },
      ]),
    });

    console.log(`Found ${assets.total} total assets`);
    
    for (const asset of assets.items) {
      const assetId = asset.tags?.asset_id?.[0];
      const customTags = asset.tags?.custom_tags || [];
      
      console.log(`\nAsset: ${asset.title}`);
      console.log(`  ID: ${assetId}`);
      console.log(`  Type: ${asset.athena_original_type}`);
      console.log(`  Media Type: ${asset.media_type}`);
      console.log(`  Custom Tags: ${customTags.length > 0 ? customTags.join(', ') : 'none'}`);
      console.log(`  Summary Ready: ${asset.summary_ready}`);
    }

    // Find all folders
    console.log('\n\nSearching for folders...');
    const folders = await client.assets.list({
      limit: 50,
      filters: JSON.stringify({
        media_type: 'athena/folder',
      }),
    });

    console.log(`Found ${folders.total} folders`);
    for (const folder of folders.items) {
      const folderId = folder.tags?.asset_id?.[0];
      console.log(`  - ${folder.title} (${folderId})`);
    }

  } catch (error) {
    if (error instanceof AthenaIntelligenceError) {
      console.error(`Athena API error (${error.statusCode}): ${error.message}`);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

workWithAssets();
```

## Response Structure

### PublicAssetOut

When you retrieve an asset, you receive a `PublicAssetOut` object with the following structure:

```typescript
interface PublicAssetOut {
  // Required fields
  created_by_id: string;
  created_at: string;  // ISO 8601 format
  title: string;
  updated_at: string;  // ISO 8601 format
  is_archived: boolean;
  is_hidden: boolean;
  media_type: string;
  athena_converted_type: string;
  athena_original_type: string;
  summary_ready: boolean;
  
  // Optional fields
  created_by_email?: string;
  tags?: {
    asset_id?: string[];
    title?: string[];
    media_type?: string[];
    athena_original_type?: string[];
    athena_converted_type?: string[];
    workspace_visible?: string[];
    shared_with_user_ids?: string[];
    custom_tags?: string[];
  };
  athena_metadata?: Record<string, unknown>;
  summary?: string;
  summary_status?: string;
}
```

### PaginatedAssetsOut

When listing assets, you receive a `PaginatedAssetsOut` object:

```typescript
interface PaginatedAssetsOut {
  total: number;      // Total number of assets matching the query
  limit: number;      // Maximum number of assets in this response
  offset: number;     // Number of assets skipped
  has_more: boolean;  // Whether there are more assets available
  next_offset?: number;  // Offset for the next page (null if no more pages)
  items: PublicAssetOut[];  // Array of assets
}
```