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

# Answer API

> Generate web-grounded answers with /answer and real-time SSE with /answer_stream.

## Overview

The Answer API combines live web search with LLM generation in one request.

Use it when you need:

* Current information from the web
* Source-backed responses
* Structured output (JSON) for downstream processing
* Streaming UX for chat and copilots

## Endpoints

| Endpoint | Method | Best for | Supports JSON output |
| - | - | - | - |
| `/api/v2/answer` | `POST` | Standard request/response flows | Yes |
| `/api/v2/answer_stream` | `POST` (SSE) | Real-time streaming UX | No |

<Note>
  `provider_key` is accepted for backward compatibility but currently ignored; provider usage is not billed to the user's provider account.
</Note>

## Authentication

All requests require:

```bash theme={null}
Authorization: Bearer YOUR_LLMLAYER_API_KEY
```

<Warning>
  Keep API keys server-side. Do not expose them in browser code.
</Warning>

## Model Selection

| Model | Pricing model | Best for |
| - | - | - |
| `llmlayer-web` | Flat `$0.007 × max_queries` | Default recommendation |
| `llmlayer-fast` | Flat `$0.009 × max_queries` | Faster responses |
| `openai/gpt-4o-mini` | Token pricing + LLMLayer fee | Budget + quality |
| `openai/gpt-5.1` | Token pricing + LLMLayer fee | Highest reasoning quality |

<Tip>
  If unsure, start with `llmlayer-web` and `max_queries=1`.
</Tip>

## Quickstart

### Non-streaming (`/answer`)

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { LLMLayerClient } from 'llmlayer';

  const client = new LLMLayerClient({
    apiKey: process.env.LLMLAYER_API_KEY,
  });

  const response = await client.answer({
    query: 'What are the latest developments in quantum computing?',
    model: 'llmlayer-web',
    returnSources: true,
  });

  console.log(response.answer);
  console.log('Sources:', response.sources?.length || 0);
  console.log('LLMLayer cost:', response.llmlayer_cost);
  ```

  ```python Python theme={null}
  from llmlayer import LLMLayerClient

  client = LLMLayerClient(api_key='YOUR_LLMLAYER_API_KEY')

  response = client.answer(
      query='What are the latest developments in quantum computing?',
      model='llmlayer-web',
      return_sources=True,
  )

  print(response.answer)
  print('Sources:', len(response.sources or []))
  print('LLMLayer cost:', response.llmlayer_cost)
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.llmlayer.dev/api/v2/answer \
    -H "Authorization: Bearer YOUR_LLMLAYER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "query": "What are the latest developments in quantum computing?",
      "model": "llmlayer-web",
      "return_sources": true
    }'
  ```
</CodeGroup>

Example response (simplified):

```json theme={null}
{
  "answer": "...",
  "sources": [
    {
      "title": "...",
      "link": "https://...",
      "snippet": "..."
    }
  ],
  "response_time": "2.14",
  "input_tokens": 1432,
  "output_tokens": 288,
  "model_cost": null,
  "llmlayer_cost": 0.007
}
```

### Streaming (`/answer_stream`)

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { LLMLayerClient } from 'llmlayer';

  const client = new LLMLayerClient({
    apiKey: process.env.LLMLAYER_API_KEY,
  });

  const stream = client.streamAnswer({
    query: 'Explain retrieval-augmented generation in simple terms',
    model: 'openai/gpt-4o-mini',
    returnSources: true,
  });

  for await (const event of stream) {
    if (event.type === 'answer') {
      process.stdout.write(event.content || '');
    } else if (event.type === 'sources') {
      console.log('\n\nSources:', event.data?.length || 0);
    } else if (event.type === 'usage') {
      console.log('\nCost:', (event.model_cost || 0) + (event.llmlayer_cost || 0));
    } else if (event.type === 'done') {
      console.log('\nDone in', event.response_time, 'seconds');
    }
  }
  ```

  ```python Python theme={null}
  from llmlayer import LLMLayerClient

  client = LLMLayerClient(api_key='YOUR_LLMLAYER_API_KEY')

  stream = client.stream_answer(
      query='Explain retrieval-augmented generation in simple terms',
      model='openai/gpt-4o-mini',
      return_sources=True,
  )

  for event in stream:
      t = event.get('type')
      if t == 'answer':
          print(event.get('content', ''), end='', flush=True)
      elif t == 'sources':
          print('\n\nSources:', len(event.get('data', [])))
      elif t == 'usage':
          total = (event.get('model_cost') or 0) + (event.get('llmlayer_cost') or 0)
          print('\nCost:', total)
      elif t == 'done':
          print('\nDone in', event.get('response_time'), 'seconds')
  ```

  ```bash cURL (SSE) theme={null}
  curl -N -X POST https://api.llmlayer.dev/api/v2/answer_stream \
    -H "Authorization: Bearer YOUR_LLMLAYER_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Accept: text/event-stream" \
    -d '{
      "query": "Explain retrieval-augmented generation in simple terms",
      "model": "openai/gpt-4o-mini",
      "return_sources": true
    }'
  ```
