Skip to content

API reference

Patients

Master pasien, consent, alergi, dokumen pasien, dan lookup identitas (modul frontoffice).

OpenAPI 3.1 · version 1.1.0 · 127 operations · 30 webhook events

Base URLhttps://api.medivana.cloud/api/v1

Endpoint descriptions come from the OpenAPI specification and are written in Indonesian.

Cari atau daftar pasien

q dikenali otomatis: 16 digit → NIK (persis), 13 digit → No. BPJS, 08…/628… → telepon, berisi angka tanpa spasi → No. RM, selain itu nama (substring lalu kemiripan ejaan). Filter eksplisit boleh digabung. Tanpa q/filter: pasien terbaru berhalaman cursor; pencarian tidak berhalaman (maks limit). Identitas di daftar selalu tersamar (*_masked); nilai penuh hanya di detail.

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Parameters

Parameters GET /patients
NameInTypeDescription
qquerystringNIK, No. BPJS, telepon, No. RM, atau nama
nikquerystring
mrnquerystring
namequerystring
phonequerystring
bpjs_noquerystring
birth_datequerystring (date)
include_mergedqueryboolean
include_inactivequeryboolean
limitqueryinteger
cursorquerystringNilai next_cursor dari halaman sebelumnya

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Daftar pasien (identitas tersamar)application/json

{
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "mrn": "RM-000123",
      "name": "Pasien Contoh",
      "sex": "female",
      "birth_date": "1990-05-12",
      "age_label": "36 th 5 bl",
      "age_years": 36,
      "nik_masked": "9999********0001",
      "phone_masked": "6281******001",
      "bpjs_no_masked": "*********0001",
      "allergy_status": "has",
      "is_active": true,
      "merged_into": null
    }
  ],
  "next_cursor": "eyJ0IjoiMjAyNi0xMC0yOVQwODoxNTowMiswNzowMCJ9"
}
Schema 200
Schema 200
NameTypeDescription
itemsrequiredarray<object>
items[].idstring (uuid)
items[].mrnstring
items[].namestring
items[].sexmale | female
items[].birth_datestring (date) | null
items[].age_labelstring
items[].age_yearsinteger | null
items[].nik_maskedstring | null
items[].phone_maskedstring | null
items[].bpjs_no_maskedstring | null
items[].allergy_statusunknown | none | has
items[].is_activeboolean
items[].merged_intostring (uuid) | null
next_cursorstring
Errors
  • 400bad-requestParameter atau format permintaan tidak valid
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenScope token tidak memberi izin (forbidden), atau langganan klinik baca-saja untuk operasi tulis (read-only)
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Daftarkan pasien baru

Wajib name dan sex. mrn kosong → nomor RM otomatis sesuai pengaturan RM klinik. Telepon dinormalkan ke 62…. Bila nik diisi dan satusehat_ihs kosong, server mencari IHS number ke SATUSEHAT (maks 3 detik; kegagalan tidak menghalangi pendaftaran, lihat satusehat_lookup). NIK yang sudah terdaftar → 409 dengan existing_patient_id; baca pasien itu alih-alih membuat baru. Menerbitkan event patient.created.

Scopes
patients:write
RBAC permissions
patient.write
Module
frontoffice
X-Branch-ID
X-Branch-ID required

Parameters

Parameters POST /patients
NameInTypeDescription
X-Branch-IDrequiredheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Request body application/json

Request body POST /patients
NameTypeDescription
namestring
sexmale | female | L | P
birth_datestring (date)
birth_placestring
nikstring
phonestring
bpjs_nostring
emailstring
addressstring
villagestring
districtstring
citystring
provincestring
postal_codestring
religionstring
marital_statussingle | married | divorced | widowed
occupationstring
educationstring
blood_typestring
nationalitystring
mother_namestring
emergency_namestring
emergency_relationstring
emergency_phonestring
satusehat_ihsstring | null
notesstring | null
mrnstring | nullKosong = nomor RM otomatis
skip_satusehat_lookupboolean
{
  "name": "Pasien Contoh",
  "sex": "female",
  "birth_date": "1990-05-12",
  "birth_place": "Semarang",
  "nik": "9999010101900001",
  "phone": "0812-0000-0001",
  "email": "pasien@contoh.test",
  "address": "Jl. Contoh No. 10",
  "city": "Semarang",
  "province": "Jawa Tengah",
  "skip_satusehat_lookup": false
}

Code examples

Code example language
curl -X POST "https://api.medivana.cloud/api/v1/patients" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "X-Branch-ID: $MEDIVANA_BRANCH_ID" \
  -H "Content-Type: application/json" \
  -d '{"name":"Pasien Contoh","sex":"female","birth_date":"1990-05-12","birth_place":"Semarang","nik":"9999010101900001","phone":"0812-0000-0001","email":"pasien@contoh.test","address":"Jl. Contoh No. 10","city":"Semarang","province":"Jawa Tengah","skip_satusehat_lookup":false}'
