> For clean Markdown of any page, append `.md` to the page URL.
> Documentation index: https://you.com/docs/llms.txt (section indexes: append `/llms.txt` to any section URL).
> Search these docs: Docs MCP at https://you.com/docs/_mcp/server (`searchDocs`, no API key).
> Call live You.com APIs: Product MCP at https://api.you.com/mcp (keyless `?profile=free` exposes `you-search` and `you-discover`. Research and finance use `/mcp/research`, `/mcp/finance`, or `?tools=` on `/mcp`). To pick an API or integration path, call `you-discover` on that server instead of guessing.
> OpenAPI: https://you.com/docs/openapi.json—auth header `X-API-Key`, env `YDC_API_KEY`.

# Structured Output

Use `output_schema` when you want `output.content` returned as a JSON object instead of free-form text. This is useful for pulling reported figures into fixed fields, comparing companies on the same metrics, or feeding Finance Research API output into a model, dashboard, or other typed system.

`output_schema` is supported with every `research_effort` value.

```curl
curl -X POST https://api.you.com/v1/finance_research \
  -H "X-API-Key: $YDC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "What were Apple'\''s revenue and diluted EPS in its most recent fiscal quarter, and how did EPS compare with consensus?",
    "research_effort": "deep",
    "output_schema": {
      "type": "object",
      "properties": {
        "company": {
          "type": "string"
        },
        "fiscal_quarter": {
          "type": "string"
        },
        "revenue_usd_billions": {
          "type": "number"
        },
        "diluted_eps_usd": {
          "type": "number"
        },
        "eps_vs_consensus": {
          "type": "string",
          "enum": ["beat", "inline", "miss"]
        }
      },
      "required": ["company", "fiscal_quarter", "revenue_usd_billions", "diluted_eps_usd", "eps_vs_consensus"],
      "additionalProperties": false
    }
  }'
```

When `output_schema` is provided, the structured result is returned in `output.content` and `output.content_type` is `object`. Sources remain in `output.sources`. The API does not add citation fields into your schema object automatically.

```json maxLines=25
{
  "output": {
    "content": {
      "company": "Apple",
      "fiscal_quarter": "Fiscal Q3 2026",
      "revenue_usd_billions": 109.4,
      "diluted_eps_usd": 2.02,
      "eps_vs_consensus": "beat"
    },
    "content_type": "object",
    "sources": [
      {
        "url": "https://www.apple.com/newsroom/pdfs/fy2026q3/FY26_Q3_Consolidated_Financial_Statements.pdf",
        "title": "Apple Inc. CONDENSED CONSOLIDATED STATEMENTS OF OPERATIONS (Unaudited)"
      },
      {
        "url": "https://www.apple.com/newsroom/2026/07/apple-reports-third-quarter-results/",
        "title": "Apple reports third quarter results - Apple"
      }
    ]
  },
  "warnings": []
}
```

## Schema Rules

`output_schema` follows a narrow JSON Schema subset designed for reliable structured generation. The rules and limits are the same as the [Research API](/docs/guides/research/structured-output), so one schema works on both endpoints.

Required rules:

