Beta: These six tables are in beta. Their schema may change without the notice period that change management gives generally available tables.
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.
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.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.
For the full column list of every table mentioned here, see the hosted database schema reference.
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.
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_ididentifies the Elation Note.visit_note_ididentifies the same note invisit_note.
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 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
Question formats in the data
The question formats a practice picks in the custom block builder do not map one-to-one ontoquestion_type. Several collapse together:
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 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_textis 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_nameis 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.labelis 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 wherequestion_textis 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 joinelation_note_response_optionto 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.
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_blockholds the block as it exists today. Itscurrent_state_snapshotcolumn 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_snapshotholds the definition frozen when a note used the block. Itscustom_block_snapshotcolumn 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:Rolling a question up across notes
This counts how many notes selected each option for one question:question_id to use, list the questions your practice’s blocks actually collect:
Combining with Visit Note data
Join tovisit_note for the encounter date, author, and sign-off:
Related Articles
- Elation Note Guide - Managing custom blocks
- Elation Note Introduction
- Visit Notes
- Visit Notes and Bills
- Where can I see what data is available?
- Hosted Database Release Notes