Circle V2 API Docs
    Preparing search index...
    testFill: MutationProcedure<
        {
            input: {
                annotationIds?: string[];
                chosenContacts?: Record<string, string>;
                formId: string;
                includeEmr?: boolean;
                maxAiFields?: number;
                patientId: string;
                renderAnswers?: {
                    annotationId: string;
                    value:
                        | { kind: "simple"; values: string[] }
                        | { kind: "subfields"; subfields: Record<string, string> };
                }[];
                renderPdf?: boolean;
                selectedDocumentIds?: string[];
                selectedSessionIds?: string[];
                treatmentEpisodeId?: string;
            };
            meta: object;
            output: {
                aiFieldCount: number;
                aiFieldIds: string[];
                aiFieldsAnswered: number;
                chunkSize: number;
                degradations: DegradationSummaryEntry[];
                deterministicAnswerCount: number;
                fields: DryRunFormFillField[];
                formId: FormId;
                patientId: PatientId;
                pdf: { byteLength: number; dataUrl: string; fileName: string }
                | null;
                pdfOmittedReason: "too_large" | "not_requested" | null;
                skippedFieldIds: string[];
                truncated: boolean;
                undrawnCount: number;
                unpositionedCount: number;
            };
        },
    > = ...

    Answers a sample of this template's fields against a real patient chart WITHOUT persisting anything — no run, no answers, no document, no analytics event claiming a fill happened.

    Carries canAccessPatient rather than a template gate: unlike every other procedure in this router it reads a patient's chart. The form, its org and every chosen contact are authorized inside the service by the SAME checks startFormFillRun runs.

    It runs INLINE, which is why the field cap exists. An uncapped session stays inline by chunking: annotationIds bounds each call to one chunk of the output's aiFieldIds, and a final renderAnswers call draws the accumulated answers into ONE PDF. The server remembers nothing between calls, so the client carries the answers.