* The root must be an object.
* The root must not use top-level `anyOf`.
* Every object must define `properties`.
* Every object must set `additionalProperties: false`.
* Every property must be listed in `required`. To make a field optional, keep it in `required` and make it nullable—see [Optional and Nullable Fields](#optional-and-nullable-fields).
* Recursive schemas are not supported.
* A property's type must not be a bare `{"type": "null"}`. Use a nullable union such as `{"type": ["number", "null"]}` instead.

Supported patterns include nested objects, arrays, enums, nested `anyOf`, and non-recursive `$defs` and `$ref`.

Unsupported keywords:

* `allOf`
* `contains`
* `not`
* `dependentRequired`
* `dependentSchemas`
* `format`
* `if` / `then` / `else`
* `maxContains` / `minContains`
* `maxItems` / `minItems`
* `maxLength` / `minLength`
* `maxProperties` / `minProperties`
* `maximum` / `minimum`
* `multipleOf`
* `pattern`
* `patternProperties`
* `propertyNames`
* `unevaluatedItems` / `unevaluatedProperties`
* `uniqueItems`

Selected limits:

| Limit                                      | Value  |
| ------------------------------------------ | ------ |
| Max nesting depth                          | 5      |
| Max total properties                       | 100    |
| Max total enum values                      | 500    |
| Max large-enum string budget (>250 values) | 7,500  |
| Max total schema string budget             | 25,000 |

If the schema is invalid, the request fails validation before model execution. The schema string budget counts property names, `$defs` names, enum values, and `const` values. It applies to schema shape only. Request-level limits such as the 40,000-character `input` limit are enforced separately at the request layer.

> **Note**
>
> There is no separate raw byte-size limit on the schema. What matters is the **25,000-character string budget**, which counts only property names, `$defs` names, `enum` values, and `const` values—not structural JSON (`{}`, `"type"`, whitespace). A 30 KB schema file can still pass if its counted strings stay under budget—a much smaller file can fail if it has many long enum values, such as a full list of ticker symbols.

A schema is rejected with `422` **before any model execution** if it exceeds any limit above (depth, property count, enum count, or string budget) or violates a [Schema Rule](#schema-rules). The error message names the specific limit or rule.

> **Note**
>
> Nesting depth counts every object and array level. A per-company array whose items hold a per-segment array of objects (`companies[] → segments[] → segment`) reaches the depth limit quickly. Flatten one level—for example, give each company `segment_names` and `segment_revenue_usd_billions` arrays—when you hit it.

## Optional and Nullable Fields

Every property you declare must appear in `required`. This is what makes structured generation reliable—the model always emits every field—and it matches OpenAI Structured Outputs.

To express a value that **may be unknown or not applicable**, keep the field in `required` but make its type **nullable** by adding `"null"`. The model returns `null` when the value isn't available instead of guessing. Financial schemas need this often: a company that pays no dividend has no dividend yield, and a pre-profit company has no meaningful P/E ratio.

Use the concise form (equivalent to `number | null`):

```json
"forward_pe": { "type": ["number", "null"] }
```

An `anyOf` spelling is also valid but more verbose—prefer the concise form above:

```json
"forward_pe": { "anyOf": [{ "type": "number" }, { "type": "null" }] }
```

> **Note**
>
> A property's type may **not** be a bare `{"type": "null"}` (a field that can only ever be null). Make the field nullable instead, as shown above. A `null` branch *inside* an `anyOf` is fine.

Omitting a field from `required` produces an invalid schema—the request fails validation before execution. Nullability is the only mechanism for "may be absent."

**Response behavior**

* A nullable field with no available value is returned as `null`.
* A non-nullable required field with no available value forces the model to emit something anyway (typically an empty string `""` for strings). Required fields are **never omitted** from the response, and the model does not fabricate a citation-backed value to fill them. If a field can legitimately be unknown, make it nullable so you get a clean `null` instead of `""` or `0`.

**Example**

```json
{
  "type": "object",
  "properties": {
    "ticker": { "type": "string" },
    "forward_pe": { "type": ["number", "null"] }
  },
  "required": ["ticker", "forward_pe"],
  "additionalProperties": false
}
```

## Conditional Structure

Conditional keywords (`if` / `then` / `else`, `dependentRequired`, `dependentSchemas`) are not supported. To express "field Y is required only when X"—for example, `annual_dividend_per_share_usd` is required only when `pays_dividend` is `true`—model the object as a **discriminated `anyOf` union**: one branch per case, with a shared field pinned to a distinct value via `enum`.

```json
{
  "type": "object",
  "properties": {
    "dividend": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "pays_dividend":                 { "type": "boolean", "enum": [true] },
            "annual_dividend_per_share_usd": { "type": "number" },
            "dividend_yield_pct":            { "type": ["number", "null"] }
          },
          "required": ["pays_dividend", "annual_dividend_per_share_usd", "dividend_yield_pct"],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": { "pays_dividend": { "type": "boolean", "enum": [false] } },
          "required": ["pays_dividend"],
          "additionalProperties": false
        }
      ]
    }
  },
  "required": ["dividend"],
  "additionalProperties": false
}
```

When `pays_dividend` is `true`, `annual_dividend_per_share_usd` is required—when `false`, only `pays_dividend` is allowed. This is the same pattern OpenAI Structured Outputs uses, so one schema works across both.

> **Note**
>
> `anyOf` may not be used at the schema root—nest the union under a property (or array `items`), as shown above.

## Comparing Multiple Companies

Put the per-company fields in an array of objects to get one row per company in a single request. Nullable fields keep a missing figure from being filled with a guess, and an `enum` turns a qualitative judgment into a value you can filter on:

```curl
curl -X POST https://api.you.com/v1/finance_research \
  -H "X-API-Key: $YDC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Compare free cash flow, share buybacks, and dividends per share for Apple, Microsoft, and Alphabet in each company'\''s most recent fiscal year.",
    "research_effort": "deep",
    "output_schema": {
      "type": "object",
      "properties": {
        "companies": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "ticker": { "type": "string" },
              "fiscal_year": { "type": "string" },
              "free_cash_flow_usd_billions": { "type": ["number", "null"] },
              "buybacks_usd_billions": { "type": ["number", "null"] },
              "dividends_per_share_usd": { "type": ["number", "null"] },
              "capital_allocation_priority": {
                "type": "string",
                "enum": ["buybacks", "dividends", "reinvestment", "balanced"]
              }
            },
            "required": ["ticker", "fiscal_year", "free_cash_flow_usd_billions", "buybacks_usd_billions", "dividends_per_share_usd", "capital_allocation_priority"],
            "additionalProperties": false
          }
        },
        "summary": { "type": "string" }
      },
      "required": ["companies", "summary"],
      "additionalProperties": false
    }
  }'
```

Structured output does not change what the Finance Research API reads. Figures still come from the sources in `output.sources`, so check them against the primary filing before they feed an investment decision or a client report.

[View full API reference](/docs/api-reference/finance-research/v1-finance_research)

## Next Steps

#### [Finance Research API Overview](/docs/guides/finance-research)

The finance index, effort levels, use cases, and pricing

#### [Research API Structured Output](/docs/guides/research/structured-output)

The same `output_schema` rules on the open-web Research API

#### [API Reference](/docs/api-reference/finance-research/v1-finance_research)

Full parameter reference, request/response schemas, and playground