Episodes

Managing Clinical Episodes

This guide covers how to work with episodes — the clinical workflow containers that form Jump EHR's inbox system. Episodes track patient workflows from initial trigger through to resolution.

Overview

Episodes in Jump EHR represent items in the practice inbox. Each episode groups related clinical activity for a patient:

  • Appointment follow-ups
  • Lab result reviews
  • Questionnaire submissions
  • Manual clinical tasks

Every status change, note, and action is recorded as an episode event, creating an immutable timeline.

Required API Scopes

ScopePurpose
read_episodesView episodes and events
write_episodesCreate episodes, add events, close/reopen/assign

Creating an Episode

Create a manual episode for a patient when you need to track a workflow that wasn't automatically triggered:

const API_BASE = 'https://app.usejump.co.uk/functions/v1/api-v1';
 
async function createEpisode(patientId, title, priority = 'medium') {
  const response = await fetch(`${API_BASE}/episodes`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID()
    },
    body: JSON.stringify({
      patient_id: patientId,
      title: title,
      priority: priority,
      source_type: 'manual',
      journey_type: 'general'
    })
  });
 
  const { data } = await response.json();
  return data;
}

Querying the Inbox

List open episodes assigned to a specific user, sorted by most recently active:

async function getInbox(assignedTo, filters = {}) {
  const params = new URLSearchParams({
    status_in: 'open,pending_patient,awaiting_review',
    assigned_to: assignedTo,
    limit: '20'
  });
 
  if (filters.priority) params.set('priority_in', filters.priority);
  if (filters.journeyType) params.set('journey_type', filters.journeyType);
 
  const response = await fetch(`${API_BASE}/episodes?${params}`, {
    headers: { 'Authorization': `Bearer ${API_KEY}` }
  });
 
  const { data, meta } = await response.json();
  return { episodes: data, hasMore: meta.has_more, nextOffset: meta.next_offset };
}

Adding Events to an Episode

Events form the timeline within an episode. Add clinical notes, record actions, or log system events:

async function addNote(episodeId, note, createdBy) {
  const response = await fetch(`${API_BASE}/episodes/${episodeId}/events`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID()
    },
    body: JSON.stringify({
      event_type: 'note',
      title: 'Clinical note',
      description: note,
      created_by: createdBy,
      created_by_type: 'user'
    })
  });
 
  const { data } = await response.json();
  return data;
}

Episode events are append-only. They cannot be edited or deleted. To correct an event, create a new event referencing the original.


Episode Lifecycle Actions

Close an Episode

async function closeEpisode(episodeId, reason = 'resolved', note = null) {
  const response = await fetch(`${API_BASE}/episodes/${episodeId}/close`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ reason, note })
  });
 
  const { data, meta } = await response.json();
  // meta.action === 'closed', meta.performed_at, meta.performed_by
  return data;
}

Close reasons: resolved, duplicate, patient_declined, admin_closed

Assign an Episode

async function assignEpisode(episodeId, userId) {
  const response = await fetch(`${API_BASE}/episodes/${episodeId}/assign`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      assigned_to: userId,
      responsibility: 'practice'
    })
  });
 
  return (await response.json()).data;
}

Escalate Priority

async function escalate(episodeId, reason) {
  await fetch(`${API_BASE}/episodes/${episodeId}/change-priority`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ priority: 'urgent', reason })
  });
}

Building an Episode Timeline View

Fetch the full event timeline for an episode:

async function getTimeline(episodeId) {
  const response = await fetch(
    `${API_BASE}/episodes/${episodeId}/events?limit=100`,
    { headers: { 'Authorization': `Bearer ${API_KEY}` } }
  );
 
  const { data } = await response.json();
  return data; // Sorted by created_at descending
}

Event types you'll commonly see: note, status_change, assignment, priority_change, questionnaire_response, communication, lab_result, appointment.


Next Steps