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

# Elation Note

<Info>**Beta:** These six tables are in beta. Their schema may change without the notice period that [change management](/articles/hdb/change-management) gives generally available tables.</Info>

The Elation Note is the note format that supersedes the legacy Visit Note. Within it, practices build **custom blocks** to collect structured, reusable sets of questions during a visit. Unlike the free-text bullets in `visit_note_bullet`, the answers are stored as question-and-answer data you can group, filter, and aggregate directly in SQL.

This page covers how that data is modeled for querying. For what custom blocks are, how to build one, and how the question formats and conditional logic behave in the application, see [Elation Note Guide - Managing custom blocks](/articles/Elation-Note-Guide-custom-blocks).

## The six tables

Six tables model this data, in two groups.

### Answer tables: what clinicians recorded

These hold the answers themselves. Rows reference a patient and a note, and volume scales with how much documenting a practice does.

| Table                              | What it holds                                                                                                                                                                             |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`elation_note`**                 | The reporting table for custom block answers. **Not one row per note.** One row per answer value, already joined to its question and its response label. Start here for querying answers. |
| **`elation_note_structured_data`** | The raw answer records behind `elation_note`, keyed on the Elation Note's own identifier. Has the widest coverage of the six tables.                                                      |

### Configuration tables: how the blocks are built

These describe the blocks and questions a practice has set up, not anything a clinician entered. They are practice-scoped and reused across every note, so they are small and change only when someone edits a block in Settings.

| Table                                    | What it holds                                                                                        |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| **`elation_note_custom_block`**          | Current state of each custom block a practice has built, including its label.                        |
| **`elation_note_custom_block_snapshot`** | The block's definition frozen at the time a note used it.                                            |
| **`elation_note_question`**              | Current definition of each question in a custom block: its prompt, type, and whether it is required. |
| **`elation_note_response_option`**       | The selectable options for choice-style questions, mapping a stored value to its display text.       |

For the full column list of every table mentioned here, see the [hosted database schema reference](/articles/hdb/where-can-i-see-what-data-is-available).

## What a row in `elation_note` represents

Each row is **one answer value**: a single question's answer within a single custom block on a single note.

A single note typically occupies dozens of rows, one for every answer value in every custom block it uses. For note-level results, aggregate by `el8_note_id` or `visit_note_id`, or query `visit_note` for the note record itself.

* A single-value question (`string`, `date`, `boolean`) produces exactly one row.
* A multi-select question (`array`) produces **one row per selected option**. A question with four boxes checked returns four rows.

Because of this, `elation_note` has no single-column primary key, and `visit_note_id` plus `question_id` is not unique.

Expect `elation_note` to be far smaller than `visit_note`: it covers only the notes that use custom blocks.

## How Elation Notes relate to Visit Notes

Every Elation Note also exists as a Visit Note, and the answer tables carry both identifiers:

* **`el8_note_id`** identifies the Elation Note.
* **`visit_note_id`** identifies the same note in `visit_note`.

The two are one to one: one Elation Note, one Visit Note. Neither is unique within `elation_note` itself, because a note spans many answer rows.

This matters for two reasons.

