> 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.

# Structured Output

> Extract structured data using custom schemas with the TypeScript SDK

This example demonstrates a realistic workflow that combines the Research Agent with the Structured Data Extractor to gather information and convert it into structured JSON data using custom schemas.

Key features:

* Two-step workflow: Research Agent → Structured Data Extractor
* Custom schema definition for precise data extraction
* Full TypeScript support with type safety
* Proper error handling for production use

### 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 {
  type AthenaIntelligence,
  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
});
```

### Step 1: Gather Information with Research Agent

First, use the Research Agent to gather comprehensive information on your topic:

```typescript
const researchRequest: AthenaIntelligence.ResearchAgentRequest = {
  config: {
    enabled_tools: ['search'],
    model: 'gpt-4-turbo-preview',
  },
  messages: [
    {
      content: 'Research recent AI investment trends and find specific funding rounds from 2024',
      role: 'user',
      type: 'user',
    },
  ],
};

console.log('🔎 Running Research Agent…');
const researchResponse: AthenaIntelligence.ResearchAgentResponse =
  await client.agents.research.invoke(researchRequest);

// Extract research content from the response
const researchContent = researchResponse?.findings ?? '';

console.log('📝 Research summary obtained:');
console.log(researchContent);
```

### Step 2: Define Your Schema

Define the exact structure you want for your extracted data:

```typescript
// Define the schema we expect from the extractor
const schema = {
  investments: {
    item_1: {
      company: 'string',
      amount_usd_millions: 'number',
      country: 'string',
      investors: 'string',
    },
    item_2: {
      company: 'string',
      amount_usd_millions: 'number',
      country: 'string',
      investors: 'string',
    },
  },
  total_announced_usd_millions: 'number',
} as const;
```

### Step 3: Extract Structured Data

Use the Structured Data Extractor to convert the research findings into your desired format:

```typescript
const extractorRequest: AthenaIntelligence.StructuredDataExtractorRequest = {
  text_input: researchContent,
  custom_type_dict: schema,
  parsing_model: 'gpt-4-turbo-preview',
  chunk_messages: [],
};

console.log('🏗️ Extracting structured data…');
const extractionResponse: AthenaIntelligence.StructuredDataExtractorResponse =
  await client.tools.structuredDataExtractor.invoke(extractorRequest);

console.log('✅ Structured output:');
const structuredData = extractionResponse?.reduced_data;
console.log(JSON.stringify(structuredData, null, 2));
```

### Advanced Schema Examples

Create more complex schemas for different use cases:

```typescript
// Company analysis schema
const companySchema = {
  companies: {
    company_1: {
      name: 'string',
      description: 'string',
      market_cap_billions: 'number',
      industry: 'string',
      headquarters: 'string',
      key_products: 'string',
    },
    company_2: {
      name: 'string',
      description: 'string',
      market_cap_billions: 'number',
      industry: 'string',
      headquarters: 'string',
      key_products: 'string',
    },
  },
  market_trends: {
    trend_1: 'string',
    trend_2: 'string',
    trend_3: 'string',
  },
  summary_metrics: {
    total_market_cap: 'number',
    average_growth_rate: 'number',
    number_of_companies: 'number',
  },
} as const;

// News analysis schema
const newsSchema = {
  articles: {
    article_1: {
      headline: 'string',
      summary: 'string',
      publication_date: 'string',
      source: 'string',
      sentiment: 'string',
    },
    article_2: {
      headline: 'string',
      summary: 'string',
      publication_date: 'string',
      source: 'string',
      sentiment: 'string',
    },
  },
  overall_sentiment: 'string',
  key_themes: {
    theme_1: 'string',
    theme_2: 'string',
  },
} as const;
```

### TypeScript Type Safety

Define interfaces for better type safety when working with extracted data:

```typescript
// Define TypeScript interfaces based on your schema
interface InvestmentItem {
  company: string;
  amount_usd_millions: number;
  country: string;
  investors: string;
}

interface InvestmentData {
  investments: {
    item_1: InvestmentItem;
    item_2: InvestmentItem;
  };
  total_announced_usd_millions: number;
}

// Type the extracted data
const typedData = structuredData as InvestmentData;

// Now you have full TypeScript support
console.log(`Total funding: $${typedData.total_announced_usd_millions}M`);
typedData.investments.item_1.company; // TypeScript knows this is a string
```

### Error Handling

Always include comprehensive error handling for production applications:

```typescript
try {
  // Research step
  const researchResponse = await client.agents.research.invoke(researchRequest);
  const researchContent = researchResponse?.findings ?? '';

  if (!researchContent) {
    throw new Error('No research content received');
  }

  // Extraction step
  const extractionResponse = await client.tools.structuredDataExtractor.invoke({
    text_input: researchContent,
    custom_type_dict: schema,
    parsing_model: 'gpt-4-turbo-preview',
    chunk_messages: [],
  });

  const structuredData = extractionResponse?.reduced_data;
  console.log('Extraction successful:', structuredData);
} catch (error) {
  if (error instanceof AthenaIntelligenceError) {
    console.error(`Athena API error (${error.statusCode}): ${error.message}`);
  } else {
    console.error('Unexpected error:', error);
  }
}
```

### Complete Working Example

Here's a complete example that demonstrates the full workflow:

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

async function runStructuredOutputExample() {
  try {
    const client = new AthenaIntelligenceClient({
      apiKey: process.env.ATHENA_API_KEY,
      // Optional: override baseUrl for custom environments
      // baseUrl: 'https://your-custom-api.example.com',
    });

    // Step 1: Research
    const researchRequest: AthenaIntelligence.ResearchAgentRequest = {
      config: {
        enabled_tools: ['search'],
        model: 'gpt-4-turbo-preview',
      },
      messages: [
        {
          content: 'Research recent AI investment trends and find specific funding rounds from 2024',
          role: 'user',
          type: 'user',
        },
      ],
    };

    console.log('🔎 Running Research Agent…');
    const researchResponse = await client.agents.research.invoke(researchRequest);
    const researchContent = researchResponse?.findings ?? '';

    console.log('📝 Research summary obtained');

    // Step 2: Define schema
    const schema = {
      investments: {
        item_1: {
          company: 'string',
          amount_usd_millions: 'number',
          country: 'string',
          investors: 'string',
        },
        item_2: {
          company: 'string',
          amount_usd_millions: 'number',
          country: 'string',
          investors: 'string',
        },
      },
      total_announced_usd_millions: 'number',
    } as const;

    // Step 3: Extract structured data
    const extractorRequest: AthenaIntelligence.StructuredDataExtractorRequest = {
      text_input: researchContent,
      custom_type_dict: schema,
      parsing_model: 'gpt-4-turbo-preview',
      chunk_messages: [],
    };

    console.log('🏗️ Extracting structured data…');
    const extractionResponse = await client.tools.structuredDataExtractor.invoke(extractorRequest);

    console.log('✅ Structured output:');
    const structuredData = extractionResponse?.reduced_data;
    console.log(JSON.stringify(structuredData, null, 2));
  } catch (error) {
    if (error instanceof AthenaIntelligenceError) {
      console.error(`Athena API error (${error.statusCode}): ${error.message}`);
    } else {
      console.error('Unexpected error:', error);
    }
  }
}

runStructuredOutputExample();
```