Tutorial: Creating a Real-Time BPJS Claim Monitoring Dashboard for Hospitals & Clinics
T
Kembali ke Blog

Tutorial: Creating a Real-Time BPJS Claim Monitoring Dashboard for Hospitals & Clinics

Tutorial
Tim Pilar Inovasi 22 Oct 2026 6 min baca 1,341 kata 3
A technical guide to building a real-time BPJS claim monitoring dashboard: VClaim API polling, PostgreSQL normalization, KPIs, and automated WhatsApp alerts.

In many hospitals and clinics, the casemix team only finds out there are problematic claims when the monthly report is printed — usually two to three weeks after the patient is discharged. Verifiers then race against deadlines, pending files pile up, and cash flow is disrupted because payments are delayed. From experience integrating SIMRS with VClaim BPJS Kesehatan, the root cause is rarely the tariff or coding. What happens most often is delayed information: the data is already available on the BPJS server, but it is never pulled and processed into indicators that management can read every day. A real-time monitoring dashboard closes this gap — one screen that displays claim status by discharge date, the rupiah value held up, and the list of files that must be followed up today, not next month.

Mapping BPJS Claim Data Sources Worth Monitoring

Not all data needs to be pulled. For an operational dashboard, four groups of sources are sufficient. First, VClaim API version 2.0 through the endpoint Monitoring/Klaim/TglPulang/{tglAwal}/{tglAkhir}/{jenisRawat}, which returns a list of SEPs along with claim status. Second, E-Klaim 5.9 and above to see the position of files at the verifier, including INACBG codes and approved amounts. Third, SatuSehat FHIR with the Claim and ClaimResponse resources if the hospital is already connected to the national platform. Fourth, internal SIMRS data: coding results, completeness of medical summaries, and file submission status.

The frequency of data pulls determines the architecture. The VClaim monitoring endpoint is safe to call every 5–15 minutes per jenis rawat because its payload is light. Conversely, claim details per SEP should be taken on-demand when the user opens a row in the dashboard. This pattern preserves the consumer ID quota and avoids the 429 Too Many Requests rejections often experienced by type B hospitals with a volume of 400–900 SEPs per day.

What must be remembered: VClaim does not provide webhooks. All synchronization is pull-based. So, real-time here means local data that is always fresh within minutes. Redis 7 is used as a cache for raw responses, while PostgreSQL 16 stores a normalized version for fast analytical queries.

Before writing code, agree with management on metric definitions: percentage of pending claims, rupiah value held up, file aging in buckets 0–7, 8–14, and more than 14 days, as well as the top ten INACBG codes contributing to pending. Without these definitions, the dashboard will be full of numbers but will not change any decision.

Building a Backend for Data Synchronization and Normalization

The stack I use in type C hospitals and primary clinics: Node.js 20 LTS with axios 1.7 and node-cron 3.0, PostgreSQL 16, Redis 7, and Socket.IO 4.7 for pushing to the browser. If your team is PHP-based, Laravel 11 with Scheduler and Horizon gives equivalent results and is easier for hospital IT staff to maintain.

Minimal table structure: klaim(no_sep PRIMARY KEY, tgl_sep, tgl_pulang, jenis_rawat, kode_inacbg, biaya_diajukan, biaya_disetujui, status, updated_at) plus a klaim_log table for auditing status changes. Add composite indexes on (tgl_pulang, status) and (jenis_rawat, status). With 300 thousand rows of two-year data, monthly aggregate queries still finish under 200 ms.

Here is the core of the synchronization worker. Note the UPSERT pattern so the job is safe to run repeatedly:

// sync-klaim.js — Node.js 20, polling VClaim tiap 5 menit
import axios from "axios";
import { pool } from "./db.js";
import { io } from "./server.js";

const url = "/Monitoring/Klaim/TglPulang/2024-05-01/2024-05-31/2";
setInterval(async () => {
  const { data } = await axios.get(process.env.VCLAIM_BASE + url, { headers: signHeaders() });
  for (const r of data.response.klaim || []) {
    await pool.query(
      `INSERT INTO klaim(no_sep,status,biaya_diajukan) VALUES($1,$2,$3)
       ON CONFLICT(no_sep) DO UPDATE SET status=EXCLUDED.status, updated_at=now()`,
      [r.noSEP, r.statusKlaim, Number(r.biayaPengajuan)]);
  }
  io.to("casemix").emit("klaim:update", { total: rows.length, at: Date.now() });
}, 300_000);

