Session Management API

The Session Management API allows Capture API customers to programmatically create and manage user sessions with fine-grained access control through scopes.


Overview

The Session Management API is designed for EHR and LIS systems that integrate with Tiro.health using the Capture API. It enables you to:

  • Create sessions programmatically with specific scopes and FHIR context
  • Control access to resources throughout the session lifetime using scope-based permissions
  • Handover sessions to end-users in a browser environment
  • Terminate sessions when the user logs out or the session expires

This API is particularly useful when you need to:

  • Launch Tiro.health forms with pre-configured patient and encounter context
  • Restrict what data users can access during a session
  • Integrate Tiro.health into your application's authentication flow
  • Provide seamless user experience with session continuity

Authentication Required: All Session Management API endpoints require OAuth2 authentication using client credentials. See the Authentication guide for details on obtaining and using access tokens.


Session Lifecycle

A typical session follows this lifecycle:

  1. Session Creation: Your backend calls POST /session, optionally including scopes and FHIR context (Patient, Encounter)
  2. Browser Handover: The end-user's browser submits the session token to POST /session/$handover via form POST. The session will be activated, a secure cookie is set, and the user is redirected to Tiro.health
  3. Active Session: The user operates within Tiro.health with access controlled by the session's scopes
  4. Session Termination: The session is deleted via DELETE /session (equivalent to logout) or expires automatically
Mermaid diagram
POST/session

Create a Session

Creates a new authenticated session for an end-user. This endpoint can optionally include FHIR context and scope restrictions.

Request Body

  • Name
    scope
    Type
    string
    Description

    Space-separated list of requested scopes (e.g., "patient/Patient.read patient/Observation.write"). These scopes control what data the user can access during the session.

  • Name
    patient
    Type
    integer
    Description

    FHIR server ID of the patient to associate with this session.

  • Name
    encounter
    Type
    integer
    Description

    FHIR server ID of the encounter to associate with this session.

  • Name
    fhirContext
    Type
    array
    Description

    Array of FHIR context items using external identifiers to specify Patient and Encounter resources. Use this when integrating with systems that use different identifier namespaces. Each item should include role: "launch" to indicate the primary launch context. See FHIR Context for details.

  • Name
    deployment_mode
    Type
    string
    Description

    Either "embedded" or "standalone". Defaults to "embedded".

  • Name
    smart_web_messaging_handle
    Type
    string
    Description

    Optional handle for SMART Web Messaging correlation.

  • Name
    smart_web_messaging_origin
    Type
    string
    Description

    Optional origin for SMART Web Messaging target.

Create Session Request

curl -X POST https://reports.tiro.health/session \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "patient/Patient.read patient/Observation.write",
    "patient": 123,
    "deployment_mode": "embedded"
  }'

POST/session/$handover

Session Handover

The handover endpoint completes the session activation flow by consuming a one-time session token and setting the authentication cookie in the end-user's browser. This is typically called automatically when the user is redirected from your system to Tiro.health.

Form Parameters

  • Name
    token
    Type
    string
    Description

    The session token received from the session creation step. This token is single-use and expires after 5 minutes.

  • Name
    next
    Type
    string
    Description

    The URL to redirect the user to after successful session activation (typically the Tiro.health application URL).

Session Handover

<form action="https://reports.tiro.health/session/$handover"
      method="POST">
  <input type="hidden" name="token" value="<session_token>" />
  <input type="hidden" name="next"
         value="https://app.tiro.health/reports/edit?response=QuestionnaireResponse/example" />
  <button type="submit">Continue to Tiro.health</button>
</form>

Response (303 See Other)

// Redirects to the 'next' URL with session cookie set
Location: https://app.tiro.health/reports/edit?response=QuestionnaireResponse/example
Set-Cookie: auth_session=<session_id>; HttpOnly; Secure; SameSite=Strict

GET/session

Get Session Information

Retrieves information about the current authenticated session. This endpoint requires a valid session cookie.

Response Fields

  • Name
    id
    Type
    integer
    Description

    Unique identifier for the session.

  • Name
    user
    Type
    object
    Description

    User information including practitioner details.

  • Name
    data_tenant
    Type
    object
    Description

    Data tenant associated with this session.

  • Name
    active
    Type
    boolean
    Description

    Whether the session is currently active.

  • Name
    expired_timestamp
    Type
    datetime
    Description

    When the session expires.

  • Name
    created_timestamp
    Type
    datetime
    Description

    When the session was created.

  • Name
    last_modified_timestamp
    Type
    datetime
    Description

    When the session was last modified.

  • Name
    deployment_mode
    Type
    string
    Description

    Either "embedded" or "standalone".

  • Name
    fhir_server
    Type
    object
    Description

    FHIR server address and granted scopes for this session.

Get Session Request

curl https://reports.tiro.health/session \
  -H "Cookie: auth_session=<session_id>"

Response (200 OK)

