Skip to main content
PUT
/
documents
/
{id}
curl -X PUT \
  'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12' \
  -H 'Authorization: Bearer your_jwt_token_here' \
  -F 'document=@updated_report.pdf' \
  -F 'title=Updated Report'
const formData = new FormData();
formData.append('document', file); // PDF or image file
formData.append('title', 'Updated Report'); // optional

const response = await fetch(
  'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12',
  {
    method: 'PUT',
    headers: { Authorization: 'Bearer your_jwt_token_here' },
    body: formData,
  }
);

const result = await response.json();
import requests

files = {'document': open('updated_report.pdf', 'rb')}
data = {'title': 'Updated Report'}  # optional

response = requests.put(
    'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12',
    headers={'Authorization': 'Bearer your_jwt_token_here'},
    files=files,
    data=data,
)

result = response.json()
{
  "success": true,
  "data": {
    "_id": "66a3f1c2b8e4d21f9c0a7b40",
    "appointment_id": "665e0b9d3f2a1c4d8e7f0a12",
    "document_url": "https://storage.medisync.me/665e0b9d3f2a1c4d8e7f0a12_1719924000000_updated_report.pdf",
    "document_key": "665e0b9d3f2a1c4d8e7f0a12_1719924000000_updated_report.pdf",
    "doctor_id": "6512a7c9e4b0a1f2d3c45678",
    "file_name": "updated_report.pdf",
    "title": "updated_report.pdf",
    "file_type": "pdf",
    "mime_type": "application/pdf",
    "source": "upload",
    "extraction_status": "pending",
    "include_in_context": true,
    "createdAt": "2026-07-02T15:20:00.000Z",
    "updatedAt": "2026-07-02T15:20:00.000Z",
    "__v": 0
  }
}

Overview

Uploads a new document file for an appointment. Depending on what is already attached, the endpoint either replaces an existing document or adds a new one:
  • If the appointment has a consent document, that consent document is replaced.
  • Otherwise, if the appointment has exactly one document, that document is replaced.
  • Otherwise (multiple documents and none is a consent document), the new file is simply added.
A new document record with a new _id is created on every call. Accepted file types are PDF, PNG, JPEG, JPG and WEBP.
This operation is not atomic. When a document is replaced, the old file is deleted from storage and the database first, and the new file is uploaded afterward. If the new upload fails, the old document is already gone.
This endpoint is plan-gated by the documents.attach_additional feature. Accounts whose plan does not include it receive 403 FEATURE_NOT_AVAILABLE.

Authentication

Authorization
string
required
Bearer token for authenticated access. The doctor’s ID is extracted from the JWT token.
Authorization: Bearer your_jwt_token_here

Path Parameters

id
string
required
The appointment ID (ObjectId) whose document should be replaced or created. The appointment must belong to the authenticated doctor, otherwise a 403 Forbidden is returned.

Body Parameters

The request must be sent as multipart/form-data.
document
file
required
The replacement document file. Allowed types: application/pdf, image/png, image/jpeg, image/jpg, image/webp.
title
string
Optional display title for the document. If omitted, the uploaded file’s original filename is used.

Response

success
boolean
Whether the operation was successful
data
object
The newly stored document record
error
string
Error message (only present when success is false)
Additional fields may be present on the document object and should be treated as opaque.

Example Request

curl -X PUT \
  'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12' \
  -H 'Authorization: Bearer your_jwt_token_here' \
  -F 'document=@updated_report.pdf' \
  -F 'title=Updated Report'
const formData = new FormData();
formData.append('document', file); // PDF or image file
formData.append('title', 'Updated Report'); // optional

const response = await fetch(
  'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12',
  {
    method: 'PUT',
    headers: { Authorization: 'Bearer your_jwt_token_here' },
    body: formData,
  }
);

const result = await response.json();
import requests

files = {'document': open('updated_report.pdf', 'rb')}
data = {'title': 'Updated Report'}  # optional

response = requests.put(
    'https://app.medisync.me/api/documents/665e0b9d3f2a1c4d8e7f0a12',
    headers={'Authorization': 'Bearer your_jwt_token_here'},
    files=files,
    data=data,
)

result = response.json()

Example Response

{
  "success": true,
  "data": {
    "_id": "66a3f1c2b8e4d21f9c0a7b40",
    "appointment_id": "665e0b9d3f2a1c4d8e7f0a12",
    "document_url": "https://storage.medisync.me/665e0b9d3f2a1c4d8e7f0a12_1719924000000_updated_report.pdf",
    "document_key": "665e0b9d3f2a1c4d8e7f0a12_1719924000000_updated_report.pdf",
    "doctor_id": "6512a7c9e4b0a1f2d3c45678",
    "file_name": "updated_report.pdf",
    "title": "updated_report.pdf",
    "file_type": "pdf",
    "mime_type": "application/pdf",
    "source": "upload",
    "extraction_status": "pending",
    "include_in_context": true,
    "createdAt": "2026-07-02T15:20:00.000Z",
    "updatedAt": "2026-07-02T15:20:00.000Z",
    "__v": 0
  }
}

Error Responses

{
  "success": false,
  "error": "Error deleting old document"
}
{
  "success": false,
  "error": "Unsupported file type. Allowed: PDF, PNG, JPEG, WEBP."
}
{
  "success": false,
  "error": "No file uploaded"
}
{
  "success": false,
  "error": "Appointment not found"
}
{
  "success": false,
  "error": "Forbidden"
}
{
  "success": false,
  "code": "FEATURE_NOT_AVAILABLE",
  "feature": "documents.attach_additional",
  "message": "This feature is not included in your current plan."
}
{
  "success": false,
  "message": "Unauthorized"
}