Lewati ke isi

Referensi API

Pasien

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

OpenAPI 3.1 · versi 1.1.0 · 127 operasi · 30 event webhook

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

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.

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Parameter

Parameter GET /patients
NamaLokasiTipeKeterangan
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

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 200
Skema 200
NamaTipeKeterangan
itemswajibarray<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
Galat
  • 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.

Scope
patients:write
Izin RBAC
patient.write
Modul
frontoffice
X-Branch-ID
Wajib X-Branch-ID

Parameter

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

Body permintaan application/json

Body permintaan POST /patients
NamaTipeKeterangan
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
}

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 201
Skema 201
NamaTipeKeterangan
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
Galat
  • 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.

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Parameter

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

Contoh kode

Bahasa contoh kode
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()

Respons

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
    }
  ]
}
Skema 200
Skema 200
NamaTipeKeterangan
itemswajibarray<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
Galat
  • 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.

Scope
patients:write
Izin RBAC
patient.write
Modul
frontoffice

Body permintaan application/json

Body permintaan POST /patients/lookup-nik
NamaTipeKeterangan
nikwajibstring
{
  "nik": "9999010101900001"
}

Contoh kode

Bahasa contoh kode
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()

Respons

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"
    }
  }
}
Skema 200
Skema 200
NamaTipeKeterangan
localobject | null
satusehatobject
satusehat.statusfound | not_found | unavailable | skipped
satusehat.patientobject | null
Galat
  • 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

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Contoh kode

Bahasa contoh kode
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()

Respons

200Pengaturan nomor RMapplication/json

{
  "prefix": "RM-",
  "pad_length": 6,
  "last_value": 122,
  "example": "RM-000123"
}
Skema 200
Skema 200
NamaTipeKeterangan
prefixstring
pad_lengthinteger
last_valueinteger
examplestring
Galat
  • 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.

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Parameter

Parameter GET /patients/{id}
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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.

Scope
patients:write
Izin RBAC
patient.write
Modul
frontoffice
X-Branch-ID
Wajib X-Branch-ID

Parameter

Parameter PATCH /patients/{id}
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
X-Branch-IDwajibheaderstring (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.

Body permintaan application/json

Body permintaan PATCH /patients/{id}
NamaTipeKeterangan
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": ""
}

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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.

Scope
patients:write
Izin RBAC
patient.write
Modul
frontoffice
X-Branch-ID
Wajib X-Branch-ID

Parameter

Parameter POST /patients/{id}/satusehat-lookup
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
X-Branch-IDwajibheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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).

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Parameter

Parameter GET /patients/{id}/merges
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)

Contoh kode

Bahasa contoh kode
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()

Respons

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"
    }
  ]
}
Skema 200
Skema 200
NamaTipeKeterangan
itemswajibarray<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)
Galat
  • 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.

Scope
patients:readpatients:write(cukup salah satu)
Izin RBAC
patient.read
Modul
frontoffice

Parameter

Parameter GET /patients/{id}/consents
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)

Contoh kode

Bahasa contoh kode
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()

Respons

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
    }
  ]
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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}/allergiesTautan ke operasi ini: Alergi pasien

Alergi pasien

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

Scope
encounters:readpatients:readpatients:write(cukup salah satu)
Izin RBAC
encounter.read · patient.read
Modul
rme

Parameter

Parameter GET /patients/{id}/allergies
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
include_resolvedqueryboolean

Contoh kode

Bahasa contoh kode
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()

Respons

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
    }
  ]
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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.

Scope
encounters:read
Izin RBAC
encounter.read
Modul
rme

Parameter

Parameter GET /patients/{id}/history-summary
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
encountersqueryintegerJumlah kunjungan terakhir

Contoh kode

Bahasa contoh kode
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()

Respons

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"
      }
    ]
  }
}
Skema 200
Skema 200
NamaTipeKeterangan
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
Galat
  • 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)

Scope
encounters:readpatients:write(cukup salah satu)
Izin RBAC
encounter.read · patient.write
Modul
frontoffice

Parameter

Parameter GET /patients/{id}/documents
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)

Contoh kode

Bahasa contoh kode
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()

Respons

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"
    }
  ]
}
Skema 200
Skema 200
NamaTipeKeterangan
itemswajibarray<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
Galat
  • 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.

Scope
patients:write
Izin RBAC
encounter.write · patient.write
Modul
frontoffice
X-Branch-ID
Wajib X-Branch-ID

Parameter

Parameter POST /patients/{id}/documents
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
X-Branch-IDwajibheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Body permintaan multipart/form-data

Body permintaan POST /patients/{id}/documents
NamaTipeKeterangan
filewajibstring (binary)
titlestringDefault nama berkas
categorygeneral | lab_external | imaging | referral | consent | photo | identity | other
notesstring

Contoh kode

Bahasa contoh kode
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()

Respons

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"
}
Skema 201
Skema 201
NamaTipeKeterangan
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
Galat
  • 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}/downloadTautan ke operasi ini: Unduh isi dokumen klinis

Unduh isi dokumen klinis

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

Scope
encounters:readpatients:write(cukup salah satu)
Izin RBAC
encounter.read · patient.write
Modul
frontoffice

Parameter

Parameter GET /clinical-documents/{id}/download
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)

Contoh kode

Bahasa contoh kode
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

Respons

200Isi berkasapplication/octet-stream

Galat
  • 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).

Scope
patients:write
Izin RBAC
encounter.write · patient.write
Modul
frontoffice
X-Branch-ID
Wajib X-Branch-ID

Parameter

Parameter DELETE /clinical-documents/{id}
NamaLokasiTipeKeterangan
idwajibpathstring (uuid)
X-Branch-IDwajibheaderstring (uuid)Cabang aktif. Wajib kecuali klien API hanya punya satu cabang (dipakai otomatis); tanpa cabang aktif → 400.

Contoh kode

Bahasa contoh kode
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()

Respons

204Dihapus

Galat
  • 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