> ## 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.

# Create Notes

> Create or update the clinical notes for an appointment

## Overview

Create or update the notes for a specific appointment. A single notes document is stored per appointment: if notes do not yet exist for the appointment they are created, otherwise the existing notes are updated. When the notes are saved successfully the appointment status is automatically set to `finished`.

<Info>
  **Automatic status update**: When notes are saved, the associated appointment status is set to `finished` and a real-time update is emitted to connected clients.
</Info>

<Note>
  This operation is scoped to the owning doctor. The appointment identified by `{id}` must belong to the authenticated user (`appointment.doctor_id`). A request for an appointment you do not own returns `403 Forbidden`, and an unknown appointment returns `404 Appointment not found`.
</Note>

## Authentication

<ParamField header="Authorization" type="string" required>
  Bearer token for authenticated access. The doctor (user) identity is taken from the JWT.

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

A missing or invalid token returns `401` with a `message` field. See [Error Responses](#error-responses).

## Path Parameters

<ParamField path="id" type="string" required>
  Appointment ID (MongoDB ObjectId, 24 hex characters) to create or update notes for. Must be owned by the authenticated doctor.
</ParamField>

## Body Parameters

<ParamField body="notes" type="string" required>
  Clinical notes content. Effectively required — an empty value is rejected by the model. Markdown asterisks are stripped server-side before the content is stored (for example `*text*` is stored as `text`).
</ParamField>

<ParamField body="summary" type="string">
  Optional short summary. Defaults to an empty string when notes are first created. When notes already exist and `summary` is omitted, the existing summary is preserved.
</ParamField>

<ParamField body="citations" type="array">
  Optional citation objects. Stored only on the initial creation of a notes document. These are normally produced by the platform rather than supplied by integrators.
</ParamField>

## Response

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

<ResponseField name="data" type="object">
  The saved notes document.

  <Expandable title="data properties">
    <ResponseField name="_id" type="string">
      Unique identifier for the notes document (MongoDB ObjectId).
    </ResponseField>

    <ResponseField name="appointment_id" type="string">
      The appointment ID these notes belong to.
    </ResponseField>

    <ResponseField name="notes" type="string">
      The clinical notes content.
    </ResponseField>

    <ResponseField name="summary" type="string">
      Summary of the notes.
    </ResponseField>

    <ResponseField name="citations" type="array">
      Citation objects, or `null` when none are present.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO 8601 timestamp when the notes were created.
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO 8601 timestamp when the notes were last updated.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="error" type="string">
  Error message (only present when `success` is `false`).
</ResponseField>

<Note>
  The `data` object is the full saved notes document and may contain additional fields beyond those listed above. Treat any unlisted fields as opaque.
</Note>

## Example Request

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST \
    'https://app.medisync.me/api/notes/add/664e0b1f7c2a5e0011fa9911' \
    -H 'Authorization: Bearer your_jwt_token_here' \
    -H 'Content-Type: application/json' \
    -d '{
      "notes": "Patient presented with chest pain. EKG normal. Plan: monitor, follow up in 1 week.",
      "summary": "Chest pain, normal findings, continue monitoring"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://app.medisync.me/api/notes/add/664e0b1f7c2a5e0011fa9911',
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer your_jwt_token_here',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        notes: 'Patient presented with chest pain. EKG normal. Plan: monitor, follow up in 1 week.',
        summary: 'Chest pain, normal findings, continue monitoring'
      })
    }
  );

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

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

  response = requests.post(
      'https://app.medisync.me/api/notes/add/664e0b1f7c2a5e0011fa9911',
      headers={
          'Authorization': 'Bearer your_jwt_token_here',
          'Content-Type': 'application/json'
      },
      json={
          'notes': 'Patient presented with chest pain. EKG normal. Plan: monitor, follow up in 1 week.',
          'summary': 'Chest pain, normal findings, continue monitoring'
      }
  )

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

## Example Response

<ResponseExample>
  ```json Response theme={null}
  {
    "success": true,
    "data": {
      "_id": "665f1c2a9b1e8a0012ab34cd",
      "appointment_id": "664e0b1f7c2a5e0011fa9911",
      "notes": "Patient presented with chest pain. EKG normal. Plan: monitor, follow up in 1 week.",
      "summary": "Chest pain, normal findings, continue monitoring",
      "citations": null,
      "createdAt": "2026-06-30T10:30:00.000Z",
      "updatedAt": "2026-06-30T10:30:00.000Z"
    }
  }
  ```
</ResponseExample>

## Error Responses

<ResponseExample>
  ```json 401 Unauthorized (missing/invalid token) theme={null}
  {
    "success": false,
    "message": "Unauthorized"
  }
  ```

  ```json 401 Unauthorized (session revoked) theme={null}
  {
    "success": false,
    "message": "Session ended on this device because you signed in elsewhere.",
    "code": "SESSION_REVOKED"
  }
  ```

  ```json 403 Forbidden (not appointment owner) theme={null}
  {
    "success": false,
    "error": "Forbidden"
  }
  ```

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

  ```json 400 Validation error (missing notes) theme={null}
  {
    "success": false,
    "error": "Notes validation failed: notes: Path `notes` is required."
  }
  ```
</ResponseExample>

## Behavior Notes

* **Create vs update**: If a notes document already exists for the appointment it is updated; otherwise a new one is created.
* **Summary handling**: When `summary` is provided it is set. When it is omitted and notes already exist, the existing summary is preserved; for brand-new notes it defaults to an empty string.
* **Asterisk stripping**: Markdown asterisks are removed from `notes` before storage.
* **Automatic workflow**: On a successful save the appointment status is set to `finished` and a real-time update is emitted to connected clients.

## Status Codes

* **200** — Notes created or updated successfully.
* **400** — Validation or save failure.
* **401** — Missing, invalid, or revoked authentication token.
* **403** — Authenticated user does not own the appointment.
* **404** — Appointment not found.
