Get Embeddable URLs with User Authentication

 

This document describes how to use the x-integration-user header to authenticate users when requesting embeddable URLs from the FHIR API.

Overview

All embeddable endpoints support user authentication through the optional x-integration-user header. When provided, this header contains base64-encoded JSON with user information that creates a secure session for accessing Empego’s embedded functionality. If not provided, the session will use the owner of the API key.

Header Format

Parameter Details

  • Header Name: x-integration-user
  • Type: Base64-encoded JSON string
  • Required: No (optional - falls back to API key owner if not provided)

JSON Schema (when decoded)

{
  "userId": "string",              // Required
  "firstName": "string",           // Optional (cloned from API key owner if not provided)
  "lastName": "string",            // Optional (cloned from API key owner if not provided)
  "email": "string",               // Optional (cloned from API key owner if not provided)
  "licenseNumber": "string",       // Optional (cloned from API key owner if not provided)
  "preferredLanguage": "FR | EN"   // Optional (cloned from API key owner if not provided)
}

Field Descriptions

  • userId: Required - Unique identifier for the user in your system
  • firstName: Optional - User’s first name (inherited from API key owner if not provided)
  • lastName: Optional - User’s last name (inherited from API key owner if not provided)
  • email: Optional - User’s email address (inherited from API key owner if not provided)
  • licenseNumber: Optional - Professional license number (inherited from API key owner if not provided)
  • preferredLanguage: Optional - User’s preferred language (FR for French or EN for English, inherited from API key owner if not provided)

User Authentication Options

Option 1: Use API Key Owner (Default)

If no x-integration-user header is provided, the system will automatically use the owner of the API key for session creation. This is the simplest approach and requires no additional setup.

curl -X GET "https://api.empego.ca/empego-integrations/R4/embeddable/consultation/view?patientKey=patient123&locale=en" \
  -H "Api-key: YOUR_API_KEY"

Option 2: Use Existing User

For users that already exist in the Empego system, provide the x-integration-user header with just the userId:

curl -X GET "https://api.empego.ca/empego-integrations/R4/embeddable/consultation/view?patientKey=patient123&locale=en" \
  -H "Api-key: YOUR_API_KEY" \
  -H "x-integration-user: eyJ1c2VySWQiOiJleGlzdGluZ191c2VyXzEyMyJ9"

Option 3: Create New User or Update Existing User

When you provide user information for a userId that doesn’t exist in the Empego system, a new user will be automatically created. If the user already exists, the system will intelligently update their profile with any new information provided, ensuring user data stays current across integrations.

Requirements for automatic user creation:

  • userId: Unique identifier for the user
  • firstName: Required when creating a new user (if user doesn’t exist)
  • lastName: Required when creating a new user (if user doesn’t exist)
  • email: Required when creating a new user (if user doesn’t exist)
  • licenseNumber: Optional but recommended for healthcare professionals
  • preferredLanguage: Optional (defaults to system default)

User Update Behavior:

  • Smart Updates: Only meaningful data changes trigger database updates (providing only userId won’t update anything)
  • Selective Updates: Only fields with actual changes are updated, preserving unchanged data
curl -X GET "https://api.empego.ca/empego-integrations/R4/embeddable/consultation/view?patientKey=patient123&locale=en" \
  -H "Api-key: YOUR_API_KEY" \
  -H "x-integration-user: eyJ1c2VySWQiOiJuZXdfdXNlcl80NTYiLCJmaXJzdE5hbWUiOiJEci4gQWxpY2UiLCJsYXN0TmFtZSI6IkpvaG5zb24iLCJlbWFpbCI6ImFsaWNlLmpvaG5zb25AY2xpbmljLmNvbSIsImxpY2Vuc2VOdW1iZXIiOiJNRDc4OTEyMyIsInByZWZlcnJlZExhbmd1YWdlIjoiRU4ifQ=="

Important: If you provide incomplete user information for a userId that doesn’t exist, you’ll receive a 400 Bad Request error. If the user already exists, their profile will be updated with any new information provided in the header.

