Circle V2 API Docs
    Preparing search index...

    Type Alias TemplateSnapshotCoordinate

    One coordinates row of an annotation, as-persisted: spatial fields are TEXT in the legacy schema (stringified numbers) and are intentionally NOT parsed here — the fill pipeline owns numeric interpretation, and round-tripping the raw strings keeps the snapshot lossless.

    NULLABILITY IS AUTHORITATIVE: every spatial column is nullable TEXT in the legacy schema, so these are string | null; readers must handle a null spatial value.

    v1 semantics of value (binding for readers):

    • value IS NULL → the annotation's parent bounding box.
    • value IS NOT NULL → a sub-field prompt box (value holds the sub-prompt text).
    type TemplateSnapshotCoordinate = {
        height: string | null;
        hPct: string | null;
        id: number;
        page: string | null;
        value: string | null;
        width: string | null;
        wPct: string | null;
        x: string | null;
        xPct: string | null;
        y: string | null;
        yPct: string | null;
    }
    Index

    Properties

    height: string | null
    hPct: string | null
    id: number

    Numeric coordinate id. It corresponds to the sub-field answer-value keys, but those keys are STRINGS (Object.entries over a jsonb object yields "123", never 123).

    Consumers MUST normalize with String(coord.id) before any Set/Map/includes lookup against sub-field keys. Bracket indexing (obj[coord.id]) coerces and works by accident, which is exactly what makes the other forms dangerous: new Set(keys).has(coord.id) and keys.includes(coord.id) silently miss on every row and render blank sub-fields with no error.

    page: string | null
    value: string | null
    width: string | null
    wPct: string | null
    x: string | null
    xPct: string | null

    Percentage-based spatial columns, carried for fidelity/forensics ONLY.

    DO NOT RENDER FROM THESE. A production audit established that v1 derived them at save time by dividing CSS-pixel coordinates by the canvas device-pixel backing store, so on DPR-2 displays the persisted percentages are roughly HALF their true value. The stored values are unreliable in production and cannot be corrected after the fact (the authoring DPR is not recorded).

    V2's renderer (@repo/experimental-server/pdf drawAnswers) deliberately uses the ABSOLUTE x/y/width/height in PDF points — v1 rendered pages at intrinsic scale, so CSS px at zoom 1 approximates PDF points — and must NOT be switched to these percentages.

    They are captured because this payload is declared frozen and lossless: taking every spatial column now avoids a snapshotVersion bump later just to add them.

    y: string | null
    yPct: string | null