---
title: "Get trace annotation"
method: GET
path: "/v1/projects/{projectSlug}/traces/{traceId}/annotations/{annotationId}"
tags: ["Traces"]
---

# Get trace annotation

`GET /v1/projects/{projectSlug}/traces/{traceId}/annotations/{annotationId}`

Returns one annotation by id pinned to the trace.

## Path parameters

- `projectSlug` string, required — Project slug (human-readable identifier)
- `traceId` string, required — 32-character trace identifier.
- `annotationId` string, required — Stable annotation identifier.

## Response `200`

Annotation

- Annotation
  - `id` string, required — Stable annotation identifier.
  - `organizationId` string, required — Organization that owns this annotation.
  - `projectId` string, required — Project this annotation lives in.
  - `sessionId` string, nullable, required — Session id lifted from the annotated trace. `null` when the trace has no session.
  - `traceId` string, nullable, required — Identifier of the annotated trace.
  - `spanId` string, nullable, required — Span the annotation pins to. Defaults to the trace's last LLM-completion span.
  - `simulationId` string, nullable, required — Simulation reference, if any.
  - `signalId` string, nullable, required — Signal this annotation contributes to, if any.
  - `value` number, required — Normalized score value in [0, 1]. Higher = better.
  - `passed` boolean, required — Whether the annotation marks the output as passing.
  - `feedback` string, required — Free-text feedback explaining the score.
  - `error` string, nullable, required — Generation error text, when the annotation itself errored. `null` for successful annotations.
  - `errored` boolean, required — `true` when the annotation could not be generated successfully.
  - `duration` integer, required — Generation duration in nanoseconds. `0` for human annotations.
  - `tokens` integer, required — Total LLM tokens consumed generating the score. `0` for human annotations.
  - `cost` integer, required — Total LLM cost in microcents (100,000,000 per USD). `0` for human annotations.
  - `draftedAt` string, date-time, nullable, required — ISO-8601 timestamp at which the annotation was drafted. `null` for published annotations.
  - `annotatorId` string, nullable, required — User who authored the annotation. `null` when not attributed to a user.
  - `createdAt` string, date-time, required — ISO-8601 timestamp at which the annotation was created.
  - `updatedAt` string, date-time, required — ISO-8601 timestamp of the last metadata update.
  - `source` 'annotation', required — Always `"annotation"` for this shape.
  - `sourceId` union, required — Origin marker. Sentinel `"UI"` / `"API"` / `"SYSTEM"` for drafts and automation, or a CUID for authored rows.
    - 'UI' | 'API' | 'SYSTEM'
    - string
  - `metadata` AnnotationMetadata, required — Annotation-specific metadata: `rawFeedback` plus a snapshot of the anchor at write time.
    - `rawFeedback` string, required — Original feedback text as written by the annotator, before any server-side enrichment.
    - `messageIndex` integer — 0-based message index inside the conversation. Omit for conversation-level annotations.
    - `partIndex` integer — 0-based index into the target message's `parts[]`. Requires `messageIndex`.
    - `startOffset` integer — Inclusive start offset for substring annotations. Must be paired with `endOffset` and `partIndex`.
    - `endOffset` integer — Exclusive end offset for substring annotations. Must be paired with `startOffset` and `partIndex`, and `>= startOffset`.
    - `textFormat` 'pretty-json' — UI-side text transform applied before the offsets were captured (e.g. `"pretty-json"`). Resolvers must apply the same transform before slicing.

## Other responses

- `400` — Validation error
- `401` — Unauthorized
- `404` — Not found

---

[API](https://skmtc.net/latitude-dev/apis/latitude.md) · [All operations](https://skmtc.net/latitude-dev/apis/latitude/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/latitude-dev/latitude/versions/6a8789c59a5c/schema)
