> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reducto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Layout & Table Extraction to Analytics

> Extract and analyze financial data from 10-K annual reports using Parse, Extract, and table extraction

Extract structured financial data from SEC 10-K filings for investment analysis, competitive intelligence, or compliance automation.

***

## Sample Document

<iframe src="/samples/10k-apple.pdf" width="100%" height="500px" style={{ border: "1px solid #e0e0e0", borderRadius: "8px" }} />

<Note>
  Download the sample: [10k-apple.pdf](/samples/10k-apple.pdf)
</Note>

***

## Create API Key

<Steps>
  <Step title="Open Studio">
    Go to [studio.reducto.ai](https://studio.reducto.ai) and sign in. From the home page, click **API Keys** in the left sidebar.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/api-1.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=6fda1435e042681807741c7743273da2" alt="Studio home page with API Keys in sidebar" width="3164" height="1922" data-path="cookbooks/dummy-docs/screenshots/api-1.png" />
    </Frame>
  </Step>

  <Step title="View API Keys">
    The API Keys page shows your existing keys. Click **+ Create new API key** in the top right corner.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/api-2.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=10db7406c2ac7217e4b1d75e028b58e1" alt="API Keys page with Create button" width="3164" height="1922" data-path="cookbooks/dummy-docs/screenshots/api-2.png" />
    </Frame>
  </Step>

  <Step title="Configure Key">
    In the modal, enter a name for your key and set an expiration policy (or select "Never" for no expiration). Click **Create**.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/api-3.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=afb60f6cfb4d33940669d534dd007343" alt="New API Key modal with name and expiration fields" width="3164" height="1922" data-path="cookbooks/dummy-docs/screenshots/api-3.png" />
    </Frame>
  </Step>

  <Step title="Copy Your Key">
    Copy your new API key and store it securely. You won't be able to see it again after closing this dialog.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/api-4.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=c861b1c2f593244957cf15c6fd717f60" alt="Copy API key dialog" width="3164" height="1922" data-path="cookbooks/dummy-docs/screenshots/api-4.png" />
    </Frame>

    Set the key as an environment variable:

    ```bash theme={null}
    export REDUCTO_API_KEY="your-api-key-here"
    ```
  </Step>
</Steps>

***

## Studio Walkthrough

<Steps>
  <Step title="Create an Extract Pipeline">
    Go to [studio.reducto.ai](https://studio.reducto.ai) and create an Extract pipeline. Upload the 10-K PDF.

    Extract runs Parse under the hood, then uses an LLM to locate and return only the specific fields you define. This is ideal for pulling financial metrics from 10-K filings.
  </Step>

  <Step title="Configure Parse Settings">
    Before defining your schema, check the Parse settings that Extract will use. Open the **Configurations** tab to access settings.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/apple-10k-1.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=f4bee0232c029486d9cf6fb3f388859b" alt="Parse view with Configurations showing settings options" width="2608" height="1506" data-path="cookbooks/dummy-docs/screenshots/apple-10k-1.png" />
    </Frame>

    Key settings for financial documents:

    * **Enable AI Summarization** — Generate summaries of figures and charts
    * **Return Figure/Table Images** — Include extracted images of charts and tables
  </Step>

  <Step title="View Parse Results">
    Click **Run** to see the parsed content. Reducto parses financial tables with their structure preserved, including multi-year comparative data.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/apple-10k-parse-result-2.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=05faf892bba9c0358f09a6bf4ef4086e" alt="Parse results showing extracted financial table with gross margin data" width="2594" height="1502" data-path="cookbooks/dummy-docs/screenshots/apple-10k-parse-result-2.png" />
    </Frame>

    Notice how the Products and Services gross margin table keeps proper row/column structure with data for 2023, 2022, and 2021. If a value doesn't appear in Parse output, Extract can't find it either.
  </Step>

  <Step title="Switch to Extract and Import Schema">
    Click **Extract** to switch views. While Parse gives you the full document content, Extract lets you define a schema to pull only the specific fields you need as structured JSON.

    For 10-K analysis, we want to extract two categories of data:

    * **Company info** — Name, ticker symbol, fiscal year end, and SEC CIK number from the cover page
    * **Income statement** — Key metrics like total revenue, cost of sales, gross profit, operating expenses, and operating income from the financial statements

    Click **Import** in the Schema Builder to paste this pre-defined JSON schema:

    ```json theme={null}
    {
      "type": "object",
      "properties": {
        "company_info": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "Company name from cover page"
            },
            "ticker": {
              "type": "string",
              "description": "Stock ticker symbol"
            },
            "fiscal_year_end": {
              "type": "string",
              "description": "Fiscal year end date"
            },
            "cik": {
              "type": "string",
              "description": "SEC CIK number"
            }
          }
        },
        "income_statement": {
          "type": "object",
          "description": "Data from Consolidated Statements of Operations",
          "properties": {
            "total_revenue": {
              "type": "number",
              "description": "Total net sales/revenue in millions"
            },
            "cost_of_sales": {
              "type": "number",
              "description": "Cost of goods sold in millions"
            },
            "gross_profit": {
              "type": "number",
              "description": "Gross profit (revenue minus COGS)"
            },
            "operating_expenses": {
              "type": "number",
              "description": "Total operating expenses"
            },
            "operating_income": {
              "type": "number",
              "description": "Operating income"
            }
          }
        }
      }
    }
    ```

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/cookbooks/dummy-docs/screenshots/apple-10k-upload-schema-json-3.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=a0701d31835ed5286a3ccfdfab64e9c5" alt="Paste JSON Schema modal showing company_info and income_statement schema" width="3164" height="1922" data-path="cookbooks/dummy-docs/screenshots/apple-10k-upload-schema-json-3.png" />
    </Frame>
  </Step>

  <Step title="Run and View Results">
    The Schema Builder shows your imported schema with nested structure. Click **Run** to execute the extraction.

    The Results tab shows your extracted data matching your schema. Use the toolbar to copy or download the results or switch to JSON.

    <Frame>
      <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/images/apple-10k-result.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=eed06cf32fa79ecf63b2b3e27777295e" alt="Extraction results showing company_info and income_statement data" width="2830" height="1694" data-path="images/apple-10k-result.png" />
    </Frame>
  </Step>
</Steps>

***

## Using the API

To run this extraction programmatically, click **Deploy** in Studio.

<Frame>
  <img src="https://mintcdn.com/reducto/9Avr4qdsIoNo7JLQ/images/apple-10k-deployment.png?fit=max&auto=format&n=9Avr4qdsIoNo7JLQ&q=85&s=b5cc24a8166c11642b55c4805beaa55f" alt="Deploy Pipeline dialog showing Pipeline and Direct API Call options" width="1816" height="1070" data-path="images/apple-10k-deployment.png" />
</Frame>

**Pipeline ID** creates a stable endpoint with a single identifier. Your code stays simple regardless of workflow complexity. Update settings in Studio and redeploy without changing code.

<CodeGroup>
  ```python Python theme={null}
  from pathlib import Path
  from reducto import Reducto

  client = Reducto()
  upload = client.upload(file=Path("10k-apple.pdf"))

  result = client.pipeline.run(
      input=upload,
      pipeline_id="k97c67gd5jahhs5anj3zr1gqd97zadrg"
  )
  ```

  ```typescript TypeScript theme={null}
  import Reducto from "reductoai";
  import fs from "fs";

  const client = new Reducto();
  const upload = await client.upload({
    file: fs.createReadStream("10k-apple.pdf"),
  });

  const result = await client.pipeline.run({
    input: upload,
    pipelineId: "k97c67gd5jahhs5anj3zr1gqd97zadrg",
  });
  ```

  ```bash cURL theme={null}
  # First, upload your file
  curl -X POST "https://platform.reducto.ai/upload" \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -F "file=@10k-apple.pdf"

  # This returns a response like: {"upload_id": "abc123"}
  # Use the upload_id in the next request

  # Run the pipeline
  curl -X POST "https://platform.reducto.ai/pipeline" \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "input": "reducto://abc123",
      "pipeline_id": "k97c67gd5jahhs5anj3zr1gqd97zadrg"
    }'
  ```
</CodeGroup>

**Direct API Call** exports the raw configuration as code. Use this when you need runtime flexibility or want configuration in version control.

<CodeGroup>
  ```python Python theme={null}
  from pathlib import Path
  from reducto import Reducto

  client = Reducto()
  upload_response = client.upload(file=Path("10k-apple.pdf"))

  instructions = {
    "schema": {
      "type": "object",
      "properties": {
        "company_info": {
          "type": "object",
          "properties": {
            "name": {"type": "string", "description": "Company name from cover page"},
            "ticker": {"type": "string", "description": "Stock ticker symbol"},
            "fiscal_year_end": {"type": "string", "description": "Fiscal year end date"},
            "cik": {"type": "string", "description": "SEC CIK number"}
          },
          "required": ["name", "ticker", "fiscal_year_end", "cik"]
        },
        "income_statement": {
          "type": "object",
          "description": "Data from Consolidated Statements of Operations",
          "properties": {
            "total_revenue": {"type": "number", "description": "Total net sales/revenue in millions"},
            "cost_of_sales": {"type": "number", "description": "Cost of goods sold in millions"},
            "gross_profit": {"type": "number", "description": "Gross profit (revenue minus COGS)"},
            "operating_expenses": {"type": "number", "description": "Total operating expenses"},
            "operating_income": {"type": "number", "description": "Operating income"}
          },
          "required": ["total_revenue", "cost_of_sales", "gross_profit", "operating_expenses", "operating_income"]
        }
      },
      "required": ["company_info", "income_statement"]
    }
  }
  settings = {
    "citations": {"enabled": True, "numerical_confidence": False}
  }

  result = client.extract.run(
      input=upload_response,
      instructions=instructions,
      settings=settings
  )
  print(result)
  ```

  ```typescript TypeScript theme={null}
  import Reducto from 'reductoai';
  import fs from 'fs';

  const client = new Reducto();
  const uploadResponse = await client.upload({
      file: fs.createReadStream("10k-apple.pdf")
  });

  const instructions = {
    "schema": {
      "type": "object",
      "properties": {
        "company_info": {
          "type": "object",
          "properties": {
            "name": {"type": "string", "description": "Company name from cover page"},
            "ticker": {"type": "string", "description": "Stock ticker symbol"},
            "fiscal_year_end": {"type": "string", "description": "Fiscal year end date"},
            "cik": {"type": "string", "description": "SEC CIK number"}
          },
          "required": ["name", "ticker", "fiscal_year_end", "cik"]
        },
        "income_statement": {
          "type": "object",
          "description": "Data from Consolidated Statements of Operations",
          "properties": {
            "total_revenue": {"type": "number", "description": "Total net sales/revenue in millions"},
            "cost_of_sales": {"type": "number", "description": "Cost of goods sold in millions"},
            "gross_profit": {"type": "number", "description": "Gross profit (revenue minus COGS)"},
            "operating_expenses": {"type": "number", "description": "Total operating expenses"},
            "operating_income": {"type": "number", "description": "Operating income"}
          },
          "required": ["total_revenue", "cost_of_sales", "gross_profit", "operating_expenses", "operating_income"]
        }
      },
      "required": ["company_info", "income_statement"]
    }
  };
  const settings = {
    "citations": {"enabled": true, "numerical_confidence": false}
  };

  const result = await client.extract.run({
      input: uploadResponse,
      instructions,
      settings
  });
  ```

  ```bash cURL theme={null}
  # First, upload your file
  curl -X POST "https://platform.reducto.ai/upload" \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -F "file=@10k-apple.pdf"

  # This returns a response like: {"upload_id": "abc123"}
  # Use the upload_id in the next request

  # Extract the document
  curl -X POST "https://platform.reducto.ai/extract" \
    -H "Authorization: Bearer $REDUCTO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "input": "abc123",
    "instructions": {
      "schema": {
        "type": "object",
        "properties": {
          "company_info": {
            "type": "object",
            "properties": {
              "name": {"type": "string", "description": "Company name from cover page"},
              "ticker": {"type": "string", "description": "Stock ticker symbol"},
              "fiscal_year_end": {"type": "string", "description": "Fiscal year end date"},
              "cik": {"type": "string", "description": "SEC CIK number"}
            },
            "required": ["name", "ticker", "fiscal_year_end", "cik"]
          },
          "income_statement": {
            "type": "object",
            "description": "Data from Consolidated Statements of Operations",
            "properties": {
              "total_revenue": {"type": "number", "description": "Total net sales/revenue in millions"},
              "cost_of_sales": {"type": "number", "description": "Cost of goods sold in millions"},
              "gross_profit": {"type": "number", "description": "Gross profit (revenue minus COGS)"},
              "operating_expenses": {"type": "number", "description": "Total operating expenses"},
              "operating_income": {"type": "number", "description": "Operating income"}
            },
            "required": ["total_revenue", "cost_of_sales", "gross_profit", "operating_expenses", "operating_income"]
          }
        },
        "required": ["company_info", "income_statement"]
      }
    },
    "settings": {
      "citations": {"enabled": true, "numerical_confidence": false}
    }
  }'
  ```
</CodeGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Table Formats" icon="table" href="/configs/parse/table-output-formats">
    Configure table extraction
  </Card>

  <Card title="Chunking Methods" icon="scissors" href="/configs/parse/chunking-methods">
    Optimize document sectioning
  </Card>

  <Card title="Array Extraction" icon="list" href="/configs/extract/array-extraction">
    Extract multi-year data
  </Card>

  <Card title="Pipeline Basics" icon="diagram-project" href="/workflows/pipeline-basics">
    Chain multiple operations
  </Card>
</CardGroup>