Option 4: Clone from API Key Owner

To create a new user with the same profile information as the API key owner but with a different userId, provide only the userId. The system will clone all other information from the API key owner.

User Update Scenarios

The system handles different user update scenarios:

Scenario 1: ID-Only Request (No Updates)

When you provide only a userId for an existing user, no updates occur:

const user = {
  "userId": "existing_user_123"
};

Result: User profile remains unchanged - optimal performance with no database operations.

Scenario 2: Partial Updates

When you provide a userId with some updated information, only the changed fields are updated:

const user = {
  "userId": "existing_user_123",
  "email": "new.email@clinic.com",  // This will be updated
  "firstName": "John"               // If already "John", no update occurs
};

Result: Only the email field is updated if it differs from the current value.

Scenario 3: Complete Profile Updates

When you provide comprehensive user information, all changed fields are updated:

const user = {
  "userId": "existing_user_123",
  "firstName": "Dr. John",
  "lastName": "Updated",
  "email": "john.updated@newclinic.com",
  "licenseNumber": "MD999888",
  "preferredLanguage": "FR"
};

Result: All fields that differ from current values are updated in a single optimized operation.

Implementation Examples

Existing User (Option 2)

1. Create Minimal User Object

const user = {
  "userId": "existing_user_123"
};

2. Base64 Encode

const userHeader = Buffer.from(JSON.stringify(user)).toString('base64');
// Result: eyJ1c2VySWQiOiJleGlzdGluZ191c2VyXzEyMyJ9

New User Creation (Option 3)

1. Create Complete User Object

const user = {
  "userId": "new_user_456",
  "firstName": "Dr. Alice",
  "lastName": "Johnson", 
  "email": "alice.johnson@clinic.com",
  "licenseNumber": "MD789123",
  "preferredLanguage": "EN"
};

2. Base64 Encode

const userHeader = Buffer.from(JSON.stringify(user)).toString('base64');
// Result: eyJ1c2VySWQiOiJuZXdfdXNlcl80NTYiLCJmaXJzdE5hbWUiOiJEci4gQWxpY2UiLCJsYXN0TmFtZSI6IkpvaG5zb24iLCJlbWFpbCI6ImFsaWNlLmpvaG5zb25AY2xpbmljLmNvbSIsImxpY2Vuc2VOdW1iZXIiOiJNRDc4OTEyMyIsInByZWZlcnJlZExhbmd1YWdlIjoiRU4ifQ==

Clone from API Key Owner (Option 4)

For existing users or when you want to use the API key owner’s information with a different user ID:

1. Create Minimal User Object

const user = {
  "userId": "emp456"
};

2. Base64 Encode

const userHeader = Buffer.from(JSON.stringify(user)).toString('base64');
// Result: eyJ1c2VySWQiOiJlbXA0NTYifQ==

3. Make API Request

curl -X GET "https://api.empego.ca/empego-integrations/R4/embeddable/consultation/view?patientKey=patient123&locale=en" \
  -H "Api-key: YOUR_API_KEY" \
  -H "x-integration-user: eyJ1c2VySWQiOiJlbXA0NTYifQ=="

Note: When only userId is provided, the system will clone the firstName, lastName, email, licenseNumber, and preferredLanguage from the API key owner’s profile.

Supported Endpoints

All embeddable endpoints support the optional x-integration-user header:

Consultation Endpoints

  • GET /embeddable/consultation/view - Start a consultation with a patient
  • GET /embeddable/consultation/dashboard - View consultation dashboard
  • GET /embeddable/consultation/specific - View specific consultation details
  • GET /embeddable/consultation/answer - Patient consultation answer view

Follow-up Endpoints

  • GET /embeddable/followup/view - Create follow-up with patient
  • GET /embeddable/followup/dashboard - View follow-up dashboard
  • GET /embeddable/followup/specific - View specific follow-up details
  • GET /embeddable/followup/plan - Plan follow-up with prefilled data