const res = await fetch("https://api.medivana.cloud/api/v1/patients", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "X-Branch-ID": process.env.MEDIVANA_BRANCH_ID,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Pasien Contoh",
    sex: "female",
    birth_date: "1990-05-12",
    birth_place: "Semarang",
    nik: "9999010101900001",
    phone: "0812-0000-0001",
    email: "pasien@contoh.test",
    address: "Jl. Contoh No. 10",
    city: "Semarang",
    province: "Jawa Tengah",
    skip_satusehat_lookup: false,
  }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.post(
    "https://api.medivana.cloud/api/v1/patients",
    headers={
        "Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}",
        "X-Branch-ID": os.environ["MEDIVANA_BRANCH_ID"],
    },
    json={
        "name": "Pasien Contoh",
        "sex": "female",
        "birth_date": "1990-05-12",
        "birth_place": "Semarang",
        "nik": "9999010101900001",
        "phone": "0812-0000-0001",
        "email": "pasien@contoh.test",
        "address": "Jl. Contoh No. 10",
        "city": "Semarang",
        "province": "Jawa Tengah",
        "skip_satusehat_lookup": False,
    },
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

201Pasien dibuatapplication/json

{
  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
  "mrn": "RM-000123",
  "name": "Pasien Contoh",
  "sex": "female",
  "birth_date": "1990-05-12",
  "birth_place": "Semarang",
  "age_label": "36 th 5 bl",
  "age_years": 36,
  "nik_masked": "9999********0001",
  "nik": "9999010101900001",
  "phone_masked": "6281******001",
  "phone": "6281200000001",
  "bpjs_no_masked": null,
  "bpjs_no": null,
  "email": "pasien@contoh.test",
  "address": "Jl. Contoh No. 10",
  "city": "Semarang",
  "province": "Jawa Tengah",
  "satusehat_ihs": "P00000000001",
  "allergy_status": "unknown",
  "is_active": true,
  "merged_into": null,
  "registered_branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
  "notes": null,
  "created_at": "2026-10-29T08:15:02+07:00",
  "updated_at": "2026-10-29T08:15:02+07:00",
  "version": 1,
  "satusehat_lookup": "found"
}
Schema 201
Schema 201
NameTypeDescription
idstring (uuid)
mrnstring
namestring
sexmale | female
birth_datestring (date) | null
age_labelstring
age_yearsinteger | null
nik_maskedstring | null
phone_maskedstring | null
bpjs_no_maskedstring | null
allergy_statusunknown | none | has
is_activeboolean
merged_intostring (uuid) | null
nikstring | null
phonestring | null
bpjs_nostring | null
birth_placestring | null
emailstring | null
addressstring | null
villagestring | null
districtstring | null
citystring | null
provincestring | null
postal_codestring | null
religionstring | null
marital_statussingle | married | divorced | widowed | null
occupationstring | null
educationstring | null
blood_typestring | null
nationalitystring | null
mother_namestring | null
emergency_namestring | null
emergency_relationstring | null
emergency_phonestring | null
satusehat_ihsstring | null
registered_branch_idstring (uuid) | null
notesstring | null
created_atstring (date-time)
updated_atstring (date-time)
versioninteger
satusehat_lookupfound | not_found | unavailable | skippedHanya pada respons create/lookup
Errors
  • 400bad-requestCabang aktif belum dipilih (X-Branch-ID)
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenScope token tidak memberi izin (forbidden), atau langganan klinik baca-saja untuk operasi tulis (read-only)
  • 409conflictNIK sudah terdaftar
  • 422validationValidasi gagal; rincian per field di errors
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Periksa kemungkinan pasien ganda

Panggil sebelum membuat pasien. Kriteria NIK sama (skor 1), telepon sama (0,6), tanggal lahir sama + nama mirip, atau nama sangat mirip.

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Parameters

Parameters GET /patients/duplicate-check
NameInTypeDescription
namequerystring
birth_datequerystring (date)
nikquerystring
phonequerystring
exclude_idquerystring (uuid)Abaikan pasien ini (saat mengubah data)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/duplicate-check" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/duplicate-check", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/duplicate-check",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Kandidat duplikat (skor tertinggi dulu)application/json

{
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "mrn": "RM-000123",
      "name": "Pasien Contoh",
      "sex": "female",
      "birth_date": "1990-05-12",
      "nik_masked": "9999********0001",
      "reasons": [
        "name_birth_date"
      ],
      "score": 0.8
    }
  ]
}
Schema 200
Schema 200
NameTypeDescription
itemsrequiredarray<object>
items[].idstring (uuid)
items[].mrnstring
items[].namestring
items[].sexmale | female
items[].birth_datestring (date) | null
items[].age_labelstring
items[].age_yearsinteger | null
items[].nik_maskedstring | null
items[].phone_maskedstring | null
items[].bpjs_no_maskedstring | null
items[].allergy_statusunknown | none | has
items[].is_activeboolean
items[].merged_intostring (uuid) | null
items[].reasonsarray<nik | phone | name_birth_date | name>
items[].scorenumber
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenScope token tidak memberi izin (forbidden), atau langganan klinik baca-saja untuk operasi tulis (read-only)
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Cari NIK di data lokal lalu SATUSEHAT

