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

# Citation Attribution

> Which citation actually shaped an AI answer — a verified influence map, span by span

Every scraper gives you an answer's citation *list*. `CITATION_ATTRIBUTION` tells you
which of those citations actually **made** the answer: which answer sentence came from
which source passage, with verbatim evidence for every claim.

Submit it like any other task — same endpoint, queue, polling and webhooks:

```bash theme={null}
curl -X POST https://api.querying.ai/v1/async/task \
  -H "Authorization: Bearer $QUERYING_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "taskType": "CITATION_ATTRIBUTION",
    "payload": {
      "answer": "…the AI answer, as raw markdown…",
      "prompt": "best korean instant ramen",
      "citations": [
        { "url": "https://example.com/best-ramen", "body": "…the page text…" },
        { "url": "https://another.example.com/review", "body": "…the page text…" }
      ],
      "language": "en"
    }
  }'
```

The natural pairing is a two-step flow: run an Answers engine (`GEMINI`,
`PERPLEXITY`, …), then feed its `text` and `sources[].url` straight into this task.

## Payload

| Field              | Required | Notes                                                                                                                                                        |
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `answer`           | yes      | The AI answer as raw markdown, 1–200,000 chars. Keep it unmodified — link fragments in the text are part of the analysis.                                    |
| `citations[]`      | yes      | 1–25 sources. Supply each source's text via `body` — citations without a readable body come back as `unfetched`. At most 10 discussion-thread URLs per task. |
| `citations[].kind` | no       | How the answer cites this source: `inline` (linked from the answer text) or `panel` (listed as a source only). Auto-detected when omitted.                   |
| `prompt`           | no       | The question that produced the answer. Improves precision: answer text that merely restates the question is attributed to nothing.                           |
| `language`         | no       | Language for the `insight` narrative. Defaults to the answer's language.                                                                                     |

## Result

```jsonc theme={null}
{
  "influence": {
    "answerChars": 322,
    "attributedChars": 143,
    "coverage": 0.44,                    // share of the answer traceable to the citations
    "ranking": ["https://example.com/…", "https://another.example.com/…"],
    "insight": "The #1 recommendation comes directly from a first-person review…"  // 2–4 sentences, or null
  },
  "attributions": [                       // one per input citation, same order
    {
      "citationUrl": "https://example.com/best-ramen",
      "kind": "panel",
      "outcome": "passage",               // comment | post | passage | none | unfetched
      "influence": 0.28,                  // this citation's verified share of the answer
      "rank": 1,
      "sourceRef": { "kind": "passage", "index": 8 },
      "spans": [
        {
          "answerEvidence": "Shin Ramyun is widely regarded as the best-known",
          "sourceEvidence": "Shin Ramyun is going to be your classic pick.",
          "evidenceVerified": true,        // both sides re-checked against the actual documents
          "strength": "paraphrase",        // verbatim | paraphrase | fact-match
          "method": "judge",
          "answerRange": { "start": 0, "end": 48 },   // character offsets into your answer
          "sourceRef": { "kind": "passage", "index": 8 }
        }
      ],
      "method": "judge"
    }
  ],
  "debug": { "ms": 9800, "judgeCalls": 2, "cacheHits": 0, "unfetched": 0,
             "llmTokens": { "input": 9100, "output": 1200 }, "sourceFetches": 1 }
}
```

How to read it:

* **`spans[]` is the influence map.** Each span pairs an exact fragment of *your
  answer* (`answerEvidence`, located at `answerRange`) with the exact fragment of the
  *source* that carries the same information (`sourceEvidence`). The two sides don't
  need to look alike — a paraphrased or translated claim still maps to its source.
* **`evidenceVerified` is the trust gate.** Both fragments are re-checked to exist
  verbatim in their own documents. Unverified spans are excluded from all scores;
  filter them out in your pipeline too.
* **`outcome` names what part of the source carried the information**: `passage` for
  documents; for discussion-thread sources, `comment` (a specific comment, with its
  location in `sourceRef`) or `post` (the thread's opening post).
* **`influence` and `coverage` are computed, not estimated** — the character share of
  the answer covered by verified spans. Two citations backing the same sentence both
  get credit; the totals count shared text once.
* **`kind: "inline"` with `outcome: "none"`** means the answer links a citation whose
  source doesn't actually support the claim it's attached to.
* **A result full of `none` is a finding, not a failure** — the answer didn't use its
  citations. AI answers routinely draw most of their text from model knowledge rather
  than the visible citations; `coverage` measures influence *relative to the sources
  you provided*.
* **`debug.llmTokens` and `debug.sourceFetches`** are the usage behind the task's
  credit charge.

## Limits

* 25 citations per task; at most 10 discussion-thread citations.
* Repeated analyses of the same source reuse a short-lived fetch cache.
* Citations without a supplied `body` are returned as `unfetched` today; automatic
  fetching is planned.
