SMARTWebEHR 1.6.1
dotnet add package SMARTWebEHR --version 1.6.1
NuGet\Install-Package SMARTWebEHR -Version 1.6.1
<PackageReference Include="SMARTWebEHR" Version="1.6.1" />
<PackageVersion Include="SMARTWebEHR" Version="1.6.1" />
<PackageReference Include="SMARTWebEHR" />
paket add SMARTWebEHR --version 1.6.1
#r "nuget: SMARTWebEHR, 1.6.1"
#:package SMARTWebEHR@1.6.1
#addin nuget:?package=SMARTWebEHR&version=1.6.1
#tool nuget:?package=SMARTWebEHR&version=1.6.1
SMARTWebEHR
SMARTWebEHR is a .NETStandard 2.0 library that handles SMART WEB messaging as an Electronic Health Record (EHR). See https://build.fhir.org/ig/HL7/smart-web-messaging/smart-web-messaging.html
This library also supports SDC (Structured Data Capture) SMART Web Messaging protocol. See https://github.com/brianpos/sdc-smart-web-messaging/blob/main/docs/sdc-swm-protocol.md
Features
- Handles SMART WEB messaging
- Supports SDC (Structured Data Capture) SMART Web Messaging protocol
- Compatible with .NETStandard 2.0
Messages from app to EHR
Currently the following messages are supported:
status.handshakescratchpad.createscratchpad.updatescratchpad.readscratchpad.writeform.submittedui.done
Messages from EHR to app
ui.form.requestSubmitui.form.persistsdc.configuresdc.configureContextsdc.displayQuestionnaire
Installation
To install SMARTWebEHR, you can use the NuGet Package Manager:
dotnet add package SMARTWebEHR
Usage
Here is a simple example of how to use the SMARTWebEHR library:
SmartMessageHandler messageHandler = new SmartMessageHandler();
// subscribe to resource changed event
EventHandler<ResourceChangedEventArgs> eventHandler = (sender, e) =>
{
// Handle the resource change event
Console.WriteLine("Resource changed:");
Console.WriteLine(e.Resource.ToString());
if (e.Resource.TypeName == "QuestionnaireResponse")
{
QuestionnaireResponse QR = e.Resource as QuestionnaireResponse;
// Do something with the QuestionnaireResponse
}
};
messageHandler.ResourceChanged += eventHandler;
// Create scratchpad.create message to create a QuestionnaireResponse in the scratchpad
string jsonString = """
{
"messageId": "123",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "scratchpad.create",
"payload": {
"resource": {
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://hl7.org/fhir/Questionnaire/gcs",
"status": "in-progress",
"subject": {"reference": "Patient/123"},
"encounter": {"reference": "Encounter/123"}
}
}
}
""";
// Handle the message
var result = messageHandler.HandleMessage(jsonString);
Example Messages
status.handshake
Request
{
"messageId": "1234",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "status.handshake",
"payload": { }
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "1234",
"additionalResponsesExpected": false,
"payload": {
"$type": "base",
}
}
scratchpad.create
Request
{
"messageId": "123",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "scratchpad.create",
"payload": {
"resource": {
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://hl7.org/fhir/Questionnaire/gcs",
"status": "in-progress",
"subject": {"reference": "Patient/123"},
"encounter": {"reference": "Encounter/123"}
}
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "123",
"additionalResponsesExpected": false,
"payload": {
"$type": "scratchpadCreate",
"status": "201 Created",
"location": "QuestionnaireResponse/2034822185"
}
}
scratchpad.update
Request
{
"messageId": "1234",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "scratchpad.update",
"payload": {
"resource": {
"id": "1593463928",
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://hl7.org/fhir/Questionnaire/gcs",
"status": "completed",
"subject": {"reference": "Patient/123"},
"encounter": {"reference": "Encounter/123"}
}
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "1234",
"additionalResponsesExpected": false,
"payload": {
"$type": "scratchpadUpdate",
"status": "200 OK",
}
}
scratchpad.read
Request
{
"messageId": "1234",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "scratchpad.read",
"payload": {}
}
Response (success)
{
"messageId":"3c3febbe-08e6-41b6-9f80-d89c3cee52bd",
"responseToMessageId":"1234",
"additionalResponsesExpected":false,
"payload":{
"$type":"scratchpadRead",
"scratchpad":[
{
"resourceType":"QuestionnaireResponse",
"id":"1593463928",
"questionnaire":"http://hl7.org/fhir/Questionnaire/gcs",
"status":"completed",
"subject":{
"reference":"Patient/123"
},
"encounter":{
"reference":"Encounter/123"
}
}
]
}
}
Request
{
"messageId": "1234",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiudCo",
"messageType": "scratchpad.read",
"payload": {
"location": "QuestionnaireResponse/1593463928"
}
}
Response (success)
{
"messageId":"3c3febbe-08e6-41b6-9f80-d89c3cee52bd",
"responseToMessageId":"1234",
"additionalResponsesExpected":false,
"payload":{
"$type":"scratchpadRead",
"resource": {
"resourceType":"QuestionnaireResponse",
"id":"1593463928",
"questionnaire":"http://hl7.org/fhir/Questionnaire/gcs",
"status":"completed",
"subject":{
"reference":"Patient/123"
},
"encounter":{
"reference":"Encounter/123"
}
}
}
}
scratchpad.delete
Request
{
"messageId": "1234",
"messagingHandle": "bws8YCbyBtCYi5mWVgUDRqX8xcjiud4o",
"messageType": "scratchpad.delete",
"payload": {
"location": "QuestionnaireResponse/1593463928"
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c2754e",
"responseToMessageId": "1234",
"additionalResponsesExpected": false,
"payload": {
"$type": "scratchpadDelete",
"status": "200 OK",
}
}
sdc.configure
Request
{
"messageId": "sdc-configure-123",
"messagingHandle": "smart-web-messaging",
"messageType": "sdc.configure",
"payload": {
"terminologyServer": "https://terminology.example.com",
"dataServer": "https://fhir.example.com",
"configuration": {
"enableValidation": true,
"theme": "dark"
}
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "sdc-configure-123",
"additionalResponsesExpected": false,
"payload": {
"$type": "base"
}
}
sdc.configureContext
Request
{
"messageId": "sdc-configure-context-123",
"messagingHandle": "smart-web-messaging",
"messageType": "sdc.configureContext",
"payload": {
"launchContext": [
{
"name": "patient",
"contentResource": {
"resourceType": "Patient",
"id": "P100",
"gender": "male"
}
},
{
"name": "user",
"contentResource": {
"resourceType": "Practitioner",
"id": "PR789"
}
},
{
"name": "encounter",
"contentResource": {
"resourceType": "Encounter",
"id": "E200",
"status": "cancelled"
}
}
]
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "sdc-configure-context-123",
"additionalResponsesExpected": false,
"payload": {
"$type": "base"
}
}
sdc.displayQuestionnaire
Request with Questionnaire resource
{
"messageId": "sdc-display-questionnaire-123",
"messagingHandle": "smart-web-messaging",
"messageType": "sdc.displayQuestionnaire",
"payload": {
"questionnaire": {
"resourceType": "Questionnaire",
"id": "patient-intake",
"url": "http://example.com/questionnaire/patient-intake",
"version": "1.0",
"status": "active",
"title": "Patient Intake Form",
"item": [{
"linkId": "patient-name",
"text": "Patient Name",
"type": "string",
"required": true
}]
},
"questionnaireResponse": {
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://example.com/questionnaire/patient-intake",
"status": "in-progress",
"subject": {"reference": "Patient/123"}
},
"context": {
"subject": {"reference": "Patient/123"},
"author": {"reference": "Practitioner/456"},
"encounter": {"reference": "Encounter/789"},
"launchContext": [
{
"name": "patient",
"contentResource": {
"resourceType": "Patient",
"id": "123",
"name": [{"given": ["John"], "family": "Doe"}]
}
}
]
}
}
}
Request with canonical URL
{
"messageId": "sdc-display-questionnaire-456",
"messagingHandle": "smart-web-messaging",
"messageType": "sdc.displayQuestionnaire",
"payload": {
"questionnaire": "http://example.com/questionnaire/patient-intake",
"questionnaireResponse": {
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://example.com/questionnaire/patient-intake",
"status": "in-progress",
"subject": {"reference": "Patient/123"}
},
"context": {
"subject": {"reference": "Patient/123"},
"author": {"reference": "Practitioner/456"},
"encounter": {"reference": "Encounter/789"}
}
}
}
Request with ResourceReference
{
"messageId": "sdc-display-questionnaire-789",
"messagingHandle": "smart-web-messaging",
"messageType": "sdc.displayQuestionnaire",
"payload": {
"questionnaire": {"reference": "Questionnaire/patient-intake"},
"questionnaireResponse": {
"resourceType": "QuestionnaireResponse",
"questionnaire": "http://example.com/questionnaire/patient-intake",
"status": "in-progress",
"subject": {"reference": "Patient/123"}
},
"context": {
"subject": {"reference": "Patient/123"},
"author": {"reference": "Practitioner/456"},
"encounter": {"reference": "Encounter/789"}
}
}
}
Response (success)
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c275be",
"responseToMessageId": "sdc-display-questionnaire-123",
"additionalResponsesExpected": false,
"payload": {
"$type": "base"
}
}
Errors
The error responses are not part of the specifications so might change in the future.
JsonException response
{
"messageId":"c305686f-54eb-416e-8f8c-3203416d1e73",
"responseToMessageId":"123",
"additionalResponsesExpected":false,
"payload":{
"$type":"error",
"errorMessage":"',' is an invalid start of a property name. Expected a '\"'. Path: $ | LineNumber: 1 | BytePositionInLine: 23.",
"errorType":"JsonException"
}
}
ValidationException response
{
"messageId": "eb678ea5-79a6-444b-90a7-a1a2a8c2754e",
"responseToMessageId": "1234",
"additionalResponsesExpected": false,
"payload": {
"$type": "error",
"errorMessage": "MessagingHandle is mandatory.",
"errorType":"ValidationException"
}
}
UnknownMessageTypeException response
{
"messageId":"24ff4fab-145d-418f-b131-e67ca4373aab",
"responseToMessageId":"123",
"additionalResponsesExpected":false,
"payload":{
"$type":"error",
"errorMessage":"Unknown messageType: ??",
"errorType":"UnknownMessageTypeException"
}
}
Authors
- Thibault Mahieu - thibault.mahieu@tiro.health
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- Hl7.Fhir.R5 (>= 5.11.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.7)
- System.Memory (>= 4.5.5)
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
- System.Text.Json (>= 9.0.2)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.0
- Hl7.Fhir.R5 (>= 5.11.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.7)
- System.Memory (>= 4.5.5)
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
- System.Text.Json (>= 9.0.2)
- System.Threading.Tasks.Extensions (>= 4.5.4)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on SMARTWebEHR:
| Package | Downloads |
|---|---|
|
Tiro.Health.Winforms.FormViewer.Net48
WinForms FHIR Form Viewer |
|
|
Tiro.Health.FormViewer.WinForms
A powerful WinForms UserControl for displaying and interacting with FHIR Questionnaires using SMART on FHIR protocols. Built with WebView2 and SMARTWebEHR integration. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.6.1 | 140 | 1/15/2026 |
| 1.6.0 | 503 | 12/17/2025 |
| 1.5.6 | 633 | 12/9/2025 |
| 1.5.5 | 253 | 12/4/2025 |
| 1.5.4 | 715 | 12/3/2025 |
| 1.5.3 | 700 | 12/2/2025 |
| 1.5.2 | 708 | 12/2/2025 |
| 1.5.1 | 703 | 12/2/2025 |
| 1.5.0 | 224 | 11/27/2025 |
| 1.4.2 | 245 | 9/1/2025 |
| 1.4.0 | 210 | 9/1/2025 |
| 1.3.2 | 180 | 7/29/2025 |
| 1.3.1 | 171 | 7/29/2025 |
| 1.3.0 | 215 | 7/15/2025 |
| 1.2.0 | 231 | 5/8/2025 |
| 1.1.0 | 189 | 2/20/2025 |
| 1.0.0 | 190 | 2/18/2025 |