local berisi pasien tersamar bila NIK sudah terdaftar. SATUSEHAT dilewati (skipped) bila pasien lokal sudah punya IHS number. unavailable = integrasi belum dikonfigurasi, galat, atau timeout.

Scopes
patients:write
RBAC permissions
patient.write
Module
frontoffice

Request body application/json

Request body POST /patients/lookup-nik
NameTypeDescription
nikrequiredstring
{
  "nik": "9999010101900001"
}

Code examples

Code example language
curl -X POST "https://api.medivana.cloud/api/v1/patients/lookup-nik" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"nik":"9999010101900001"}'
const res = await fetch("https://api.medivana.cloud/api/v1/patients/lookup-nik", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    nik: "9999010101900001",
  }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.post(
    "https://api.medivana.cloud/api/v1/patients/lookup-nik",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    json={
        "nik": "9999010101900001",
    },
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Hasil lookupapplication/json

{
  "local": null,
  "satusehat": {
    "status": "found",
    "patient": {
      "ihs_number": "P00000000001",
      "nik": "9999010101900001",
      "name": "PASIEN CONTOH",
      "birth_date": "1990-05-12T00:00:00Z",
      "gender": "female",
      "address": "Jl. Contoh No. 10"
    }
  }
}
Schema 200
Schema 200
NameTypeDescription
localobject | null
satusehatobject
satusehat.statusfound | not_found | unavailable | skipped
satusehat.patientobject | null
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenScope token tidak memberi izin (forbidden), atau langganan klinik baca-saja untuk operasi tulis (read-only)
  • 422validationValidasi gagal; rincian per field di errors
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Format nomor rekam medis

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/mrn-settings" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/mrn-settings", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/mrn-settings",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Pengaturan nomor RMapplication/json

{
  "prefix": "RM-",
  "pad_length": 6,
  "last_value": 122,
  "example": "RM-000123"
}
Schema 200
Schema 200
NameTypeDescription
prefixstring
pad_lengthinteger
last_valueinteger
examplestring
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenScope token tidak memberi izin (forbidden), atau langganan klinik baca-saja untuk operasi tulis (read-only)
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Detail pasien

Identitas lengkap (NIK, telepon, BPJS penuh). Setiap pembacaan dicatat di audit log (patient.read). Pasien yang sudah digabung punya merged_into; ikuti ke pasien tujuan.

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Parameters

Parameters GET /patients/{id}
NameInTypeDescription
idrequiredpathstring (uuid)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Pasienapplication/json

{
  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
  "mrn": "RM-000123",
  "name": "Pasien Contoh",
  "sex": "female",
  "birth_date": "1990-05-12",
  "birth_place": "Semarang",
  "age_label": "36 th 5 bl",
  "age_years": 36,
  "nik_masked": "9999********0001",
  "nik": "9999010101900001",
  "phone_masked": "6281******001",
  "phone": "6281200000001",
  "bpjs_no_masked": null,
  "bpjs_no": null,
  "email": "pasien@contoh.test",
  "address": "Jl. Contoh No. 10",
  "city": "Semarang",
  "province": "Jawa Tengah",
  "satusehat_ihs": "P00000000001",
  "allergy_status": "unknown",
  "is_active": true,
  "merged_into": null,
  "registered_branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
  "notes": null,
  "created_at": "2026-10-29T08:15:02+07:00",
  "updated_at": "2026-10-29T08:15:02+07:00",
  "version": 1,
  "satusehat_lookup": "found"
}
Schema 200
Schema 200
NameTypeDescription
idstring (uuid)
mrnstring
namestring
sexmale | female
birth_datestring (date) | null
age_labelstring
age_yearsinteger | null
nik_maskedstring | null
phone_maskedstring | null
bpjs_no_maskedstring | null
allergy_statusunknown | none | has
is_activeboolean
merged_intostring (uuid) | null
nikstring | null
phonestring | null
bpjs_nostring | null
birth_placestring | null
emailstring | null
addressstring | null
villagestring | null
districtstring | null
citystring | null
provincestring | null
postal_codestring | null
religionstring | null
marital_statussingle | married | divorced | widowed | null
occupationstring | null
educationstring | null
blood_typestring | null
nationalitystring | null
mother_namestring | null
emergency_namestring | null
emergency_relationstring | null
emergency_phonestring | null
satusehat_ihsstring | null
registered_branch_idstring (uuid) | null
notesstring | null
created_atstring (date-time)
updated_atstring (date-time)
versioninteger
satusehat_lookupfound | not_found | unavailable | skippedHanya pada respons create/lookup
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Ubah data pasien

Kirim hanya field yang berubah; string kosong "" mengosongkan field opsional. Mengubah nik dicek duplikat (409 + existing_patient_id). Pasien yang sudah digabung → 409. Menerbitkan event patient.updated.

Scopes
patients:write
RBAC permissions
patient.write
Module
frontoffice
X-Branch-ID
X-Branch-ID required

Parameters

Parameters PATCH /patients/{id}
NameInTypeDescription
idrequiredpathstring (uuid)
X-Branch-IDrequiredheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.
If-MatchheaderstringVersi dari ETag (mis. "3"). Bila tidak cocok → 412 stale.

Request body application/json

Request body PATCH /patients/{id}
NameTypeDescription
namestring
sexmale | female | L | P
birth_datestring (date)
birth_placestring
nikstring
phonestring
bpjs_nostring
emailstring
addressstring
villagestring
districtstring
citystring
provincestring
postal_codestring
religionstring
marital_statussingle | married | divorced | widowed
occupationstring
educationstring
blood_typestring
nationalitystring
mother_namestring
emergency_namestring
emergency_relationstring
emergency_phonestring
satusehat_ihsstring | null
notesstring | null
mrnstring | nullKosong = nomor RM otomatis
skip_satusehat_lookupboolean
{
  "phone": "0812-0000-0002",
  "address": "Jl. Contoh Baru No. 2",
  "email": ""
}

Code examples

Code example language
curl -X PATCH "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "X-Branch-ID: $MEDIVANA_BRANCH_ID" \
  -H "Content-Type: application/json" \
  -d '{"phone":"0812-0000-0002","address":"Jl. Contoh Baru No. 2","email":""}'
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "X-Branch-ID": process.env.MEDIVANA_BRANCH_ID,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phone: "0812-0000-0002",
    address: "Jl. Contoh Baru No. 2",
    email: "",
  }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.patch(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001",
    headers={
        "Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}",
        "X-Branch-ID": os.environ["MEDIVANA_BRANCH_ID"],
    },
    json={
        "phone": "0812-0000-0002",
        "address": "Jl. Contoh Baru No. 2",
        "email": "",
    },
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Pasien terbaruapplication/json

{
  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "mrn": "string",
  "name": "string",
  "sex": "male",
  "birth_date": "2026-11-02",
  "age_label": "string",
  "age_years": 0,
  "nik_masked": "string",
  "phone_masked": "string",
  "bpjs_no_masked": "string",
  "allergy_status": "unknown",
  "is_active": true,
  "merged_into": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "nik": "string",
  "phone": "string",
  "bpjs_no": "string",
  "birth_place": "string",
  "email": "string",
  "address": "string",
  "village": "string",
  "district": "string",
  "city": "string",
  "province": "string",
  "postal_code": "string",
  "religion": "string",
  "marital_status": "single",
  "occupation": "string",
  "education": "string",
  "blood_type": "string",
  "nationality": "string",
  "mother_name": "string",
  "emergency_name": "string",
  "emergency_relation": "string",
  "emergency_phone": "string",
  "satusehat_ihs": "string",
  "registered_branch_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "notes": "string",
  "created_at": "2026-11-02T08:00:00+07:00",
  "updated_at": "2026-11-02T08:00:00+07:00",
  "version": 0,
  "satusehat_lookup": "found"
}
Schema 200
Schema 200
NameTypeDescription
idstring (uuid)
mrnstring
namestring
sexmale | female
birth_datestring (date) | null
age_labelstring
age_yearsinteger | null
nik_maskedstring | null
phone_maskedstring | null
bpjs_no_maskedstring | null
allergy_statusunknown | none | has
is_activeboolean
merged_intostring (uuid) | null
nikstring | null
phonestring | null
bpjs_nostring | null
birth_placestring | null
emailstring | null
addressstring | null
villagestring | null
districtstring | null
citystring | null
provincestring | null
postal_codestring | null
religionstring | null
marital_statussingle | married | divorced | widowed | null
occupationstring | null
educationstring | null
blood_typestring | null
nationalitystring | null
mother_namestring | null
emergency_namestring | null
emergency_relationstring | null
emergency_phonestring | null
satusehat_ihsstring | null
registered_branch_idstring (uuid) | null
notesstring | null
created_atstring (date-time)
updated_atstring (date-time)
versioninteger
satusehat_lookupfound | not_found | unavailable | skippedHanya pada respons create/lookup
Errors
  • 400bad-requestCabang aktif belum dipilih (X-Branch-ID)
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 409conflictKonflik data atau status tidak mengizinkan aksi
  • 412staleIf-Match tidak cocok dengan versi terbaru
  • 422validationValidasi gagal; rincian per field di errors
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Lookup ulang IHS number SATUSEHAT dari NIK tersimpan

Tanpa body. 422 bila pasien belum punya NIK. Respons memuat satusehat_lookup.

Scopes
patients:write
RBAC permissions
patient.write
Module
frontoffice
X-Branch-ID
X-Branch-ID required

Parameters

Parameters POST /patients/{id}/satusehat-lookup
NameInTypeDescription
idrequiredpathstring (uuid)
X-Branch-IDrequiredheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Code examples

Code example language
curl -X POST "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/satusehat-lookup" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "X-Branch-ID: $MEDIVANA_BRANCH_ID"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/satusehat-lookup", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "X-Branch-ID": process.env.MEDIVANA_BRANCH_ID,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.post(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/satusehat-lookup",
    headers={
        "Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}",
        "X-Branch-ID": os.environ["MEDIVANA_BRANCH_ID"],
    },
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Pasienapplication/json

{
  "id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "mrn": "string",
  "name": "string",
  "sex": "male",
  "birth_date": "2026-11-02",
  "age_label": "string",
  "age_years": 0,
  "nik_masked": "string",
  "phone_masked": "string",
  "bpjs_no_masked": "string",
  "allergy_status": "unknown",
  "is_active": true,
  "merged_into": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "nik": "string",
  "phone": "string",
  "bpjs_no": "string",
  "birth_place": "string",
  "email": "string",
  "address": "string",
  "village": "string",
  "district": "string",
  "city": "string",
  "province": "string",
  "postal_code": "string",
  "religion": "string",
  "marital_status": "single",
  "occupation": "string",
  "education": "string",
  "blood_type": "string",
  "nationality": "string",
  "mother_name": "string",
  "emergency_name": "string",
  "emergency_relation": "string",
  "emergency_phone": "string",
  "satusehat_ihs": "string",
  "registered_branch_id": "3f0c2a10-5b7e-4c1d-9a2e-000000000001",
  "notes": "string",
  "created_at": "2026-11-02T08:00:00+07:00",
  "updated_at": "2026-11-02T08:00:00+07:00",
  "version": 0,
  "satusehat_lookup": "found"
}
Schema 200
Schema 200
NameTypeDescription
idstring (uuid)
mrnstring
namestring
sexmale | female
birth_datestring (date) | null
age_labelstring
age_yearsinteger | null
nik_maskedstring | null
phone_maskedstring | null
bpjs_no_maskedstring | null
allergy_statusunknown | none | has
is_activeboolean
merged_intostring (uuid) | null
nikstring | null
phonestring | null
bpjs_nostring | null
birth_placestring | null
emailstring | null
addressstring | null
villagestring | null
districtstring | null
citystring | null
provincestring | null
postal_codestring | null
religionstring | null
marital_statussingle | married | divorced | widowed | null
occupationstring | null
educationstring | null
blood_typestring | null
nationalitystring | null
mother_namestring | null
emergency_namestring | null
emergency_relationstring | null
emergency_phonestring | null
satusehat_ihsstring | null
registered_branch_idstring (uuid) | null
notesstring | null
created_atstring (date-time)
updated_atstring (date-time)
versioninteger
satusehat_lookupfound | not_found | unavailable | skippedHanya pada respons create/lookup
Errors
  • 400bad-requestCabang aktif belum dipilih (X-Branch-ID)
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 422validationValidasi gagal; rincian per field di errors
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Riwayat penggabungan pasien

Penggabungan di mana pasien menjadi tujuan atau sumber. Penggabungan dilakukan petugas di aplikasi (event patient.merged).

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Parameters

Parameters GET /patients/{id}/merges
NameInTypeDescription
idrequiredpathstring (uuid)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/merges" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/merges", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/merges",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Riwayat gabungapplication/json

{
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a9001",
      "target_patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "source_patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0002",
      "reason": "Pasien terdaftar dua kali",
      "source_snapshot": {
        "mrn": "RM-000124",
        "name": "Pasien Contoh",
        "sex": "female",
        "birth_date": "1990-05-12",
        "had_nik": false
      },
      "moved": {
        "encounters": 1,
        "queues": 1,
        "observations": 6,
        "diagnoses": 1,
        "procedures": 0,
        "allergies": 0,
        "consents": 0,
        "letters": 0,
        "clinical_documents": 0,
        "charges": 2,
        "files": 0
      },
      "merged_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
      "merged_at": "2026-10-29T09:00:00+07:00"
    }
  ]
}
Schema 200
Schema 200
NameTypeDescription
itemsrequiredarray<object>
items[].idstring (uuid)
items[].target_patient_idstring (uuid)
items[].source_patient_idstring (uuid)
items[].reasonstring
items[].source_snapshotobject
items[].movedobject
items[].merged_bystring (uuid)
items[].merged_atstring (date-time)
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Consent pasien (terkini per jenis dan riwayat)

