Skip to main content

Annotations

When a Question Answering or Extraction job completes, each result contains a referenceIds field. These IDs point to annotation objects — structured records that identify the exact passages in your documents that the AI used to produce each answer or extracted value.

Fetching Annotations for a Job

A single endpoint returns all annotations for all results in a job. It aggregates every referenceIds value across all results and resolves them in one call.

# For a QA job
curl -s "https://<api-domain>/api/core/qa/jobs/${JOB_ID}/annotations" \
-H "Authorization: Bearer <your-pat>"

# For an Extraction job
curl -s "https://<api-domain>/api/core/extraction/jobs/${JOB_ID}/annotations" \
-H "Authorization: Bearer <your-pat>"

Annotation Object Structure

Each annotation has the following top-level fields:

FieldDescription
idAnnotation identifier { id: string, entityType: string }
typeAlways DOCUMENT_STATEMENT for QA and Extraction jobs
statusVALID or NOTVALID
dataThe document statement payload — see below
createdTimeUnix timestamp (ms) of annotation creation
modifiedTimeUnix timestamp (ms) of last modification

Annotation Data

QA and Extraction jobs produce DOCUMENT_STATEMENT annotations. The data field contains:

FieldDescription
contentThe text excerpt the AI used as evidence
documentNameHuman-readable name of the source document
documentIdID of the source EliseFile
positionsList of position objects — see Position Types

Position Types

The positions array locates the excerpt within the document. Three formats are used depending on the file type.

BBOX — PDFs and images

FieldDescription
pageNumberZero-based page index
bbox.x0Left edge (normalised, 0–1)
bbox.y0Top edge (normalised, 0–1)
bbox.x1Right edge (normalised, 0–1)
bbox.y1Bottom edge (normalised, 0–1)
{
"type": "BBOX",
"pageNumber": 2,
"bbox": { "x0": 0.12, "y0": 0.45, "x1": 0.88, "y1": 0.52 }
}

CELL — Spreadsheets

Used for XLSX, XLS, CSV, and ODS files.

FieldDescription
sheetNameName of the sheet
rowZero-based row index
colZero-based column index
{
"type": "CELL",
"sheetName": "Sheet1",
"row": 4,
"col": 2
}

LINE — Plain text and structured text

Used for TXT, HTML, JSON, XML, and similar files.

FieldDescription
lineNumberZero-based line index
columnIndexStartStart column of the match
columnIndexStopEnd column of the match
{
"type": "LINE",
"lineNumber": 17,
"columnIndexStart": 0,
"columnIndexStop": 84
}

Looking Up Source Passages

The referenceIds in each job result map directly to the id.id of the annotation objects. Build a lookup map to display source passages alongside results:

# Fetch results
results_response = client.get(f"/qa/jobs/{job_id}/results")
results_response.raise_for_status()
results = results_response.json().get("results", [])

# Fetch annotations and build a lookup map
ann_response = client.get(f"/qa/jobs/{job_id}/annotations")
ann_response.raise_for_status()
annotation_map = {a["id"]["id"]: a for a in ann_response.json()}

# Display answers with their source passages
for result in results:
print(f"Q: {result['question']}")
print(f"A: {result['rawValue']}")
for ref in result.get("referenceIds", []):
ann = annotation_map.get(ref["id"])
if ann:
data = ann["data"]
print(f" [{data['documentName']}] {data['content'][:100]}")
for pos in data.get("positions", []):
if pos["type"] == "BBOX":
print(f" -> page {pos['pageNumber']}")
print()

Next Steps