Luna SaludAPI ReferenceLuna Salud

Reschedule an appointment

POST/appointments/{id}/reschedule

Moves an appointment in your organization to a new start time, assigns it to a different provider, or both. Send startTime, staffId or both. The appointment keeps its ID and its duration. It must be PENDING or CONFIRMED, in person, with one provider, and not started yet. The new slot must be in the future, inside the provider's availability and free; use GET /availability to find open slots. A new provider must offer the appointment's service. Pending reminders move to the new time, the providers are notified, and an appointment.updated webhook is sent. The patient is notified only when notifyPatient is true and the appointment is CONFIRMED, using your clinic's appointment change settings (email, WhatsApp, SMS), and then also gets your clinic's usual reminders for the new time; by default nothing is sent to the patient. Rescheduling to the slot and provider the appointment already has returns it unchanged, so retries are safe. Requires an API key with the write scope.

Code samples

Node.js

const fetch = require('node-fetch');

async function callApi() {
  const apiKey = 'YOUR_API_KEY';
  const url = `https://account.lunahealth.app/api/appointments/{id}/reschedule`;
  const requestBody = {
    // Add your request body data here
  };

  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });
    
    if (!response.ok) {
      throw new Error(`API error: ${response.status}`);
    }
    
    const data = await response.json();
    console.log(data);
    return data;
  } catch (error) {
    console.error('Error calling API:', error);
    throw error;
  }
}

callApi();

Python

import requests

def call_api():
    api_key = 'YOUR_API_KEY'
    
    url = 'https://account.lunahealth.app/api/appointments/{id}/reschedule'
    
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    
    params = {

    }
    
    # Add your request body data here
    request_body = {}
        try:
        response = requests.post(
            url,
            headers=headers,
            params=params,
            json=request_body
        )
        response.raise_for_status()
        
        data = response.json()
        print(data)
        return data
    except requests.exceptions.RequestException as e:
        print(f'Error calling API: {e}')
        raise

call_api()

Parameters

NameInTypeRequiredDescription
idpathstringYesID of the appointment to reschedule

Request body

Required

Request fields

NameTypeRequiredDescription
startTimestring (date-time)NoNew start time in ISO 8601 with a UTC offset, e.g. a start_time from GET /availability. Omit to keep the current time.
staffIdstringNoID of the provider who will see the patient. Omit to keep the current provider.
notifyPatientbooleanNoSend the patient an appointment change message through your clinic's settings. Defaults to false.

Example request

{
  "startTime": "2025-01-01T00:00:00Z",
  "staffId": "string",
  "notifyPatient": true
}

Responses

StatusDescription
200Successful response
400Invalid input data
401Authorization not provided
403Insufficient access
500Internal server error

200 — Successful response

Response fields

NameTypeRequiredDescription
idstringYes—
statusstringYes—
typestringYes—
titlestringnullYes—
descriptionstringnullYes—
start_timestringYes—
end_timestringYes—
telemedicinebooleanYes—
created_atstringYes—
updated_atstringYes—
patientobject | nullYes—
staffsarray<object>Yes—
serviceobject | nullYes—
locationobject | nullYes—

Example response

{
  "id": "string",
  "status": "NEW",
  "type": "APPOINTMENT",
  "title": null,
  "description": null,
  "start_time": "string",
  "end_time": "string",
  "telemedicine": true,
  "created_at": "string",
  "updated_at": "string",
  "patient": {
    "id": "string",
    "first_name": null,
    "last_name": null,
    "email": null
  },
  "staffs": [
    {
      "id": "string",
      "first_name": null,
      "last_name": null
    }
  ],
  "service": {
    "id": "string",
    "name": "string"
  },
  "location": {
    "id": "string",
    "name": null
  }
}

400 — Invalid input data

Response fields

NameTypeRequiredDescription
messagestringYesThe error message
codestringYesThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Example response

{
  "code": "BAD_REQUEST",
  "message": "Invalid input data",
  "issues": []
}

401 — Authorization not provided

Response fields

NameTypeRequiredDescription
messagestringYesThe error message
codestringYesThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Example response

{
  "code": "UNAUTHORIZED",
  "message": "Authorization not provided",
  "issues": []
}

403 — Insufficient access

Response fields

NameTypeRequiredDescription
messagestringYesThe error message
codestringYesThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Example response

{
  "code": "FORBIDDEN",
  "message": "Insufficient access",
  "issues": []
}

500 — Internal server error

Response fields

NameTypeRequiredDescription
messagestringYesThe error message
codestringYesThe error code
issuesarray<object>NoAn array of issues that were responsible for the error

Example response

{
  "code": "INTERNAL_SERVER_ERROR",
  "message": "Internal server error",
  "issues": []
}