current[kind] = consent terbaru per jenis (bisa withdrawn), null bila belum pernah. Jenis: data_processing, photo, recording, telemedicine, broadcast.

Scopes
patients:readpatients:write(any one of)
RBAC permissions
patient.read
Module
frontoffice

Parameters

Parameters GET /patients/{id}/consents
NameInTypeDescription
idrequiredpathstring (uuid)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/consents" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/consents", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/consents",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Consentapplication/json

{
  "current": {
    "data_processing": null,
    "photo": {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a7001",
      "kind": "photo",
      "status": "granted"
    },
    "recording": null,
    "telemedicine": null,
    "broadcast": null
  },
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a7001",
      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "kind": "photo",
      "status": "granted",
      "consent_version": "1.0",
      "consent_text": "Saya setuju foto klinis diambil untuk rekam medis.",
      "method": "written",
      "signer_name": null,
      "signer_relation": "self",
      "witness_name": null,
      "evidence_file_id": null,
      "encounter_id": null,
      "granted_at": "2026-10-29T08:20:00+07:00",
      "granted_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
      "withdrawn_at": null,
      "withdrawn_by": null,
      "withdraw_reason": null
    }
  ]
}
Schema 200
Schema 200
NameTypeDescription
currentobject
itemsarray<object>
items[].idstring (uuid)
items[].patient_idstring (uuid)
items[].kinddata_processing | photo | recording | telemedicine | broadcast
items[].statusgranted | withdrawn
items[].consent_versionstring
items[].consent_textstring
items[].methodwritten | verbal | digital | kiosk
items[].signer_namestring | null
items[].signer_relationstring
items[].witness_namestring | null
items[].evidence_file_idstring (uuid) | null
items[].encounter_idstring (uuid) | null
items[].granted_atstring (date-time)
items[].granted_bystring (uuid) | null
items[].withdrawn_atstring (date-time) | null
items[].withdrawn_bystring (uuid) | null
items[].withdraw_reasonstring | null
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya
GET/patients/{id}/allergiesLink to this operation: Alergi pasien

