Skip to main content

Schema

Major Release V2 (2025-12)

We are switching to v2 of our sqlite database, which is about half the size. We've made it forward compatible. Incompatible changes are:

  • Renamed completed_at to entered_at in responses (entered_at added to v1 for forward copatibility)
  • Not exporting null values in response_values#data anymore. Use fields-table to know all the fields.
  • Removed question_key in response_values. field_key has been in v1 for years with same value, add an index to [response_id, field_key] for v1 for forward compatibilty. Sadly it looks like you can't name a primary key in sqlite, so either you have to check if question_key is in the table or just accept there is an duplicate index for a short while.
    CREATE INDEX if not exists response_values_response_id_field_key ON response_values (response_id, field_key);
  • Removed anonymous from responses, use hide_pii_from_researchers and hide_values_from_professionals instead. They are already present in v1 and have been for years.
  • questions.type changed date => date_parts, check_box => multi_select, radio/select/scale => single_select, string/textarea => text. integer and float remained the same. Add renames for the new/old values as needed before you switch to v2.

Schema v2

Note: For a thorough analysis of the schema check out the interactive schema representation generated with SchemaSpy of our demo sqlite export db.

Dossier info

dossiers

AttributeDescription
idour internal id
external_identifieralso known as epd_id or clientid, the clientid we got over sso when internally_managed is false
internally_managedtrue when dossier not created through sso, but within RoQua admin area
testertrue if tagged as test account, should not be used for research
metadatajson string of extra metadata added to dossier.

respondents

A respondent is a someone who fills out a questionnaire. It's the you in “How are you?” and “How is your child/patient” on a questionnaire. The one who enters the data into roqua is not always the respondent.

Right now there is only one respondent per type, but that will change in the future.

AttributeDescription
idOur internal id.
dossier_idforeign key to dossier this respondent belongs to
typepatient, parent, second_parent, teacher, caregiver, profess. second_parent will likely be merged into parent in the future
email_presenttrue if we have an email in our system for this respondent
labelhuman readable specifier. e.g. Moeder, Medewerker, Buurman

protocol_subscriptions

A protocol subscription is when an automatic protocol is activated for a dossier. The same protocol can be subscribed multiple times for one dossier, but only once the previous subscription has been stopped (either automatically upon completion, or by cancelling manually).

AttributeDescription
dossier_idforeign key to the dossier which is subscribed to this protocol
protocol_idforeign key to the protocol that is subscribed to
start_atthe first day that responses will be created on
stop_atthe last day that responses will be created on
statusscheduled when the automatic protocol is activated but the first questionnaires haven't been prepared yet (usually because at time of export, start_at was in the future; started while the protocol is ongoing; paused when the protocol is on hold for a while (currently not feature exposed in the API or UI); stopped when stopped (either because stop_at is in the past, or because it was stopped manually in the UI)

Response data

responses

A Response the set of answers to one fill out of a questionnaire. Most attributes descriptions can be found at response endpoint

AttributeDescription
idour internal id. Same in all api's.
dossier_idforeign key to dossier who the answer belongs to.
respondent_idforeign key to respondent who the answers belong to.
entered_by_idforeign key to professional who typed in the answer if the respondent didn't do it directly (so copying from paper or doing an interview)
entered_atdatetime the response was entered into our system.
observation_timedatetime the respondent answered the questions (can be changed in the interface, when copied from paper)
questionnaire_keyroqua-key of questionnaire (in a few cases different from quby-key) points to questionnaires.key
questionnaire_variantroqua-key of specific questionnaire variant (e.g. bulk version)
requester_idforeign key to professional who prepared the response in the RoQua epd interface
statusinactive / aborted / completed / scheduled / open / expired / unattached
non_response_idforeign key to non_response
open_fromdatetime start of timewindow to fill out the response, usually the time we send an email/sms
open_tilldatetime end of the timewindow to fill out the response
started_atdatetime the respondent opened the response
hide_pii_from_researchersShould show the respondent id with the response_values/scores.
hide_values_from_professionalsShould not show the response_values/scores within a dossiers.
notesnotes added by a professional.
measurement_idforeign key to measurement this response was prepared from.
team_idforeign key to team that was active when response was prepared.

response_values

Answer to a single question in a response

AttributeDescription
response_id
field_keyoften the question key, but option_key for multi_select and date_part_keys for date_parts e.g. v_1, v_2_a3, v_3_yyyy.
datavalue of answer e.g. '2' for radio with value 2, '1' for checked checkbox, 'hello' for text
question_option_key.option key in case the question is of type single_select.

response_scores

Scores are calculated values, based on the response_values.

AttributeDescription
response_idint
score_key
score_subkeymain score is called value,
datastringified result of the subscore integer/float/string

non_responses

AttributeDescription
timestampTime at of non-response, can be set by the user, defaults to creation time.
reason_group:e.g. "Patiënt is wel benaderd voor de ROM
reason_option:e.g. "Patiënt retourneert meetinstrument niet."
reason_code:e.g. "04"
reason_other:user entered text

response_flags

Flags turn on/off questions in a response.

AttributeDescription
response_idforeign key to responses
keye.g. first_measurement_of_day / last_measurement_of_day / ptr_semi_slaap / caps_5_copisac
valuetrue/false/null

Primary key: [response_id, key]

response_textvars

Textvars allow for customizing questions to e.g. make them more specific.

AttributeDescription
response_idforeign key to responses
keye.g. adhd_rs5_l_tijdsperiode / ptr_semi_eigen_vraag1
valuetext

Primary key: [response_id, key]

Global data

questionnaires

AttributeDescription
keyPrimary key string
title
short_description
description
licensefree / pay_per_completion / private / deprecated / unknown
sbg_key

questions

AttributeDescription
questionnaire_keypoint to questionnaires.key
key
positionorder on the screen
titletitle on screen for the respondent
context_free_titletitle for professional, adds context if needed, often removes examples. defaults to title
sbg_key
question_typetext / integer / float / single_select / multi_select / date_parts

Primary key: [questionnaire_key, key]

question_options

AttributeDescription
questionnaire_keypoints to questionnaires.key
question_keypoints to questions.key
keyoption key
positionorder on screen
description
valuestringified integer/float

Primary key: [questionnaire_key, question_key, key]

fields

AttributeDescription
questionnaire_keypoints to questionnaires.key
keysee responses.field_key
typestring / integer / decimal / boolean
description

Primary key: [questionnaire_key, key]

scores

AttributeDescription
questionnaire_keypoints to questionanires.key
score_key
score_subkeyprimary subscore is value.
csv_keyheader to use in csv export
label
sbg_key

Primary key: [questionnaire_key, score_key, score_subkey]