Skip to content

Launch PopApp

Open the PopApp with patient context.

Integration Flow

  1. User opens a patient in your system
  2. If patient doesn't exist in Unomed yet, your backend creates the patient via API (see Send Patient Data)
  3. Your frontend loads the PopApp iframe with our Patient UUID as parameter and the requested module
  4. Iframe sends UNOMED_READY, your frontend responds with UNOMED_AUTH containing the OAuth2 token
  5. User sees PopApp with the patient pre-selected, already authenticated

Authentication

  • Backend (API calls): Your backend uses OAuth2 to get tokens and sync data (see Authentication)
  • Frontend (iframe): Your frontend passes the OAuth2 token to the iframe via postMessage (see PostMessage Authentication below)

URL Format

The app uses hash-based routing. The URL format is:

With patient context:

https://app.dev.unomed.ch/#/radiology/{ORGANIZATION_UUID}?patientId={PATIENT_UUID}

Without patient (organization only):

https://app.dev.unomed.ch/#/radiology/{ORGANIZATION_UUID}

Embed as iframe

The PopApp must be integrated as an iframe in your application.

<iframe
  id="unomed-popapp"
  src="https://app.dev.unomed.ch/#/radiology/ORG_UUID?patientId=PATIENT_UUID"
  width="100%"
  height="800"
  frameborder="0"
  allow="camera; microphone"
></iframe>

Dynamic Loading

function loadPopApp(organizationId, patientId) {
  const baseUrl = 'https://app.dev.unomed.ch/';
  let url;

  if (patientId) {
    url = `${baseUrl}#/radiology/${organizationId}?patientId=${patientId}`;
  } else {
    url = `${baseUrl}#/radiology/${organizationId}`;
  }

  document.getElementById('unomed-popapp').src = url;
}

// Usage
loadPopApp('org-uuid-here', 'patient-uuid-here');

Handling Close Events

The PopApp provides a close button that users can click to indicate they want to close the iframe. When clicked, the PopApp sends a postMessage event to the parent window.

Listening for Close Events

window.addEventListener('message', (event) => {
  // Verify origin for security
  if (event.origin !== 'https://app.dev.unomed.ch') return;

  if (event.data?.type === 'close-popapp') {
    // User clicked close button - hide or remove the iframe
    document.getElementById('unomed-popapp').style.display = 'none';
    // Or remove from DOM, close modal, etc.
  }
});

Message Format

Property Value Description
type 'close-popapp' Event identifier

Note: The iframe cannot close itself due to browser security restrictions. Your application must handle this event and close/hide the iframe accordingly.

PostMessage Authentication

After your backend obtains an OAuth2 token (see Authentication), your frontend passes it to the iframe via postMessage. This enables seamless single sign-on - users don't need to log in again.

Protocol Flow

Step Direction Message Description
1 iframe → PIS UNOMED_READY Iframe ready for auth
2 PIS → iframe UNOMED_AUTH Send OAuth2 token
3 iframe → PIS UNOMED_AUTH_ACK Success
3 iframe → PIS UNOMED_AUTH_ERROR Failure

Note: UNOMED_READY is always sent when the iframe loads - even if a user session is cached in localStorage. This allows your PIS to send fresh tokens at any time. If you don't send a token (no UNOMED_AUTH response), the iframe continues with the cached session.

Message Formats

UNOMED_READY (iframe → PIS):

{ "type": "UNOMED_READY", "version": 1 }

UNOMED_AUTH (PIS → iframe):

{
  "type": "UNOMED_AUTH",
  "version": 1,
  "token": "YOUR_ACCESS_TOKEN",
  "expires_in": 43200
}

Field Required Description
type Yes Must be "UNOMED_AUTH"
version Yes Must be 1
token Yes OAuth2 access token
expires_in No Token expiry in seconds (from OAuth2 token response). Used for local cache. Default: 43200 (12 hours)

Note: Patient context is passed via the URL query parameter (?patientId=...), not in the auth message.

UNOMED_AUTH_ACK (iframe → PIS):

{ "type": "UNOMED_AUTH_ACK", "version": 1 }

UNOMED_AUTH_ERROR (iframe → PIS):

{ "type": "UNOMED_AUTH_ERROR", "version": 1, "error": "TOKEN_INVALID", "message": "..." }

Error Codes

Error Description
TOKEN_INVALID Token rejected by server
TOKEN_EXPIRED Token has expired
TIMEOUT No auth message within 10 seconds
VALIDATION_FAILED Server error during validation

Important: Your origin must be allowlisted by Unomed. If your origin is not allowlisted, UNOMED_AUTH messages are silently ignored and you will receive a TIMEOUT error.

Implementation Example

const iframe = document.getElementById('unomed-popapp');
const UNOMED_ORIGIN = 'https://app.dev.unomed.ch';

window.addEventListener('message', (event) => {
  if (event.origin !== UNOMED_ORIGIN) return;

  if (event.data.type === 'UNOMED_READY') {
    iframe.contentWindow.postMessage({
      type: 'UNOMED_AUTH',
      version: 1,
      token: 'YOUR_OAUTH2_ACCESS_TOKEN',
      expires_in: 43200  // Optional: token expiry in seconds
    }, UNOMED_ORIGIN);
  }

  if (event.data.type === 'UNOMED_AUTH_ACK') {
    console.log('User authenticated');
  }

  if (event.data.type === 'UNOMED_AUTH_ERROR') {
    console.error('Auth failed:', event.data.error);
  }
});

Requirements

  1. Your domain must be allowlisted (contact info@unomed.ch)
  2. Send UNOMED_AUTH within 10 seconds of receiving UNOMED_READY
  3. Token must be a valid OAuth2 access token from Unomed