> ## Documentation Index
> Fetch the complete documentation index at: https://omniloy.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Pre-fill from your EMR (updateTemplate)

> Feed what the doctor already typed in your own form into report generation so notes integrate existing content

`updateTemplate` is a host callback that lets your EMR (SINA/HIS) hand SofIA **whatever the doctor has already written in your own form fields**. SofIA merges that content into the extraction template as context, so the generated clinical note **integrates what is already documented** instead of:

* producing an **identical copy** on **Regenerate**, or
* **ignoring** notes the doctor typed during the consultation.

You provide a function; the SDK calls it (a "pull") at the right moments and does the rest — merging, anonymizing, and de-anonymizing are all handled inside the SDK.

This page explains the **contract**, **when it is called**, and **how to wire it**.

## How it fits into the flow

The SDK **pulls** your callback at four moments and merges the result into the template it sends to the extraction backend:

<Steps>
  <Step title="Recording starts">
    `updateTemplate()` feeds the live partial extraction — a note can carry context **before** recording even starts.
  </Step>

  <Step title="Recording stops">
    `updateTemplate()` feeds the background auto-draft.
  </Step>

  <Step title="Generate clicked">
    `updateTemplate()` is pulled again for the generated report.
  </Step>

  <Step title="Regenerate clicked">
    `updateTemplate()` is pulled again so the regenerated note reflects the latest form content.
  </Step>
</Steps>

Each returned value is merged into the template as `properties.<field>.existingValue`, then sent to the extraction backend as generation context. You do **not** call anything yourself — just assign the function, and the SDK invokes it whenever it needs the freshest content.

## The contract

```typescript theme={null}
type UpdateTemplateCallback = () =>
  | Record<string, unknown>            // the existing content, keyed by field id
  | null                               // or "nothing to add"
  | undefined
  | Promise<Record<string, unknown> | null | undefined>; // may be async
```

Return an object whose **keys are the template property ids** and whose values are the current content of those fields in your EMR:

| Field kind in the template                                                 | Value you return                                                      |
| -------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Prose / scalar (`chief_complaint`, `hpi`, `plan`, `assessment`, …)         | a **string**                                                          |
| Multi-option / array sections (`diagnoses`, `medications`, `allergies`, …) | an **array of entries** (objects), shaped like the template's `items` |

```json theme={null}
{
  "chief_complaint": "Chest pain for 2 days",
  "plan": "Order ECG and bloodwork",
  "diagnoses": [
    { "icd10_code": "I10", "name": "Essential hypertension" }
  ]
}
```

Rules:

* **Keys must match template property ids exactly.** Keys that don't match any property are ignored.
* **Empty values are skipped.** Empty strings, whitespace-only strings, empty arrays, `null`, and `undefined` are dropped — that field falls back to normal generation from the transcript alone (**no degradation**).
* The function **may be sync or async**. Return `null`/`undefined`/`{}` when there is nothing to contribute.
* Return only the fields you have content for — you don't need to send every key.

## Using it

<CodeGroup>
  ```tsx React theme={null}
  import { Omniscribe } from '@omniloy/sofia-sdk/react';
  import '@omniloy/sofia-sdk/react/index.css';

  <Omniscribe
    apikey={API_KEY}
    userid={USER_ID}
    patientid={PATIENT_ID}
    template={REPORT_TEMPLATE}

    // Called by the SDK when it needs the doctor's existing EMR content.
    updateTemplate={() => ({
      chief_complaint: form.chiefComplaint,
      hpi: form.hpi,
      plan: form.plan,
      diagnoses: form.diagnoses, // [{ icd10_code, name }, ...]
    })}
  />
  ```

  ```html Web Component theme={null}
  <sofia-sdk id="sofia" apikey="your-api-key" userid="doctor-123" patientid="patient-456"></sofia-sdk>

  <script>
    const el = document.querySelector('#sofia');

    // updateTemplate is a function prop — assign it as a JS property, not an HTML attribute
    el.updateTemplate = () => ({
      chief_complaint: readField('chief_complaint'),
      plan: readField('plan'),
      diagnoses: readRows('diagnoses'), // [{ icd10_code, name }, ...]
    });
  </script>
  ```
</CodeGroup>

<Tip>
  The callback is read fresh on every pull, so you can return live values from your current form state — no need to re-assign it when the form changes.
</Tip>

### Props reference

| Prop             | Type                                                               | Purpose                                                                                                                                                   |
| ---------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `updateTemplate` | `() => Record<string, unknown> \| null \| undefined \| Promise<…>` | Returns the doctor's existing EMR field content, keyed by template property id. Pulled by the SDK at recording start/stop and before generate/regenerate. |
| `template`       | JSON Schema (`object`)                                             | The report structure. `updateTemplate` keys map to `template.properties.*`.                                                                               |

## What the SDK does with it

1. **Pull** — calls `updateTemplate()` (awaiting it if it returns a Promise).
2. **Merge** — for each returned key that matches a template property and has non-empty content, injects it as `template.properties.<field>.existingValue`. The template you passed is **never mutated** — a copy is sent.
3. **Anonymize (outbound)** — the injected `existingValue` is scrubbed with the same real→placeholder map already applied to the transcript, before it leaves for the transcriber (WebSocket) and the extraction LLM (HTTP). You do **not** need to anonymize anything yourself.
4. **De-anonymize (inbound)** — when the model echoes your content back in the result, the SDK restores the real values, so the doctor sees **exactly what they wrote** — never a placeholder.

Your backend reads the content from `properties.<field>.existingValue` in the `json_schema` it receives. **No changes to the request payload shape are needed** — the content rides inside the template that is already sent.

<Info>
  Anonymization here mirrors the [patient data](/sofia/en/sdk/patient-data#automatic-anonymization) flow: the direct identifiers in `patientdata` and the injected `existingValue` are masked before leaving the browser and restored in the final output.
</Info>

## Behavior when there is nothing to add

This path is intentionally safe:

* `updateTemplate` **not provided** → the SDK behaves exactly as before.
* Returns `null` / `undefined` / `{}` → nothing is injected; normal generation.
* A field is **empty** or its key **doesn't match** a property → that field is skipped; other fields are still used.

In all of these, generation proceeds normally from the transcript — there is no degradation and no error.

## Quick checklist

* [ ] You pass a `template` (JSON Schema) to the SDK.
* [ ] `updateTemplate` returns an object keyed by **template property ids**.
* [ ] Prose fields are **strings**; array sections are **arrays of entries**.
* [ ] Empty/unknown fields are omitted (or just left empty — the SDK skips them).
* [ ] Your backend reads `properties.<field>.existingValue` from the `json_schema`.
* [ ] (No action needed for PII) — the SDK anonymizes outbound and restores inbound.

<Warning>
  If regenerated notes still look identical, confirm your `updateTemplate` keys match the template property ids and that the values are non-empty — mismatched or empty keys are silently skipped by design.
</Warning>

## Next steps

* **[Clinical data schemas](/sofia/en/sdk/templates)** — the `template` whose property ids your keys must match
* **[Insertion preview modal](/sofia/en/sdk/insertion-preview)** — let the doctor curate the generated report before it reaches your app
* **[Patient data](/sofia/en/sdk/patient-data)** — how contextual data is anonymized