</CodeGroup>

## Request Parameters

This is the canonical request-body table for both endpoints.

| Parameter | Type | Required | Default | Applies to | Cost impact | Details |
| - | - | - | - | - | - | - |
| `query` | `string` | Yes | - | Both | - | User question/instruction |
| `model` | `string` | Yes | - | Both | Depends on model | Example: `llmlayer-web`, `openai/gpt-4o-mini` |
| `search_type` | `string` | No | `general` | Both | - | `general` or `news` |
| `date_filter` | `string` | No | `anytime` | Both | - | `anytime`, `hour`, `day`, `week`, `month`, `year` |
| `location` | `string` | No | `us` | Both | - | Country code for localized search |
| `domain_filter` | `string[]` | No | `null` | Both | - | Include domains, or exclude with `-` prefix |
| `search_context_size` | `string` | No | `medium` | Both | Indirect | `low`, `medium`, `high` |
| `max_queries` | `integer` | No | `1` | Both | Increases LLMLayer fee | Range `1-4` |
| `max_tokens` | `integer` | No | `1500` | Both | Increases model usage | Response length cap |
| `temperature` | `number` | No | `0.7` | Both | - | Range `0.0-2.0` |
| `response_language` | `string` | No | `auto` | Both | - | Example: `en`, `fr`, `es` |
| `citations` | `boolean` | No | `false` | Both | Indirect | Adds inline citation markers |
| `return_sources` | `boolean` | No | `false` | Both | - | Includes `sources` array |
| `return_images` | `boolean` | No | `false` | Both | `+ $0.001` | Includes `images` array |
| `answer_type` | `string` | No | `markdown` | `/answer` | - | `markdown`, `html`, `json` |
| `json_schema` | `string` | Conditional | `null` | `/answer` | - | Required when `answer_type="json"`. Raw HTTP expects a JSON-encoded string; SDKs accept objects and serialize them. |
| `system_prompt` | `string` | No | `null` | Both | - | Custom behavior instructions |
| `provider_key` | `string` | No | `null` | Both | - | Accepted for backward compatibility, ignored |

<Note>
  HTTP requests use `snake_case` field names. JavaScript SDK examples use `camelCase`.
</Note>

<Note>
  For `/answer` JSON mode, raw REST requests should send `json_schema` as a string. The Python and TypeScript SDKs accept schema objects for convenience and serialize them before sending the request.
</Note>

### Parameter Rules

1. `max_queries` must be between `1` and `4`.
2. `answer_type="json"` requires `json_schema`.
3. `/api/v2/answer_stream` does not support structured JSON output.
4. `provider_key` does not change routing or billing, and provider usage is not billed to the user's provider account.
5. Use `-domain.com` in `domain_filter` to exclude domains.

## Non-streaming Response Contract (`/answer`)

| Field | Type | When present | Description |
| - | - | - | - |
| `answer` | `string \| object` | Always | Generated answer (`object` when JSON mode) |
| `sources` | `array` | If `return_sources=true` | Source documents used |
| `images` | `array` | If `return_images=true` | Image search results |
| `response_time` | `string` | Always | Total processing time in seconds |
| `input_tokens` | `integer` | Always | Input token usage |
| `output_tokens` | `integer` | Always | Output token usage |
| `model_cost` | `number \| null` | Usually | Model usage cost |
| `llmlayer_cost` | `number` | Always | LLMLayer infrastructure cost |

Source objects typically include `title`, `link`, `snippet` (plus provider-specific extras).

Image objects typically include `title`, `imageUrl`, `thumbnailUrl`, `source`, `link`.

## Streaming Event Contract (`/answer_stream`)

The stream is Server-Sent Events (`text/event-stream`). Each frame contains JSON under `data:`.

| Event type | Payload | Notes |
| - | - | - |
| `sources` | `{ "type": "sources", "data": Source[] }` | Emitted when `return_sources=true` |
| `images` | `{ "type": "images", "data": Image[] }` | Emitted when `return_images=true` |
| `answer` | `{ "type": "answer", "content": "..." }` | Main text chunks |
| `usage` | `{ "type": "usage", "input_tokens": ..., "output_tokens": ..., "model_cost": ..., "llmlayer_cost": ... }` | Billing and token usage |
| `done` | `{ "type": "done", "response_time": "..." }` | Final event |
| `error` | `{ "type": "error", "error": "..." }` | Runtime stream error |

Example stream sequence:

```json theme={null}
{"type":"sources","data":[...]}
{"type":"answer","content":"The "}
{"type":"answer","content":"main idea ..."}
{"type":"usage","input_tokens":1234,"output_tokens":210,"model_cost":0.0002,"llmlayer_cost":0.004}
{"type":"done","response_time":"2.41"}
```

<Warning>
  On early setup failures, some clients may receive an immediate frame like `{ "error": "missing_query" }`.