Alergi pasien

allergy_status: unknown (belum dikaji), none (tidak ada alergi), has. Alergi resolved disembunyikan kecuali include_resolved=true.

Scopes
encounters:readpatients:readpatients:write(any one of)
RBAC permissions
encounter.read · patient.read
Module
rme

Parameters

Parameters GET /patients/{id}/allergies
NameInTypeDescription
idrequiredpathstring (uuid)
include_resolvedqueryboolean

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/allergies" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/allergies", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/allergies",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Alergiapplication/json

{
  "allergy_status": "has",
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a8001",
      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "encounter_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
      "substance": "Amoksisilin",
      "substance_code": null,
      "code_system": null,
      "item_id": null,
      "category": "obat",
      "reaction": "Urtikaria",
      "severity": "berat",
      "status": "active",
      "onset": "2019",
      "notes": null,
      "recorded_at": "2026-10-29T09:10:00+07:00",
      "recorded_by": "3f0c2a10-5b7e-4c1d-9a2e-0000000d1001",
      "resolved_at": null,
      "version": 1
    }
  ]
}
Schema 200
Schema 200
NameTypeDescription
allergy_statusunknown | none | has
itemsarray<object>
items[].idstring (uuid)
items[].patient_idstring (uuid)
items[].encounter_idstring (uuid) | null
items[].substancestring
items[].substance_codestring | null
items[].code_systemstring | null
items[].item_idstring (uuid) | null
items[].categoryobat | makanan | lingkungan
items[].reactionstring | null
items[].severityringan | sedang | berat | null
items[].statusactive | resolved | entered_in_error
items[].onsetstring | null
items[].notesstring | null
items[].recorded_atstring (date-time)
items[].recorded_bystring (uuid) | null
items[].resolved_atstring (date-time) | null
items[].versioninteger
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Riwayat klinis ringkas pasien