VClaim required headers are X-cons-id, X-timestamp, and X-signature, calculated from HMAC-SHA256 over consID&timestamp using the consumer secret. Responses on VClaim 2.0 are still encrypted with AES-256-CBC using a combined key of consID + secret + timestamp, so provide a separate decryption function and test it in the sandbox before production.

Dashboard, KPI, and Alerts That Are Actually Used

For visualization there are two realistic paths. If the IT team is limited, install Metabase 0.50 directly on the claim database — 30 minutes is enough, you already get filters, and it can be scheduled to send a daily PDF to the head of casemix. If you need full control and a display integrated with SIMRS, build a frontend with Next.js 14 with Recharts 2.12 and Socket.IO for updates without refresh.

Arrange the screen into three blocks. Top block: four KPI cards (total SEP for the current month, percentage pending, rupiah value held up, average file age). Middle block: file aging chart per bucket and 30-day pending trend. Bottom block: table of top ten INACBG codes with held-up costs, clickable to see the list of SEP numbers.

Alerts are more important than charts. Send automatic notifications to WhatsApp or Telegram when a file reaches day 14 without a status change, or when the pending claim value crosses the agreed threshold (for example, Rp250 million). The implementation is one daily job at 07:00 that reads the table and then calls the WhatsApp gateway.

Also configure role-based access rights. Verifiers only need to view the files under their responsibility; casemix needs coding and INACBG data; management only needs a KPI summary. A dashboard that shows everything to everyone will be ignored within two weeks.

Best Practices

  1. Respect consumer quotas. Limit polling to 5-15 minutes per type of care, store raw responses in Redis with a TTL according to the schedule, and avoid calling per-SEP details in bulk.
  2. Always use idempotent upsert. Key on no_sep plus discharge date so that failed and re-run jobs do not duplicate data.
  3. Store daily snapshots. The klaim_snapshot table lets you calculate pending movements between days — data that cannot be reconstructed from the API after the status changes.
  4. Monitor bridging health. Record latency and error codes for each call; set up exponential backoff and notify the IT team if it fails three times in a row.
  5. Enable audit logs and retention. Every claim status change must record who and when, kept for at least 24 months for internal audit and BPJS needs.

FAQ

Can the dashboard be real-time without direct access to the BPJS database?

Yes. BPJS provides neither webhooks nor database access, so real-time means locally synchronized data every few minutes. With 5-minute polling and Socket.IO push to the browser, staff see status changes almost immediately after BPJS updates the data.

What is the minimum server cost for this implementation?

For a hospital with 500 SEPs per day, a VPS with 4 vCPUs and 8 GB RAM is sufficient to run Node.js, PostgreSQL, Redis, and Metabase. The cost ranges from Rp500 thousand to Rp1.5 million per month, far smaller than the value of claims that can be saved from delayed files.

What if the SIMRS vendor closes database access?

Request limited read access or an internal REST endpoint. The safest pattern: build a separate synchronization service that writes to its own monitoring database, so SIMRS performance is unaffected even if the job runs heavy.

May claim data be stored on your own server?

Yes, provided it meets data protection principles: encryption at rest, role-based access, and audit logs. Avoid storing full patient identities in the dashboard — SEP number, masked card number, and cost data are enough.

Building a BPJS claim monitoring dashboard is not a months-long project. With one synchronization worker, one PostgreSQL database, and one visualization tool, you can already see the value of claims held up every morning — and follow up with the right person in charge. If your hospital or clinic is preparing a VClaim or SatuSehat integration, or wants to turn piled-up SIMRS data into operational decisions, I am ready to help design the architecture through to its implementation. Send an overview of your current claim flow for an initial consultation session and technical feasibility assessment.

Related solutions by PT Pilar Inovasi Informatika (Pilar Inovasi IT products): SIMRS (Hospital Information System) BPJS & SatuSehat Integration. Need a free consultation?

Terakhir diperbarui 22 Oct 2026

Komentar

Komentar ditinjau sebelum tampil.

Belum ada komentar. Jadilah yang pertama!