Circle V2 API Docs
    Preparing search index...
    revertAnswer: MutationProcedure<
        {
            input: { annotationId: string; deferRender?: boolean; runId: string };
            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;
            };
        },
    > = ...

    Undo a manual edit by restoring what the pipeline answered, from form_answers.ai_value.

    It goes through the SAME write and redraw path as updateAnswer — updateValue, then refreshDocument — so the stored PDF is redrawn and document.isStale reports it exactly as it does for an edit. A revert that only rewrote the row would leave the document showing the value the user just undid.

    The restored row goes back to a PIPELINE status rather than staying manual_override: reverting means "this is the model's answer again", and leaving the human latch on would keep a retry from ever touching the field. Which pipeline status is derived from the restored content the same way classifyAnswer reads it — a value with content is completed, an empty one no_answer — rather than remembered, because the original status is not recoverable and inventing completed for an empty cell is precisely the v1 bug ("N/A" persisted as a completed answer) this feature exists to undo. ai_value itself is untouched, so a revert is idempotent.

    PRECONDITION_FAILED when the row has no ai_value: every row written before the column existed, and every v1 run. That is a state, not a fault — canRevertToAiAnswer on the answer row tells the client not to offer the control at all, and this is the server's own check of the same fact.