Kunjungan terakhir, diagnosis berulang, tindakan, alergi aktif, dan tren tanda vital (≤10 nilai per kunci, lama → baru). Diaudit.

Scopes
encounters:read
RBAC permissions
encounter.read
Module
rme

Parameters

Parameters GET /patients/{id}/history-summary
NameInTypeDescription
idrequiredpathstring (uuid)
encountersqueryintegerJumlah kunjungan terakhir

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/history-summary" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/history-summary", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/history-summary",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Ringkasan riwayatapplication/json

{
  "patient": {
    "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
    "name": "Pasien Contoh",
    "mrn": "RM-000123",
    "sex": "female",
    "birth_date": "1990-05-12",
    "age_label": "36 th 5 bl",
    "age_years": 36,
    "allergy_status": "has"
  },
  "allergies": [],
  "recent_encounters": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000e0001",
      "branch_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000000b1",
      "registered_at": "2026-10-29T08:30:00+07:00",
      "status": "finished",
      "unit_name": "Poli Umum",
      "practitioner_name": "dr. Rina Contoh",
      "chief_complaint": "Batuk pilek 3 hari",
      "primary_diagnosis": {
        "code": "J06.9",
        "display": "Infeksi saluran napas atas akut, tidak spesifik"
      }
    }
  ],
  "diagnoses": [
    {
      "code": "J06.9",
      "display": "Infeksi saluran napas atas akut, tidak spesifik",
      "count": 3,
      "last_seen": "2026-10-29T10:45:00+07:00"
    }
  ],
  "procedures": [],
  "vitals_trend": {
    "systolic": [
      {
        "value": 150,
        "flag": "H",
        "observed_at": "2026-10-29T09:05:00+07:00"
      }
    ]
  }
}
Schema 200
Schema 200
NameTypeDescription
patientobject
patient.idstring (uuid)
patient.namestring
patient.mrnstring
patient.sexmale | female
patient.birth_datestring (date) | null
patient.age_labelstring
patient.age_yearsinteger | null
patient.allergy_statusunknown | none | has
allergiesarray<object>
allergies[].idstring (uuid)
allergies[].patient_idstring (uuid)
allergies[].encounter_idstring (uuid) | null
allergies[].substancestring
allergies[].substance_codestring | null
allergies[].code_systemstring | null
allergies[].item_idstring (uuid) | null
allergies[].categoryobat | makanan | lingkungan
allergies[].reactionstring | null
allergies[].severityringan | sedang | berat | null
allergies[].statusactive | resolved | entered_in_error
allergies[].onsetstring | null
allergies[].notesstring | null
allergies[].recorded_atstring (date-time)
allergies[].recorded_bystring (uuid) | null
allergies[].resolved_atstring (date-time) | null
allergies[].versioninteger
recent_encountersarray<object>
recent_encounters[].idstring (uuid)
recent_encounters[].branch_idstring (uuid)
recent_encounters[].registered_atstring (date-time)
recent_encounters[].statusstring
recent_encounters[].unit_namestring
recent_encounters[].practitioner_namestring | null
recent_encounters[].chief_complaintstring | null
recent_encounters[].primary_diagnosisobject | null
recent_encounters[].primary_diagnosis.codestring
recent_encounters[].primary_diagnosis.displaystring
diagnosesarray<object>
diagnoses[].codestring
diagnoses[].displaystring
diagnoses[].countinteger
diagnoses[].last_seenstring (date-time)
proceduresarray<object>
procedures[].idstring (uuid)
procedures[].encounter_idstring (uuid)
procedures[].patient_idstring (uuid)
procedures[].icd9cm_codestring | null
procedures[].displaystring | null
procedures[].service_idstring (uuid) | null
procedures[].service_namestring | null
procedures[].quantitynumber
procedures[].practitioner_idstring (uuid) | null
procedures[].charge_idstring (uuid) | null
procedures[].statusstring
procedures[].notesstring | null
procedures[].performed_atstring (date-time)
vitals_trendobject
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Dokumen pasien (termasuk dokumen kunjungan)

