> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.emtelligent.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.emtelligent.com/_mcp/server.

# Results and evidence

## Job status

`GET /v1/jobs/{id}` returns the job:

```json
{
  "id": "job_8f2c1d0e9b7a6c5d4e3f2a1b",
  "type": "questions",
  "status": "succeeded",
  "created_at": "2026-10-07T02:09:08Z",
  "started_at": "2026-10-07T02:09:08Z",
  "completed_at": "2026-10-07T02:09:13Z",
  "expires_at": "2026-10-08T02:09:08Z",
  "result_available": true,
  "error": null,
  "webhook": null
}
```

| `status`    | Meaning                                                                                    |
| ----------- | ------------------------------------------------------------------------------------------ |
| `queued`    | Accepted, waiting for a worker                                                             |
| `running`   | Being processed                                                                            |
| `succeeded` | Finished; download the result                                                              |
| `failed`    | Finished without a result; `error.code` says why. See [Errors](/formfill/reference/errors) |
| `canceled`  | Canceled with `DELETE /v1/jobs/{id}`                                                       |
| `expired`   | The result has been downloaded                                                             |

Times are UTC, formatted `YYYY-MM-DDTHH:MM:SSZ`.

## Downloading the result

`GET /v1/jobs/{id}/result` returns the result **once**. Store it on your side
straight away: a second request returns `410 result_expired`. At `expires_at`,
24 hours after submission, the job expires, and requests for it return
`404 not_found`. Asking before the job has
finished returns `409 not_ready`; asking for a job that failed or was canceled
returns `409 no_result`.

If you no longer want a result, `DELETE /v1/jobs/{id}` discards it without
downloading it. On a job that has not finished, the same request cancels it.

## Confidence

Every answer has a `confidence` from 0 to 1: the service's own estimate of how
well the document supports the answer. Use it to decide which answers a person
should review. It is not a calibrated probability, so choose your threshold by
reviewing a sample of your own documents.

## Evidence

Every answer comes with the verbatim quote it was taken from. In a `questions`
result, the quote is located for you:

```json
"evidence": {
  "quote": "Perineural invasion: not identified",
  "spans": [ { "start": 122, "end": 157 } ]
}
```

`start` and `end` are character offsets into the `document.text` you sent, with
`end` exclusive, so `text[start:end]` is the quote. Use them to highlight the
source of each answer in your own interface.

* **Several spans** mean the quote occurs in several places in the document, and
  the API could not tell which one the answer came from. When the document's
  section headings show it (the same diagnosis under both "Preoperative
  diagnosis" and "Postoperative diagnosis", say), only that occurrence is
  returned.
* **No spans** (`"spans": []`) mean the quote could not be found in the document.
  Treat such an answer with suspicion and send it for review:
  `stats.evidence_located` counts the answers whose quote was found.
* **A long answer copied from the document** (an operative description, say) is its
  own evidence: the quote is the whole passage, so highlighting it covers everything
  the answer contains rather than its first sentence.

Offsets count Unicode code points, which is how Python indexes a `str`. In
JavaScript, which indexes UTF-16 code units, text outside the Basic Multilingual
Plane (emoji, for example) shifts the offsets; convert before slicing such text.

In a QuestionnaireResponse, the quote is the `answer-evidence` extension on each
answer, without offsets. Locate it in the text you sent the same way.

## Answers the service derives

Two kinds of answer in a QuestionnaireResponse are not taken from a quote, and carry
an `answer-derivation` extension (`valueCode`) instead of `answer-evidence`:

| `answer-derivation` | Meaning                                                                                                                                                      |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `calculated`        | A score your form defines as a sum of option weights (a GCS total, say), calculated from the answers chosen. Its confidence is that of the weakest component |
| `implied`           | A yes/no control implied by an answered item it gates ("not testable" = false, because a response was recorded)                                              |

Show these as calculated or implied rather than as answers with missing evidence.
See [Filling a Questionnaire](/formfill/guides/questionnaires#scores), and
[Result format](/formfill/reference/result-format#extensions) for every extension.