Aidbox SDC API
Generate a link to a QuestionnaireResponse - $generate-link
This operation generates a link to a web page to be used to continue answering a specified QuestionnaireResponse.
URLs
POST [base]/QuestionnaireResponse/[id]/$generate-link
Parameters
NOTE: All parameters wrapped with Parameters object
resourceType: Parameters
parameter:
- name: [var-name]
value: [var-value]
allow-amend
Whether the generated link will allow amending and re-submitting the form.
name: allow-amend
value:
Boolean: true
allow-repopulate
Whether the generated link will allow re-populating the form.
NOTE: Repopulate will be working only with forms that contain populate behavior
name: allow-repopulate
value:
Boolean: true
redirect-on-submit
A URL where the user will be redirected to after successfully submitting the form.
name: redirect-on-submit
value:
String: https://example.com/submit-hook?questionnaire=123
redirect-on-save
A URL where the user will be redirected to after hitting Save button.
By default
Save button is not visible- form autosaved after every keystroke. But sometimes it's usefull to close form in a partially-filled state
name: redirect-on-save
value:
String: https://example.com/submit-hook?questionnaire=123
expiration
Link expiration period (days)
name: expiration
value:
Integer: 30
By default thir parameter = 7 days
theme
Form theme.
name: theme
value:
String: hs-theme
read-only
Show form in a read-only mode
name: read-only
value:
Boolean: true
app-name
Application name that will be used in Audit logging when returned link was used.
Audit logging should be enabled.
- name: app-name
value
String: my-app
Usage Example
POST [base]/QuestionnaireResponse/[id]/$generate-link
content-type: text/yaml
resourceType: Parameters
parameter:
- name: allow-amend
value:
Boolean: true
- name: redirect-on-submit
value:
String: https://example.com/submit-hook?questionnaire=123
HTTP status: 200
link: http://forms.aidbox.io/ui/sdc#/questionnaire-response/12c1178c-70a9-4e02-a53d-65b13373926e?token=eyJhbGciOiJIUzI
HTTP status: 422
resourceType: OperationOutcome
text:
status: generated
div: Parameters are invalid
issue:
- severity: error
code: invalid
expression:
- parameter.0.resource
diagnostics: unknown key :resource
Aidbox uses HS256 to sign JWT token by default. To use RS256 you need to set
BOX_SECURITY_AUTH_KEYS_PRIVATEandBOX_SECURITY_AUTH_KEYS_PUBLICenvironment variables.
Save a QuestionnaireResponse - $save
This operation validates the structure of a QuestionnaireResponse and saves it. It performs basic structural validation, but does not validate against the associated Questionnaire definition.
The operation validates only FHIR structure of QuestionnaireResponse and have associated Questionnaire. Operation doesn't validate for example — required fields like $submit operation
URLs
POST [base]/fhir/QuestionnaireResponse/$save
Parameters
NOTE: All parameters wrapped with Parameters object
resourceType: Parameters
parameter:
- name: response
resource:
# QuestionnaireResponse resource here
The operation takes a single input parameter named "response" containing a QuestionnaireResponse resource wrapped in a Parameters resource.
Output Parameters
The operation returns:
- response: The saved QuestionnaireResponse resource
- issues: Any validation issues encountered (if applicable)
Usage Example
POST [base]/fhir/QuestionnaireResponse/$save
content-type: text/yaml
resourceType: Parameters
parameter:
- name: response
resource:
resourceType: QuestionnaireResponse
questionnaire: Questionnaire/patient-registration
status: in-progress
item:
- linkId: name
text: Patient Name
item:
- linkId: name.given
text: Given Name
answer:
- valueString: John
- linkId: name.family
text: Family Name
answer:
- valueString: Smith
HTTP status: 200
resourceType: Parameters
parameter:
- name: response
resource:
resourceType: QuestionnaireResponse
id: 12c1178c-70a9-4e02-a53d-65b13373926e
questionnaire: Questionnaire/patient-registration
status: in-progress
item:
- linkId: name
text: Patient Name
item:
- linkId: name.given
text: Given Name
answer:
- valueString: John
- linkId: name.family
text: Family Name
answer:
- valueString: Smith
HTTP status: 422
resourceType: Parameters
parameter:
- name: issue
resource:
resourceType: OperationOutcome
issue:
- severity: fatal
code: invalid
expression:
- QuestionnaireResponse.item[0].item[1].answer[0].valueDecimal
details:
coding:
- system: http://aidbox.app/CodeSystem/operation-outcome-type
code: invalid-type
- system: http://aidbox.app/CodeSystem/schema-id
code: QuestionnaireResponse
diagnostics: Invalid type for the field. Expected 'string', but got 'decimal'
Submit a QuestionnaireResponse - $submit
This operation validates and submits a QuestionnaireResponse, marking it as "completed" or "amended". It performs comprehensive validation against the associated Questionnaire definition. If validation fails, it returns only the "issues" parameter without the "response" parameter and does not save the QuestionnaireResponse.
URLs
POST [base]/fhir/QuestionnaireResponse/$submit
Parameters
NOTE: All parameters wrapped with Parameters object
resourceType: Parameters
parameter:
- name: response
resource:
# QuestionnaireResponse resource here
The operation takes a single input parameter named "response" containing a QuestionnaireResponse resource wrapped in a Parameters resource.
Output Parameters
The operation returns:
- response: The submitted QuestionnaireResponse resource with status updated to "completed"
- issues: Any validation issues encountered (if applicable)
Usage Example
POST [base]/fhir/QuestionnaireResponse/$submit
content-type: text/yaml
resourceType: Parameters
parameter:
- name: response
resource:
resourceType: QuestionnaireResponse
questionnaire: Questionnaire/patient-registration
status: in-progress
item:
- linkId: name
text: Patient Name
item:
- linkId: name.given
text: Given Name
answer:
- valueString: John
- linkId: name.family
text: Family Name
answer:
- valueString: Smith
- linkId: birthDate
text: Date of Birth
answer:
- valueDate: '1970-01-01'
- linkId: gender
text: Gender
answer:
- valueCoding:
system: http://hl7.org/fhir/administrative-gender
code: male
display: Male
HTTP status: 200
resourceType: Parameters
parameter:
- name: response
resource:
resourceType: QuestionnaireResponse
id: 12c1178c-70a9-4e02-a53d-65b13373926e
questionnaire: Questionnaire/patient-registration
status: completed
item:
- linkId: name
text: Patient Name
item:
- linkId: name.given
text: Given Name
answer:
- valueString: John
- linkId: name.family
text: Family Name
answer:
- valueString: Smith
- linkId: birthDate
text: Date of Birth
answer:
- valueDate: '1970-01-01'
- linkId: gender
text: Gender
answer:
- valueCoding:
system: http://hl7.org/fhir/administrative-gender
code: male
display: Male
HTTP status: 422
resourceType: Parameters
parameter:
- name: issues
resource:
resourceType: OperationOutcome
issue:
- severity: error
code: required
expression:
- QuestionnaireResponse.item[3]
diagnostics: 'Missing required field: Contact Information'
Notify a Patient - $notify-patient
This is an asynchronous operation that sends an email notification to a patient with a generated form link for an existing QuestionnaireResponse. It supports scheduled sending, follow-up reminders, form expiration, and clinician notifications on completion or expiration.
The operation returns immediately with HTTP 202.
URLs
POST [base]/fhir/QuestionnaireResponse/$notify-patient
Parameters
NOTE: All parameters wrapped with Parameters object
resourceType: Parameters
parameter:
- name: provider
valueString: sendgrid-provider # required. One of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider
- name: response
valueReference:
reference: QuestionnaireResponse/qr-1 # required
- name: email
valueString: patient@example.com # required
- name: email-subject
valueString: "Please complete this form" # optional
- name: email-message
valueString: "Hi {{patient.firstName}}, please complete the {{form.title}} form." # optional, mustache
- name: clinician-email
valueString: doctor@example.com # optional
- name: send-at
valueString: "2026-03-25T14:00:00Z" # optional, ISO 8601
- name: config
part:
- name: deadline-days
valueInteger: 7 # optional, default: 7
- name: follow-up-enabled
valueBoolean: true # optional, default: false
- name: follow-up-delay-days
valueInteger: 3 # optional, default: 3
- name: follow-up-time
valueString: "10:00" # optional, HH:mm UTC, default: 10:00
- name: follow-up-message
valueString: "Reminder: please complete the form" # optional, mustache
The operation takes:
- provider (required): Email provider name. Must be one of
smtp-provider,postmark-provider,mailgun-provider,sendgrid-provider. - response (required): QuestionnaireResponse reference.
- email (required): Recipient email address.
- email-subject (optional): Custom email subject line. If not provided, the default subject like
"Please complete this form"is used. - email-message (optional): Custom email body message. Supports mustache templates with
{{patient.firstName}},{{patient.lastName}},{{form.title}},{{form.link}}. If not provided, a default message is used. - clinician-email (optional): Practitioner email to notify when the patient completes or misses the form.
- send-at (optional): ISO 8601 datetime for scheduled sending. If not provided, the email is sent immediately.
- config (optional): Configuration:
- deadline-days (optional, default
7): Number of days before the form link expires. - follow-up-enabled (optional, default
false): Enable follow-up reminder emails. - follow-up-delay-days (optional, default
3): Days after initial send to send the reminder. - follow-up-time (optional, default
"10:00"): Time of day (HH:mm, UTC) to send the reminder. - follow-up-message (optional): Custom reminder message. Supports the same mustache templates as
email-message.
- deadline-days (optional, default
Output
Success Response — HTTP 202 Accepted
resourceType: OperationOutcome
text:
status: generated
div: "Workflow accepted"
issue:
- severity: information
code: informational
diagnostics: "Workflow accepted"
Validation Error — HTTP 422
resourceType: OperationOutcome
text:
status: generated
div: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
issue:
- severity: fatal
code: invalid
diagnostics: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
Usage Example
POST [base]/fhir/QuestionnaireResponse/$notify-patient
content-type: text/yaml
resourceType: Parameters
parameter:
- name: provider
valueString: sendgrid-provider
- name: response
valueReference:
reference: QuestionnaireResponse/qr-1
- name: email
valueString: patient@example.com
- name: clinician-email
valueString: doctor@clinic.com
- name: config
part:
- name: deadline-days
valueInteger: 7
HTTP status: 202
resourceType: OperationOutcome
text:
status: generated
div: "Workflow accepted"
issue:
- severity: information
code: informational
diagnostics: "Workflow accepted"
HTTP status: 422
resourceType: OperationOutcome
text:
status: generated
div: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
issue:
- severity: fatal
code: invalid
diagnostics: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
Send a Questionnaire to a Patient - $send
This is an asynchronous operation that populates a QuestionnaireResponse from a Questionnaire, generates a form link, and sends it to the patient via email. It supports scheduled sending, follow-up reminders, form expiration, and clinician notifications on completion or expiration.
This is the same as $notify-patient, but called at the Questionnaire level.
The operation returns immediately with HTTP 202.
URLs
POST [base]/fhir/Questionnaire/$send
Parameters
NOTE: All parameters wrapped with Parameters object
resourceType: Parameters
parameter:
- name: provider
valueString: sendgrid-provider # required. One of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider
- name: questionnaire
valueReference:
reference: Questionnaire/intake-form # required
- name: email
valueString: patient@example.com # required
- name: subject
valueReference:
reference: Patient/pt-1 # optional
- name: encounter
valueReference:
reference: Encounter/enc-1 # optional
- name: email-subject
valueString: "Please complete this form" # optional
- name: email-message
valueString: "Hi {{patient.firstName}}, please complete the {{form.title}} form." # optional, mustache
- name: clinician-email
valueString: doctor@example.com # optional
- name: send-at
valueString: "2026-03-25T14:00:00Z" # optional, ISO 8601
- name: config
part:
- name: deadline-days
valueInteger: 7 # optional, default: 7
- name: follow-up-enabled
valueBoolean: true # optional, default: false
- name: follow-up-delay-days
valueInteger: 3 # optional, default: 3
- name: follow-up-time
valueString: "10:00" # optional, HH:mm UTC, default: 10:00
- name: follow-up-message
valueString: "Reminder: please complete the form" # optional, mustache
The operation takes:
- provider (required): Email provider name. Must be one of
smtp-provider,postmark-provider,mailgun-provider,sendgrid-provider. - questionnaire (required): Questionnaire reference. The operation will populate a new QuestionnaireResponse from it.
- email (required): Recipient email address.
- subject (optional): Patient reference. Used for populating the QuestionnaireResponse and personalizing the email template (e.g.
{{patient.firstName}}). - encounter (optional): Encounter reference. Passed to
$populatefor context. - email-subject (optional): Custom email subject line. If not provided, the default subject
"Please complete this form"is used. - email-message (optional): Custom email body message. Supports mustache templates with
{{patient.firstName}},{{patient.lastName}},{{form.title}},{{form.link}}. If not provided, a default message is used. - clinician-email (optional): Practitioner email to notify when the patient completes or misses the form.
- send-at (optional): ISO 8601 datetime for scheduled sending. If not provided, the email is sent immediately after population.
- config (optional): Configuration:
- deadline-days (optional, default
7): Number of days before the form link expires. - follow-up-enabled (optional, default
false): Enable follow-up reminder emails. - follow-up-delay-days (optional, default
3): Days after initial send to send the reminder. - follow-up-time (optional, default
"10:00"): Time of day (HH:mm, UTC) to send the reminder. - follow-up-message (optional): Custom reminder message. Supports the same mustache templates as
email-message.
- deadline-days (optional, default
Steps
The operation performs the following steps:
- populate-form — Calls
Questionnaire/$populateto create a QuestionnaireResponse. - send-form — Generates a shared link and sends the email. If
send-atis provided, the email is scheduled for later. - check-completed — Periodically checks if the patient completed the form. If a follow-up is configured and the form is not yet completed, proceeds to
send-reminder. If the deadline expires, proceeds tonotify-failure. - send-reminder — Sends a follow-up reminder email and returns to
check-completed. - notify-success — Notifies the clinician (if
clinician-emailis provided) that the form was completed. - notify-failure — Notifies the clinician (if
clinician-emailis provided) that the form expired without completion.
Output
Success Response — HTTP 202 Accepted
resourceType: OperationOutcome
text:
status: generated
div: "Workflow accepted"
issue:
- severity: information
code: informational
diagnostics: "Workflow accepted"
Validation Error — HTTP 422
resourceType: OperationOutcome
text:
status: generated
div: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
issue:
- severity: fatal
code: invalid
diagnostics: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
Usage Example
POST [base]/fhir/Questionnaire/$send
content-type: text/yaml
resourceType: Parameters
parameter:
- name: provider
valueString: sendgrid-provider
- name: questionnaire
valueReference:
reference: Questionnaire/intake-form
- name: email
valueString: patient@example.com
- name: subject
valueReference:
reference: Patient/pt-1
- name: email-subject
valueString: "Please complete the intake form"
- name: email-message
valueString: "Hi {{patient.firstName}}, please fill out your intake form before the visit."
- name: clinician-email
valueString: doctor@clinic.com
- name: config
part:
- name: deadline-days
valueInteger: 14
- name: follow-up-enabled
valueBoolean: true
- name: follow-up-delay-days
valueInteger: 3
- name: follow-up-time
valueString: "09:00"
HTTP status: 202
resourceType: OperationOutcome
text:
status: generated
div: "Workflow accepted"
issue:
- severity: information
code: informational
diagnostics: "Workflow accepted"
HTTP status: 422
resourceType: OperationOutcome
text:
status: generated
div: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
issue:
- severity: fatal
code: invalid
diagnostics: "'provider' is required and should be one of: smtp-provider, postmark-provider, mailgun-provider, sendgrid-provider"
Stop Notification - $stop-notification
This operation cancels all in-progress notifications associated with a given QuestionnaireResponse. It stops pending email sends, follow-up reminders, and completion checks.
URLs
POST [base]/fhir/QuestionnaireResponse/{id}/$stop-notification
Parameters
This operation takes no body parameters. The QuestionnaireResponse ID is provided in the URL path.
Output
Success Response — HTTP 200
Returns the number of cancelled notifications.
resourceType: OperationOutcome
text:
status: generated
div: "Cancelled 1 notification workflow(s)"
issue:
- severity: information
code: informational
diagnostics: "Cancelled 1 notification workflow(s)"
If no in-progress notifications are found for the given QuestionnaireResponse, the operation still returns 200 with a count of 0.
Usage Example
POST [base]/fhir/QuestionnaireResponse/qr-123/$stop-notification
HTTP status: 200
resourceType: OperationOutcome
text:
status: generated
div: "Cancelled 1 notification workflow(s)"
issue:
- severity: information
code: informational
diagnostics: "Cancelled 1 notification workflow(s)"