Scopes
encounters:readpatients:write(any one of)
RBAC permissions
encounter.read · patient.write
Module
frontoffice

Parameters

Parameters GET /patients/{id}/documents
NameInTypeDescription
idrequiredpathstring (uuid)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

200Dokumenapplication/json

{
  "items": [
    {
      "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6001",
      "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
      "encounter_id": null,
      "file_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6101",
      "title": "Hasil lab luar",
      "category": "lab_external",
      "notes": null,
      "filename": "hasil-lab.pdf",
      "content_type": "application/pdf",
      "size_bytes": 182311,
      "uploaded_by": "3f0c2a10-5b7e-4c1d-9a2e-000000000a11",
      "created_at": "2026-10-29T08:40:00+07:00",
      "download_url": "/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-0000000a6001/download"
    }
  ]
}
Schema 200
Schema 200
NameTypeDescription
itemsrequiredarray<object>
items[].idstring (uuid)
items[].patient_idstring (uuid)
items[].encounter_idstring (uuid) | null
items[].file_idstring (uuid)
items[].titlestring
items[].categorygeneral | lab_external | imaging | referral | consent | photo | identity | other
items[].notesstring | null
items[].filenamestring
items[].content_typestring
items[].size_bytesinteger
items[].uploaded_bystring (uuid) | null
items[].created_atstring (date-time)
items[].download_urlstringPath relatif GET /clinical-documents/{id}/download
Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Unggah dokumen pasien

multipart/form-data, maks 20 MB. Tipe: PDF, JPG, PNG, WEBP, audio, DICOM, CSV, ZIP, JSON. file_id hasil unggahan bisa dipakai sebagai bukti consent di aplikasi.

Scopes
patients:write
RBAC permissions
encounter.write · patient.write
Module
frontoffice
X-Branch-ID
X-Branch-ID required

Parameters

Parameters POST /patients/{id}/documents
NameInTypeDescription
idrequiredpathstring (uuid)
X-Branch-IDrequiredheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Request body multipart/form-data

Request body POST /patients/{id}/documents
NameTypeDescription
filerequiredstring (binary)
titlestringDefault nama berkas
categorygeneral | lab_external | imaging | referral | consent | photo | identity | other
notesstring

Code examples

Code example language
curl -X POST "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "X-Branch-ID: $MEDIVANA_BRANCH_ID" \
  -F "file=@dokumen.pdf" \
  -F 'title=…' \
  -F 'category=…' \
  -F 'notes=…'
