# Stream verification

Receive verification events as work progresses, then wait for the final result and completion event.

Documentation index: https://webcite.co/llms.txt
Canonical page: https://webcite.co/api-docs/streaming
API origin: https://api.webcite.co
Authentication: x-api-key header. Keep keys on your server.

## When to use it

Use `curl --no-buffer` to inspect the stream. See [reading SSE safely](/api-docs/streaming-guide) for a client that retains partial network frames.

Use `claim`, `include_stance`, `include_verdict`, and `decompose_claim`. The shared request schema also lists `include_numeric_assess`, but the stream handler does not apply it; use the JSON verify endpoint for that option.

## MCP completion contract

Production rollout verified on 24 September 2026: the hosted API includes evidence policy 13 and the hosted MCP connector runs 1.9.0. This does not publish or upgrade the npm package installed by local clients. Inspect response metadata and the installed client version; saved responses retain their original policy and evidence time.

MCP 1.9.0 requires both the full result and a later `done` marker. Its `structuredContent` retains the result and a separate `stream_usage` receipt. Incomplete streams and accounting failures report `partial_result`; do not automatically replay a billable request after an ambiguous failure.

## Request

POST /api/v1/verify/stream

Same 2/3/4-credit prices as JSON verification.

### curl

```curl
curl --no-buffer --fail-with-body -X POST 'https://api.webcite.co/api/v1/verify/stream' \
  -H "x-api-key: $WEBCITE_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "claim": "The Eiffel Tower is 330 meters tall",
  "include_stance": true,
  "include_verdict": true
}'
```

### Node.js

```javascript
const response = await fetch("https://api.webcite.co/api/v1/verify/stream", {
  method: "POST",
  headers: {
    "x-api-key": process.env.WEBCITE_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "claim": "The Eiffel Tower is 330 meters tall",
  "include_stance": true,
  "include_verdict": true
}),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
// Read complete SSE frames. See the streaming guide below.
console.log(response.headers.get("content-type"));
```

### python

```python
import os
import json
import requests

payload = json.loads("{\n  \"claim\": \"The Eiffel Tower is 330 meters tall\",\n  \"include_stance\": true,\n  \"include_verdict\": true\n}")
response = requests.post(
    "https://api.webcite.co/api/v1/verify/stream",
    headers={"x-api-key": os.environ["WEBCITE_API_KEY"]},
    json=payload,
    stream=True,
    timeout=(10, 300),
)
response.raise_for_status()
for line in response.iter_lines(decode_unicode=True):
    if line:
        print(line)
```

## Response

Content-Type is text/event-stream. Each data frame contains a JSON object with a type. Read result for the final structured response, usage for the billing receipt, and done for successful completion. error and accounting_error are separate failures. End of connection without done is not successful completion.

## Errors

For 400, check the request fields and source identifiers. For 401, check your API key. For 429, wait for the retry interval. See the errors guide before retrying a billable request.

## OpenAPI operation

```json
{
  "path": "/api/v1/verify/stream",
  "method": "POST",
  "operation": {
    "description": "Stream verification results via Server-Sent Events. Citations stream as processed, followed by verdict when requested.\n\nPrices match POST /verify: search-only 2 credits, stance without verdict 3 credits, and any request with verdict 4 credits. Cached and uncached V1 requests use the same price.\n\n**Event Types:** citation, groups, verdict, metadata, result, usage, done, error. A successful stream emits one usage event followed by one done event.",
    "operationId": "ApiV1Controller_verifyClaimStream",
    "parameters": [],
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/VerifyClaimDto"
          }
        }
      },
      "required": true
    },
    "responses": {
      "200": {
        "description": "SSE stream of verification results"
      },
      "401": {
        "description": "Unauthorized - API key required"
      },
      "429": {
        "description": "Rate limit exceeded"
      }
    },
    "security": [
      {
        "x-api-key": []
      },
      {
        "bearer": []
      }
    ],
    "summary": "Verify a claim with streaming response",
    "tags": [
      "Public API"
    ]
  },
  "schemas": {
    "VerifyClaimDto": {
      "properties": {
        "claim": {
          "description": "The factual claim to verify",
          "example": "The Eiffel Tower is 330 meters tall",
          "type": "string"
        },
        "decompose_claim": {
          "default": false,
          "description": "Break complex claims into sub-claims and verify each independently",
          "type": "boolean"
        },
        "include_numeric_assess": {
          "default": false,
          "description": "If true, also run deterministic numeric assessment on the claim text (no extra figure operands). Skips with reason when the claim is not numeric. Default false. Does not add a separate credit charge in this release; uses the verify bill only.",
          "type": "boolean"
        },
        "include_stance": {
          "default": true,
          "description": "Include stance analysis for each source (adds 1 credit)",
          "type": "boolean"
        },
        "include_verdict": {
          "default": true,
          "description": "Generate an overall verdict with confidence score (adds 1 credit)",
          "type": "boolean"
        },
        "thread_id": {
          "description": "Thread ID to continue a conversation",
          "type": "string"
        }
      },
      "required": [
        "claim"
      ],
      "type": "object"
    }
  }
}
```
