> ## Documentation Index
> Fetch the complete documentation index at: https://docs.medisync.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Recordings by Appointment

> Retrieve the recording(s) stored for a specific appointment.

## Overview

Returns the recording(s) stored for a specific appointment. Recordings are looked up by `appointment_id`, so the path value is an appointment ObjectId, not a recording id. The caller must be the appointment's owning doctor.

Because only one recording may exist per appointment, the returned `data` array contains zero or one recording in practice.

<Info>
  The path value is an **appointment** ObjectId. The endpoint returns the recordings whose `appointment_id` matches it.
</Info>

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer JWT token. The calling user is derived from the token.

  ```
  Authorization: Bearer <JWT>
  ```
</ParamField>

## Path Parameters

<ParamField path="appointmentId" type="string" required>
  The appointment ObjectId. Recordings are looked up by `appointment_id`; the caller must be the appointment's owning doctor.

  ```
  665f8a1b2c3d4e5f6789012f3
  ```
</ParamField>

## Response

<ResponseField name="success" type="boolean" required>
  Indicates whether the request succeeded.
</ResponseField>

<ResponseField name="data" type="array">
  Array of recording objects for the appointment (0 or 1 element in practice).

  <Expandable title="Recording Object">
    <ResponseField name="_id" type="string">
      Unique recording identifier.
    </ResponseField>

    <ResponseField name="appointment_id" type="string">
      The associated appointment ObjectId.
    </ResponseField>

    <ResponseField name="recording_url" type="string">
      URL of the stored recording file.
    </ResponseField>

    <ResponseField name="recording_key" type="string">
      Storage key of the recording file.
    </ResponseField>

    <ResponseField name="append_recordings" type="array">
      Additional recording segments attached to this recording.
    </ResponseField>

    <ResponseField name="duration_seconds" type="number">
      Recording duration in seconds. May be `null`.
    </ResponseField>

    <ResponseField name="file_size_bytes" type="number">
      File size in bytes. May be `null`.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      Creation timestamp (ISO 8601).
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      Last-update timestamp (ISO 8601).
    </ResponseField>
  </Expandable>
</ResponseField>

<Info>
  Additional fields (for example `merged_recording`, `replaced_recording`, `__v`) may appear on the recording object. Treat any field not documented here as opaque.
</Info>

## Example Request

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET \
    'https://app.medisync.me/api/recordings/665f8a1b2c3d4e5f6789012f3' \
    -H 'Authorization: Bearer <JWT>'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://app.medisync.me/api/recordings/665f8a1b2c3d4e5f6789012f3',
    {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer <JWT>'
      }
    }
  );

  const result = await response.json();
  ```

  ```python Python theme={null}
  import requests

  headers = {'Authorization': 'Bearer <JWT>'}

  response = requests.get(
      'https://app.medisync.me/api/recordings/665f8a1b2c3d4e5f6789012f3',
      headers=headers
  )

  result = response.json()
  ```
</CodeGroup>

## Example Response

```json Success (200) - Recording Present theme={null}
{
  "success": true,
  "data": [
    {
      "_id": "665f8a1b2c3d4e5f6789012f4",
      "appointment_id": "665f8a1b2c3d4e5f6789012f3",
      "recording_url": "https://storage.medisync.me/recordings/665f8a1b2c3d4e5f6789012f3_recording.wav",
      "recording_key": "665f8a1b2c3d4e5f6789012f3_recording.wav",
      "append_recordings": [],
      "duration_seconds": null,
      "file_size_bytes": 4831200,
      "createdAt": "2026-06-30T10:30:00.000Z",
      "updatedAt": "2026-06-30T10:30:00.000Z"
    }
  ]
}
```

```json Success (200) - No Recording On File theme={null}
{
  "success": true,
  "data": []
}
```

## Error Responses

```json 401 Unauthorized theme={null}
{
  "success": false,
  "message": "Unauthorized"
}
```

```json 403 Forbidden (not the owning doctor) theme={null}
{
  "success": false,
  "error": "Forbidden"
}
```

```json 404 Appointment Not Found theme={null}
{
  "success": false,
  "error": "Appointment not found"
}
```

<Note>
  The `Unauthorized` response uses the `message` field, whereas handler-level errors use the `error` field. Unexpected server errors return `400 { "success": false, "error": "<message>" }`.
</Note>

## Behavior Notes

* **Lookup by appointment**: Recordings are located by `appointment_id`; the path value is an appointment id.
* **Empty array only for existing appointments**: If the appointment exists but has no recording, `data` is `[]`. If the appointment does not exist, the endpoint returns `404 Appointment not found` (not an empty array).
* **Ownership**: Only the appointment's owning doctor may read its recordings; otherwise the request returns `403 Forbidden`.
* **At most one recording**: Because uploads are limited to one recording per appointment, `data` holds 0 or 1 element.