import { readFile } from "node:fs/promises";

const form = new FormData();
form.append("file", new Blob([await readFile("dokumen.pdf")]), "dokumen.pdf");
form.append("title", "…");
form.append("category", "…");
form.append("notes", "…");
const res = await fetch("https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "X-Branch-ID": process.env.MEDIVANA_BRANCH_ID,
  },
  body: form,
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const data = await res.json();
import os
import requests

resp = requests.post(
    "https://api.medivana.cloud/api/v1/patients/3f0c2a10-5b7e-4c1d-9a2e-000000000001/documents",
    headers={
        "Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}",
        "X-Branch-ID": os.environ["MEDIVANA_BRANCH_ID"],
    },
    files={"file": open("dokumen.pdf", "rb")},
    data={"title": "…", "category": "…", "notes": "…"},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()

Responses

201Dokumen dibuatapplication/json

{
  "id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6001",
  "patient_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a0001",
  "encounter_id": null,
  "file_id": "3f0c2a10-5b7e-4c1d-9a2e-0000000a6101",
  "title": "Hasil lab luar",
  "category": "lab_external",
  "notes": null,
  "filename": "hasil-lab.pdf",
  "content_type": "application/pdf",
  "size_bytes": 182311,
  "uploaded_by": "3f0c2a10-5b7e-4c1d-9a2e-000000000a11",
  "created_at": "2026-10-29T08:40:00+07:00",
  "download_url": "/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-0000000a6001/download"
}
Schema 201
Schema 201
NameTypeDescription
idstring (uuid)
patient_idstring (uuid)
encounter_idstring (uuid) | null
file_idstring (uuid)
titlestring
categorygeneral | lab_external | imaging | referral | consent | photo | identity | other
notesstring | null
filenamestring
content_typestring
size_bytesinteger
uploaded_bystring (uuid) | null
created_atstring (date-time)
download_urlstringPath relatif GET /clinical-documents/{id}/download
Errors
  • 400bad-requestCabang aktif belum dipilih (X-Branch-ID)
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 422validationValidasi gagal; rincian per field di errors
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya
GET/clinical-documents/{id}/downloadLink to this operation: Unduh isi dokumen klinis

Unduh isi dokumen klinis

Isi berkas apa adanya (Content-Disposition: inline). Diaudit document.read.

Scopes
encounters:readpatients:write(any one of)
RBAC permissions
encounter.read · patient.write
Module
frontoffice

Parameters

Parameters GET /clinical-documents/{id}/download
NameInTypeDescription
idrequiredpathstring (uuid)

Code examples

Code example language
curl -X GET "https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001/download" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN"
const res = await fetch("https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001/download", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
const file = Buffer.from(await res.arrayBuffer());
import os
import requests

resp = requests.get(
    "https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001/download",
    headers={"Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}"},
    timeout=30,
)
resp.raise_for_status()
content = resp.content

Responses

200Isi berkasapplication/octet-stream

Errors
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya

Hapus dokumen klinis (soft delete)

Dokumen kunjungan yang sudah ditandatangani tidak bisa dihapus (409).

Scopes
patients:write
RBAC permissions
encounter.write · patient.write
Module
frontoffice
X-Branch-ID
X-Branch-ID required

Parameters

Parameters DELETE /clinical-documents/{id}
NameInTypeDescription
idrequiredpathstring (uuid)
X-Branch-IDrequiredheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Code examples

Code example language
curl -X DELETE "https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001" \
  -H "Authorization: Bearer $MEDIVANA_TOKEN" \
  -H "X-Branch-ID: $MEDIVANA_BRANCH_ID"
const res = await fetch("https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.MEDIVANA_TOKEN}`,
    "X-Branch-ID": process.env.MEDIVANA_BRANCH_ID,
  },
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
import os
import requests

resp = requests.delete(
    "https://api.medivana.cloud/api/v1/clinical-documents/3f0c2a10-5b7e-4c1d-9a2e-000000000001",
    headers={
        "Authorization": f"Bearer {os.environ['MEDIVANA_TOKEN']}",
        "X-Branch-ID": os.environ["MEDIVANA_BRANCH_ID"],
    },
    timeout=30,
)
resp.raise_for_status()

Responses

204Dihapus

Errors
  • 400bad-requestCabang aktif belum dipilih (X-Branch-ID)
  • 401unauthorizedToken tidak ada, tidak valid, kedaluwarsa, atau dicabut
  • 402module-lockedModul tidak aktif di paket organisasi
  • 403forbiddenconfidential-recordScope tidak memberi izin (forbidden), rekam medis ditandai rahasia (confidential-record), atau baca-saja (read-only)
  • 404not-foundData tidak ada, milik organisasi lain, atau di luar cakupan cabang klien
  • 409conflictKonflik data atau status tidak mengizinkan aksi
  • 429rate-limitedBatas laju klien (rate_limit_per_min) terlampaui; coba lagi pada menit berikutnya