API Documentation is in beta. Report issues to developers@jump.health
API Reference
Holds

Holds

The Holds API allows you to temporarily reserve appointment slots before confirming a booking. Holds prevent double-booking while patients complete their information.

Endpoints

MethodEndpointDescription
POST/holdsCreate a hold
GET/holds/{id}Check hold status
DELETE/holds/{id}Release a hold
POST/holds/{id}/confirmConfirm booking

Required scope: write_holds

The Hold Object

{
  "id": "hold_123e4567-e89b-12d3-a456-426614174000",
  "appointment_type_id": "type_456e7890-e89b-12d3-a456-426614174111",
  "clinician_id": "cli_789a0123-e89b-12d3-a456-426614174222",
  "location_id": "loc_012b3456-e89b-12d3-a456-426614174333",
  "start_time": "2025-01-20T09:00:00Z",
  "end_time": "2025-01-20T09:30:00Z",
  "expires_at": "2025-01-15T10:15:00Z",
  "status": "active",
  "created_at": "2025-01-15T10:00:00Z"
}

Attributes

FieldTypeDescription
idstringUnique identifier (UUID)
appointment_type_idstringAppointment type being held
clinician_idstringClinician for the slot
location_idstringLocation (null for remote)
start_timestringSlot start time (ISO 8601)
end_timestringSlot end time (ISO 8601)
expires_atstringWhen hold expires (ISO 8601)
statusstringactive, confirmed, expired, released
created_atstringISO 8601 creation timestamp
⚠️

Holds expire after 15 minutes. Complete the booking before the hold expires, or the slot will become available again.


Create a Hold

POST /holds

Temporarily reserve an appointment slot.

Request Body

FieldTypeRequiredDescription
appointment_type_idstringYesAppointment type ID
clinician_idstringYesClinician ID
datestringYesDate (YYYY-MM-DD)
start_timestringYesTime (HH:MM)
location_idstringNoLocation ID

Request

curl -X POST "https://app.usejump.co.uk/functions/v1/api-v1/holds" \
  -H "Authorization: Bearer pk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "appointment_type_id": "type_456e7890-e89b-12d3-a456-426614174111",
    "clinician_id": "cli_789a0123-e89b-12d3-a456-426614174222",
    "date": "2025-01-20",
    "start_time": "09:00",
    "location_id": "loc_012b3456-e89b-12d3-a456-426614174333"
  }'

Response

{
  "data": {
    "id": "hold_123e4567-e89b-12d3-a456-426614174000",
    "appointment_type_id": "type_456e7890-e89b-12d3-a456-426614174111",
    "clinician_id": "cli_789a0123-e89b-12d3-a456-426614174222",
    "location_id": "loc_012b3456-e89b-12d3-a456-426614174333",
    "start_time": "2025-01-20T09:00:00Z",
    "end_time": "2025-01-20T09:30:00Z",
    "expires_at": "2025-01-15T10:15:00Z",
    "status": "active",
    "created_at": "2025-01-15T10:00:00Z"
  }
}

Errors

StatusDescription
409Slot already taken or held

Check Hold Status

GET /holds/{id}

Check if a hold is still active.

Request

curl -X GET "https://app.usejump.co.uk/functions/v1/api-v1/holds/hold_123e4567" \
  -H "Authorization: Bearer pk_live_your_api_key"

Response

{
  "data": {
    "id": "hold_123e4567-e89b-12d3-a456-426614174000",
    "status": "active",
    "expires_at": "2025-01-15T10:15:00Z"
  }
}

Release a Hold

DELETE /holds/{id}

Release a hold before it expires, making the slot available again.

Request

curl -X DELETE "https://app.usejump.co.uk/functions/v1/api-v1/holds/hold_123e4567" \
  -H "Authorization: Bearer pk_live_your_api_key"

Response

{
  "data": {
    "message": "Hold released"
  }
}

Confirm a Hold

POST /holds/{id}/confirm

Convert a hold into an actual appointment. The hold must still be active.

Request Body

FieldTypeRequiredDescription
patient_idstringYesPatient ID
attendee_namestringNoAttendee's name
attendee_emailstringNoAttendee's email
attendee_phonestringNoAttendee's phone
notesstringNoAppointment notes

Request

curl -X POST "https://app.usejump.co.uk/functions/v1/api-v1/holds/hold_123e4567/confirm" \
  -H "Authorization: Bearer pk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "patient_id": "pat_789a0123-e89b-12d3-a456-426614174444",
    "attendee_name": "Sarah Johnson",
    "attendee_email": "sarah@example.com",
    "attendee_phone": "+44 7700 900123",
    "notes": "First visit"
  }'

Response

Returns the created appointment:

{
  "data": {
    "id": "apt_555e6666-e89b-12d3-a456-426614174555",
    "patient_id": "pat_789a0123-e89b-12d3-a456-426614174444",
    "clinician_profile_id": "cli_789a0123-e89b-12d3-a456-426614174222",
    "appointment_type_id": "type_456e7890-e89b-12d3-a456-426614174111",
    "location_id": "loc_012b3456-e89b-12d3-a456-426614174333",
    "start_time": "2025-01-20T09:00:00Z",
    "end_time": "2025-01-20T09:30:00Z",
    "status": "confirmed",
    "attendee_name": "Sarah Johnson",
    "attendee_email": "sarah@example.com",
    "attendee_phone": "+44 7700 900123",
    "notes": "First visit",
    "created_at": "2025-01-15T10:05:00Z"
  }
}

Errors

StatusDescription
404Hold not found or expired

Complete Booking Flow

// Step 1: Query availability
const slots = await api.get('/availability', {
  params: {
    appointment_type_id: 'type_123',
    start_date: '2025-01-20',
    end_date: '2025-01-27'
  }
});
 
// Step 2: User selects a slot
const selectedSlot = slots.data[0];
 
// Step 3: Create a hold
const hold = await api.post('/holds', {
  appointment_type_id: 'type_123',
  clinician_id: selectedSlot.clinician_id,
  location_id: selectedSlot.location_id,
  date: '2025-01-20',
  start_time: '09:00'
});
 
// Step 4: Display countdown timer
const expiresAt = new Date(hold.data.expires_at);
// Show: "Complete booking within X minutes"
 
// Step 5: Collect patient information
// ... form submission ...
 
// Step 6: Confirm the hold
const appointment = await api.post(`/holds/${hold.data.id}/confirm`, {
  patient_id: 'pat_789',
  attendee_name: 'Sarah Johnson',
  attendee_email: 'sarah@example.com'
});
 
// Success! Appointment is booked
console.log('Appointment confirmed:', appointment.data.id);

Related Resources