**Note-level attributes live on the Visit Note.** The answer tables carry `patient_id` and `practice_id` but nothing about the note itself. For the encounter date, the author, or the sign-off, join to `visit_note` as the [example below](#combining-with-visit-note-data) does.

**`visit_note_bullet` carries the same answers as text.** Custom block answers also appear in the note's bullets, written into the prose the way a reader sees them. What `elation_note` adds is structure: the answer separated from its question, its response label resolved, and one row per value. Query `elation_note` to group, filter, or aggregate answers; read `visit_note_bullet` when you want the note as it was written.

## Table relationships

```mermaid theme={null}
erDiagram
    visit_note ||--o| elation_note : visit_note_id
    patient ||--o{ elation_note : patient_id
    elation_note }o--|| elation_note_question : question_id
    elation_note }o--|| elation_note_custom_block_snapshot : custom_block_snapshot_id
    elation_note_structured_data }o--|| elation_note_question : question_id
    elation_note_structured_data }o--|| elation_note_custom_block_snapshot : versioned_custom_block_id
    elation_note_custom_block_snapshot }o--|| elation_note_custom_block : custom_block_id
    elation_note_question ||--o{ elation_note_response_option : question_id
```

## Question formats in the data

The question formats a practice picks in the custom block builder do not map one-to-one onto `question_type`. Several collapse together:

| Format in the builder | Stored `question_type` | How to recognize it                               |
| --------------------- | ---------------------- | ------------------------------------------------- |
| Paragraph Text        | `string`               | No rows in `elation_note_response_option`         |
| Dropdown Select       | `string`               | Has rows in `elation_note_response_option`        |
| Radio Select          | `string`               | Has rows in `elation_note_response_option`        |
| Checkbox              | `array`                | Always has rows in `elation_note_response_option` |
| Date                  | `date`                 | No rows in `elation_note_response_option`         |

Dropdown and Radio are therefore indistinguishable once stored, and free text is the `string` question with no response options. You may also see `question_type = 'boolean'`, which carries no options and holds its value directly.

See [Managing custom blocks](/articles/Elation-Note-Guide-custom-blocks) for what each format does for the clinician.

## Identifying a question

Three columns describe the question an answer belongs to, and they are not equally reliable:

* **`question_text`** is the prompt shown to the clinician. How reliably it is populated depends entirely on how a practice built its blocks. Some have prompt text on nearly every question; others leave it blank on most of them and rely on a visual label instead. Check your own data before building a report around it.
* **`field_name`** is a machine-generated identifier: a short random string of letters, numbers, and dashes. It is not human-readable, but it is stable and consistent across notes, which makes it a dependable key for grouping the same question across many notes.
* **`elation_note_custom_block.label`** is the block's human-readable name, as the practice titled it in Settings. Joining through the snapshot to get this label is usually the fastest way to make results readable, and it works even where `question_text` is blank.

## How `response` is populated

`elation_note.response` gives you the value already resolved for display:

* For choice-style questions, it holds the option's **display text** from `elation_note_response_option.response_text`, not the stored raw value. You do not need to join `elation_note_response_option` to read an answer. Join it only when you need the full list of options a question offered, including ones nobody selected.
* For free-text, date, and boolean questions, it holds the value as entered.

Answers whose option was edited or deleted after the note was signed keep the text that was recorded at the time, so a small share of responses will not match any current row in `elation_note_response_option`.

## Current blocks versus the block a note used

A practice can edit a custom block at any time: rename it, add questions, or change response options. Two tables let you choose which version you mean:

* **`elation_note_custom_block`** holds the block as it exists today. Its `current_state_snapshot` column is the block's live definition as JSON. Use this table to describe how a practice's blocks are configured now.
* **`elation_note_custom_block_snapshot`** holds the definition frozen when a note used the block. Its `custom_block_snapshot` column is a JSON array of the block's fields at that moment. Use this table to interpret historical notes correctly, since a block edited in 2026 does not describe a note signed in 2025.

`elation_note.custom_block_snapshot_id` points at the snapshot, so answers are always anchored to the version the clinician actually filled in.

## Example queries

### Reading one note's answers

This returns every custom block answer on a single note, labeled by block:

<CodeGroup>
  ```sql sql theme={null}
  select
      b.label           as block_label
    , n.field_name
    , n.question_text
    , n.question_type
    , n.response
  from elation_note n
  join elation_note_custom_block_snapshot s
    on s.id = n.custom_block_snapshot_id
  join elation_note_custom_block b
    on b.id = s.custom_block_id
  where n.visit_note_id = <visit_note_id>
    and n.is_deleted = false
    and n.is_visible = true
  order by b.label, n.field_name;
  ```
</CodeGroup>

### Rolling a question up across notes

This counts how many notes selected each option for one question:

<CodeGroup>
  ```sql sql theme={null}
  select
      n.response
    , count(distinct n.visit_note_id) as notes
  from elation_note n
  where n.question_id = <question_id>
    and n.is_deleted = false
    and n.is_visible = true
  group by n.response
  order by notes desc;
  ```
</CodeGroup>

To find the `question_id` to use, list the questions your practice's blocks actually collect:

<CodeGroup>
  ```sql sql theme={null}
  select
      b.label           as block_label
    , n.question_id
    , n.field_name
    , n.question_text
    , n.question_type
    , count(distinct n.visit_note_id) as notes
  from elation_note n
  join elation_note_custom_block_snapshot s
    on s.id = n.custom_block_snapshot_id
  join elation_note_custom_block b
    on b.id = s.custom_block_id
  where n.is_deleted = false
    and n.is_visible = true
  group by 1, 2, 3, 4, 5
  order by notes desc;
  ```
</CodeGroup>

### Combining with Visit Note data

Join to `visit_note` for the encounter date, author, and sign-off:

<CodeGroup>
  ```sql sql theme={null}
  select
      v.id           as visit_note_id
    , v.document_date
    , v.physician_user_id
    , v.signed_time
    , b.label        as block_label
    , n.field_name
    , n.response
  from elation_note n
  join visit_note v
    on v.id = n.visit_note_id
  join elation_note_custom_block_snapshot s
    on s.id = n.custom_block_snapshot_id
  join elation_note_custom_block b
    on b.id = s.custom_block_id
  where v.document_date >= '2026-01-01'
    and v.deletion_time is null
    and n.is_deleted = false
    and n.is_visible = true
  order by v.document_date, b.label;
  ```
</CodeGroup>

For the note's free-text content, timing, and its relationship to bills and orders, see [Visit Notes](/articles/hdb/visit-notes).

## Related Articles

* [Elation Note Guide - Managing custom blocks](/articles/Elation-Note-Guide-custom-blocks)
* [Elation Note Introduction](/articles/Elation-Note)
* [Visit Notes](/articles/hdb/visit-notes)
* [Visit Notes and Bills](/articles/hdb/visit-notes-and-bills)
* [Where can I see what data is available?](/articles/hdb/where-can-i-see-what-data-is-available)
* [Hosted Database Release Notes](/articles/hdb/hdb-snowflake)

*If you have any questions about this topic please reach out to [Elation Support Portal](/articles/support-portal-introduction) with the subject line HDB - \<your\_question>*
