curl --request POST \
--url https://api.maxcare.ai/v3/patients/{id}/documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--header 'X-Organization-Id: <x-organization-id>' \
--form file=@example-file \
--form type=REFERRAL \
--form 'title=<string>'import requests
url = "https://api.maxcare.ai/v3/patients/{id}/documents"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"type": "REFERRAL",
"title": "<string>"
}
headers = {
"X-Organization-Id": "<x-organization-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('type', 'REFERRAL');
form.append('title', '<string>');
const options = {
method: 'POST',
headers: {'X-Organization-Id': '<x-organization-id>', Authorization: 'Bearer <token>'}
};
options.body = form;
fetch('https://api.maxcare.ai/v3/patients/{id}/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.maxcare.ai/v3/patients/{id}/documents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data",
"X-Organization-Id: <x-organization-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.maxcare.ai/v3/patients/{id}/documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Organization-Id", "<x-organization-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.maxcare.ai/v3/patients/{id}/documents")
.header("X-Organization-Id", "<x-organization-id>")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.maxcare.ai/v3/patients/{id}/documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Organization-Id"] = '<x-organization-id>'
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"code": "success",
"data": {
"patientId": "pat_c56103bcd39c46d39f3138dd2b5e05f6",
"documentId": "3f1c2a9e-7b1d-4c55-9a0e-2d4b8c1e6f70",
"ehrDocumentId": "201269302",
"ref": "ehr_eyJp….c2ln",
"type": null,
"category": "pathology",
"location": {
"id": "333500",
"title": "Pathology",
"resultsLog": true
}
}
}{
"code": "bad_request",
"message": "'id' must be a valid UUID",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unauthorized",
"message": "Invalid or missing API key",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "forbidden",
"message": "Insufficient scope",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "not_found",
"message": "Resource not found",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "conflict",
"message": "Cannot edit a signed note",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "payload_too_large",
"message": "File too large",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unsupported_media_type",
"message": "The uploaded file is not a PNG, JPEG, WEBP or HEIC image",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Maximum 1000 requests per 60 seconds.",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unexpected_integration_error",
"message": "EHR sync failed",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "server_unresponsive",
"message": "EHR integration is not available for this note",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}File a document on a patient's chart
Multipart upload of one PDF, PNG or JPEG (up to 25 MB; larger is refused with 413) into the patient’s chart in the EHR. Send exactly one of category or type. category (pathology, lab, prior_authorization, …) files the document where that category lives on the patient’s EHR instance — see GET /documents/categories: ModMed the practice’s matching category tab, EZDerm the Correspondences folder. A category the instance has no place for (or, on ModMed, a lab, pathology or imaging result while the practice’s results log cannot be read) is still filed, on the chart uncategorized (EZDerm, which has no uncategorized folder, files it in Correspondences). data.location says where it landed, or is null when the document is on the chart uncategorized — no place for the category, or ModMed took the file but did not confirm the category; do not upload it again. type: REFERRAL is the original form, kept as it was: EZDerm files it in the Correspondences folder; ModMed files it as an attachment titled title in the practice’s Referral category, or uncategorized when the practice has none. The declared content type is a hint only — the BYTES are sniffed, and anything else is rejected with 415 unsupported_media_type. The chart is re-listed right after the upload, so documentId is the id GET /patients/{id}/documents reports. documentId: null means that re-list failed, NOT the upload — the document is on the chart; do not upload it again. Send an Idempotency-Key header: a retry of the same file replays the original result for 24 hours, and a key reused for a different file is refused with 409. If the EHR does not confirm the upload the request fails with 409 ehr_write_uncertain — check the chart before uploading again. No copy of the bytes is kept on our side. Requires write:patient_documents.
curl --request POST \
--url https://api.maxcare.ai/v3/patients/{id}/documents \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--header 'X-Organization-Id: <x-organization-id>' \
--form file=@example-file \
--form type=REFERRAL \
--form 'title=<string>'import requests
url = "https://api.maxcare.ai/v3/patients/{id}/documents"
files = { "file": ("example-file", open("example-file", "rb")) }
payload = {
"type": "REFERRAL",
"title": "<string>"
}
headers = {
"X-Organization-Id": "<x-organization-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('file', '<string>');
form.append('type', 'REFERRAL');
form.append('title', '<string>');
const options = {
method: 'POST',
headers: {'X-Organization-Id': '<x-organization-id>', Authorization: 'Bearer <token>'}
};
options.body = form;
fetch('https://api.maxcare.ai/v3/patients/{id}/documents', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.maxcare.ai/v3/patients/{id}/documents",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data",
"X-Organization-Id: <x-organization-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.maxcare.ai/v3/patients/{id}/documents"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Organization-Id", "<x-organization-id>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.maxcare.ai/v3/patients/{id}/documents")
.header("X-Organization-Id", "<x-organization-id>")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.maxcare.ai/v3/patients/{id}/documents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Organization-Id"] = '<x-organization-id>'
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"type\"\r\n\r\nREFERRAL\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"title\"\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"code": "success",
"data": {
"patientId": "pat_c56103bcd39c46d39f3138dd2b5e05f6",
"documentId": "3f1c2a9e-7b1d-4c55-9a0e-2d4b8c1e6f70",
"ehrDocumentId": "201269302",
"ref": "ehr_eyJp….c2ln",
"type": null,
"category": "pathology",
"location": {
"id": "333500",
"title": "Pathology",
"resultsLog": true
}
}
}{
"code": "bad_request",
"message": "'id' must be a valid UUID",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unauthorized",
"message": "Invalid or missing API key",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "forbidden",
"message": "Insufficient scope",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "not_found",
"message": "Resource not found",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "conflict",
"message": "Cannot edit a signed note",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "payload_too_large",
"message": "File too large",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unsupported_media_type",
"message": "The uploaded file is not a PNG, JPEG, WEBP or HEIC image",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Maximum 1000 requests per 60 seconds.",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "unexpected_integration_error",
"message": "EHR sync failed",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}{
"code": "server_unresponsive",
"message": "EHR integration is not available for this note",
"trace_id": "550e8400-e29b-41d4-a716-446655440000"
}Authorizations
Marketplace API key
Headers
Client-generated key protecting retries for 24 hours
Target clinic organization ID
Path Parameters
Patient ID
Body
The document (PDF, PNG or JPEG)
What the document is; decides where it is filed. Send this or type.
referral, pathology, lab, imaging, prior_authorization, medical_records, records_request, correspondence, prescription, forms, insurance, billing, audit, disclosure The original form of category: referral
REFERRAL Title shown on the chart
200