{
  "id": 12345,
  "user": {
    "id": 67890,
    "email": "doctor@hospital.org",
    "name": "Dr. Smith"
  },
  "data_tenant": {
    "id": 1,
    "name": "Hospital Name"
  },
  "active": true,
  "expired_timestamp": "2025-11-20T18:00:00Z",
  "created_timestamp": "2025-11-20T10:00:00Z",
  "last_modified_timestamp": "2025-11-20T10:00:00Z",
  "deployment_mode": "embedded",
  "fhir_server": {
    "address": "https://fhir.hospital.org/R4",
    "scope": ["patient/Patient.read", "patient/Observation.write"]
  }
}

DELETE/session

Delete a Session

Terminates the current session, marking it as inactive and removing the authentication cookie. This is equivalent to logging the user out.

After deletion, the session can no longer be used and any subsequent requests with the session cookie will be rejected.

Delete Session Request

curl -X DELETE https://reports.tiro.health/session \
  -H "Cookie: auth_session=<session_id>"

Response (204 No Content)

// Empty response body

Scope-based Access Control

Scopes define what actions and resources a user can access during their session. When you create a session with specific scopes, those restrictions are enforced throughout the entire session lifetime.

Scope Format

Scopes follow the FHIR SMART on FHIR format: <context>/<resourceType>.<action>

Supported formats:

  • patient/<resourceType>.<action> - Patient-scoped access to specific resource types
  • system/<resourceType>.<action> - System-wide access to specific resource types

Examples:

  • patient/Patient.read - Read access to patient resources in the patient's compartment
  • patient/Observation.write - Write access to observations in the patient's compartment
  • patient/Encounter.read - Read access to encounters in the patient's compartment
  • system/Patient.read - System-wide read access to all patient resources
  • patient/Patient.read patient/Observation.write - Multiple scopes can be combined

How Scopes Work

When a session is created with scopes:

  1. The scopes are stored with the session
  2. All FHIR API requests during the session are checked against these scopes
  3. Requests for resources or actions not covered by the scopes are denied
  4. Scopes remain active until the session is deleted or expires

Example: Restricted Session

# Create a read-only session for patient data
curl -X POST https://reports.tiro.health/session \
  -H "Content-Type: application/json" \
  -d '{
    "scope": "patient/Patient.read patient/Encounter.read patient/Observation.read",
    "patient": 123
  }'

In this session, the user can read patient, encounter, and observation data but cannot modify anything. Any attempt to create or update resources will be denied.


FHIR Context

Sessions can include FHIR context to associate them with specific patients and encounters. There are two ways to specify context:

Using Direct IDs

When you have the internal FHIR server IDs, use the direct patient and encounter parameters:

{
  "patient": 123,
  "encounter": 456
}

This is the simplest approach when your system already uses Tiro.health's FHIR server IDs.

Using External Identifiers with fhirContext

When integrating with external systems that use their own identifier namespaces, use the fhirContext array following the SMART on FHIR launch context specification:

{
  "fhirContext": [
    {
      "identifier": {
        "system": "http://hospital.org/patient-ids",
        "value": "P-12345"
      },
      "type": "Patient",
      "role": "launch"
    },
    {
      "identifier": {
        "system": "http://hospital.org/encounter-ids",
        "value": "E-67890"
      },
      "type": "Encounter",
      "role": "launch"
    }
  ]
}

Key features:

  • identifier: Specifies the external system identifier (system + value)
  • type: Resource type (Patient or Encounter)
  • role: "launch": Indicates this is the primary launch context for the session

Identifier Resolution

When using external identifiers, Tiro.health will:

  1. Look up existing resources with matching identifiers
  2. Create new resources if no match is found
  3. Associate the session with the resolved or created resources

This enables seamless cross-system integration without requiring ID mapping or pre-registration of resources.


Security Considerations

Token Expiration

  • Session tokens expire after 5 minutes and are single-use only
  • Active sessions have configurable expiration times
  • Expired tokens cannot be used for handover and will return a 401 error

Token Security

  • Session tokens should be treated as sensitive credentials
  • Tokens are deleted immediately after successful handover (one-time use)
  • Always use HTTPS when transmitting tokens
  • Never log or store session tokens

Cookie Security

Session cookies are configured with security best practices:

  • HttpOnly - Cannot be accessed via JavaScript
  • Secure - Only transmitted over HTTPS
  • SameSite=Strict - Protection against CSRF attacks
  • Scoped to tiro.health domain

Best Practices

  1. Minimize scope - Only grant the minimum permissions needed
  2. Short-lived tokens - Use the default 5-minute token expiration
  3. Secure token transmission - Pass tokens via secure form POST, not URL parameters
  4. Immediate handover - Complete the handover flow as quickly as possible
  5. Explicit logout - Always delete sessions when users log out
  6. Monitor sessions - Track active sessions and their expiration times

Was this page helpful?