Administration Endpoints

  • GET /embeddable/administration/franchise-management - Franchise management view
  • GET /embeddable/administration/franchise-onboarding - Franchise onboarding view
  • GET /embeddable/administration/franchise-offboarding - Franchise offboarding view

Statistics Endpoints

  • GET /embeddable/statistics - View statistics dashboard

Authentication Flow

sequenceDiagram
    participant Client as Integration Client
    participant API as FHIR API
    participant Database as User Database
    participant App as Empego App

    Client->>Client: 1. Create user JSON object (optional)
    Client->>Client: 2. Base64 encode user object (optional)
    Client->>API: 3. Request embeddable URL with Api-key header and optional x-integration-user header
    
    alt User exists and has updates
        API->>Database: 4a. Update user profile with changed fields only
        Database-->>API: 4b. Updated user profile
    else User doesn't exist
        API->>Database: 4c. Create new user
        Database-->>API: 4d. New user profile
    else User exists with no changes
        API->>API: 4e. Use existing user (no database operation)
    end
    
    API-->>Client: 5. Return embeddable URL with embedded session
    Client->>App: 6. Load embeddable URL in iframe
    App-->>Client: 7. Display authenticated interface for the specified user

Error Handling

400 Bad Request

  • Invalid JSON format in the user object
  • Invalid base64 encoding
  • User creation failed (missing required fields for new user creation when user doesn’t exist)

401 Unauthorized

  • Invalid API key
  • Session creation failed

Example Error Responses

Invalid header format (400 Bad Request):

{
  "timestamp": "2025-01-15T14:30:00.123Z",
  "status": 400,
  "error": "Bad Request",
  "message": "Invalid x-integration-user header format",
  "path": "/empego-integrations/R4/embeddable/consultation/view"
}

Authentication failed (401 Unauthorized):

{
  "timestamp": "2025-01-15T14:30:00.123Z",
  "status": 401,
  "error": "Unauthorized",
  "message": "Authentication failed",
  "path": "/empego-integrations/R4/embeddable/consultation/view"
}

Missing required fields for user creation (400 Bad Request):

{
  "timestamp": "2025-01-15T14:30:00.123Z",
  "status": 400,
  "error": "Bad Request", 
  "message": "User creation failed - missing required fields",
  "path": "/empego-integrations/R4/embeddable/consultation/view"
}

Example Integration

class EmpegoIntegration {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
  }

  createUserHeader(user) {
    const userJson = JSON.stringify(user);
    return Buffer.from(userJson).toString('base64');
  }

  async getConsultationUrl(patientKey, user, locale = 'en') {
    const userHeader = this.createUserHeader(user);
    
    const response = await fetch(
      `${this.baseUrl}/embeddable/consultation/view?patientKey=${patientKey}&locale=${locale}`,
      {
        headers: {
          'Api-key': 'YOUR_API_KEY',
          'x-integration-user': userHeader
        }
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to get consultation URL: ${response.statusText}`);
    }

    return await response.text();
  }
}

// Usage Examples
const integration = new EmpegoIntegration('https://api.empego.ca/empego-integrations/R4');

// Example 1: Create new user or update existing user
const newOrUpdatedUser = {
  userId: 'emp123',
  firstName: 'Dr. Jane',
  lastName: 'Smith',
  email: 'jane.smith@clinic.com',
  licenseNumber: 'MD123456',
  preferredLanguage: 'EN'
};

const consultationUrl = await integration.getConsultationUrl('patient123', newOrUpdatedUser);

// Example 2: Use existing user without updates (optimal performance)
const existingUser = {
  userId: 'emp123'
};

const dashboardUrl = await integration.getConsultationUrl('patient456', existingUser);

// Example 3: Update only specific fields for existing user
const partialUpdate = {
  userId: 'emp123',
  email: 'jane.newemail@clinic.com',  // Only email will be updated
  preferredLanguage: 'FR'             // Only language will be updated if different
};

const followUpUrl = await integration.getConsultationUrl('patient789', partialUpdate);