</Warning>

## Practical Examples

### 1) News summary with citations

```json theme={null}
{
  "query": "Latest developments in renewable energy",
  "model": "openai/gpt-5.1",
  "search_type": "news",
  "date_filter": "week",
  "citations": true,
  "return_sources": true,
  "max_queries": 2
}
```

### 2) Structured JSON extraction (`/answer` only)

```json theme={null}
{
  "query": "Summarize top AI model launches this month",
  "model": "openai/gpt-5.1",
  "answer_type": "json",
  "json_schema": "{\"type\":\"object\",\"properties\":{\"summary\":{\"type\":\"string\"},\"items\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}},\"required\":[\"summary\",\"items\"]}"
}
```

### 3) Domain-constrained answer

```json theme={null}
{
  "query": "What are current type 2 diabetes treatment guidelines?",
  "model": "openai/gpt-5.1",
  "domain_filter": ["pubmed.gov", "nih.gov", "-reddit.com"],
  "search_context_size": "high",
  "temperature": 0.3,
  "return_sources": true
}
```

## Error Handling

### `/answer` error format

```json theme={null}
{
  "detail": {
    "error_type": "validation_error",
    "error_code": "missing_query",
    "message": "Query parameter cannot be empty",
    "details": null
  }
}
```

### Common status codes

| Status | Category | Typical reason |
| - | - | - |
| `400` | Validation | Missing/invalid request parameters |
| `401` | Authentication | Missing or invalid LLMLayer API key |
| `429` | Rate limit/provider | Provider or account rate limiting |
| `500` | Internal/provider | Unexpected backend/provider failure |
| `502` | Provider | Upstream provider-specific failure |

### `/answer_stream` errors

* Runtime failures are emitted as stream events (`type: error`).
* Early validation failures can appear as an immediate single `error` frame.

## Pricing

### Standard token-priced models

```text theme={null}
Total = (0.004 × max_queries)
      + model_input_cost
      + model_output_cost
      + (0.001 if return_images=true)
```

### LLMLayer fixed-price models

```text theme={null}
llmlayer-web  = 0.007 × max_queries
llmlayer-fast = 0.009 × max_queries
```

<Note>
  Use `llmlayer_cost` and `model_cost` from responses as the billing source of truth.
</Note>

## Implementation Checklist

1. Start with `/answer` unless you need progressive rendering.
2. Set `max_queries=1` first; increase only for research-style queries.
3. Enable `return_sources=true` for trust-sensitive use cases.
4. Use `answer_type="json"` + `json_schema` for structured pipelines.
5. Add retry/backoff logic for transient `429/500/502` paths.
6. Keep keys server-side and log `llmlayer_cost` + token usage.

## FAQ

<AccordionGroup>
  <Accordion title="When should I use /answer_stream instead of /answer?">
    Use `/answer_stream` for chat UIs and live typing effects. Use `/answer` for batch jobs, strict request/response flows, and JSON structured output.
  </Accordion>

  <Accordion title="Can I stream JSON structured output?">
    No. Streaming returns incremental text chunks and does not support JSON schema-constrained output.
  </Accordion>

  <Accordion title="How do I control source quality?">
    Use `domain_filter`, `search_type`, `date_filter`, and `search_context_size` together. For factual tasks, use lower `temperature`.
  </Accordion>

  <Accordion title="Is provider_key still supported?">
    It is accepted for backward compatibility but currently ignored; provider usage is not billed to the user's provider account.
  </Accordion>

  <Accordion title="What happens if I pass an unsupported model?">
    The backend currently falls back to `llmlayer-web` instead of failing the request.
  </Accordion>

  <Accordion title="How do I minimize cost?">
    Start with `llmlayer-web`, keep `max_queries=1`, only request images/sources when needed, and tune `max_tokens` to expected output length.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="Web Search API" icon="magnifying-glass" href="/api-reference/endpoint/web-search">
    Raw search results without LLM generation
  </Card>

  <Card title="Scraper API" icon="globe" href="/api-reference/endpoint/scrape">
    Extract full page content from URLs
  </Card>

  <Card title="Answer Stream Endpoint" icon="stream" href="/api-reference/endpoint/stream-answer">
    OpenAPI reference for SSE endpoint
  </Card>
</CardGroup>

<CardGroup cols={2}>
  <Card title="Python SDK" icon="python" href="https://pypi.org/project/llmlayer/">
    Python package and usage examples
  </Card>

  <Card title="TypeScript SDK" icon="js" href="https://www.npmjs.com/package/llmlayer">
    JS/TS package and usage examples
  </Card>
</CardGroup>

## Need Help?

<CardGroup cols={2}>
  <Card title="Discord Community" icon="discord" href="https://discord.gg/EqQF4cjTq5">
    Ask implementation questions
  </Card>

  <Card title="Email Support" icon="envelope" href="mailto:support@llmlayer.ai">
    [support@llmlayer.ai](mailto:support@llmlayer.ai)
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.