Circle V2 API Docs
    Preparing search index...
    updateAnswer: MutationProcedure<
        {
            input: {
                annotationId: string;
                deferRender?: boolean;
                fontSize?: number
                | null;
                runId: string;
                value:
                    | { kind: "simple"; values: string[] }
                    | {
                        kind: "subfields";
                        subfields: Record<string, { fontSize?: number; value: string }>;
                    }
                    | { kind: "null" };
            };
            meta: object;
            output: {
                answer: {
                    annotationId: string;
                    annotationPrompt: string
                    | null;
                    annotationType: "ai_prompt" | "checkbox" | "text" | "contact";
                    answerId: string;
                    canRevertToAiAnswer: boolean;
                    citations: unknown;
                    contactLink: { contactTypeName: string; fieldKey: string } | null;
                    contextSources: NormalizedContextSource[];
                    coordinates: FormAnswerCoordinate[];
                    coordinatesSource: CoordinateSource;
                    createdAt: string | null;
                    fieldStatus: FormRunFieldStatus;
                    fontSize: string | null;
                    generatedByAi: boolean | null;
                    isExclusive: boolean | null;
                    noAnswerReason: NoAnswerReasonCode | null;
                    status: string | null;
                    subfieldProgress: { filled: number; total: number } | null;
                    updatedAt: string | null;
                    value: DecodedAnswerValue;
                };
                document: EditedDocumentState;
                runId: FormRunId;
            };
        },
    > = ...

    Edit one answer by hand and mark it manual_override.

    The response is EXACTLY one element of getAnswers' answers (same toAnswerOutput) so the drawer patches its cache in place; building it costs a whole-run re-read because listForRun is the only read the repo exposes. updateValue's WHERE clause is keyed on BOTH run and annotation, so a foreign annotation matches nothing and no id in the body can steer the write. manual_override is a latch: bulkUpsert skips such rows, so an edit made mid-fill wins over the model.

    The row is read first only to carry its per-coordinate statuses across the write — see toDecodedAnswerValue. The write is unconditional on that read, so a concurrent upsert can cost a stale status on one box and nothing else.

    The PDF is redrawn synchronously after the answer is durable; a failed redraw is never fatal, document.isStale reports it. With deferRender the redraw is skipped and document.deferred says so, for a batch that renders once at its end; the answer is committed exactly the same way.