BedKoi API for hospital software
Connected to BedKoi, a hospital's own software (its HMS) keeps the free-bed counts current by itself, and requests for a bed reach the software directly. This guide is for the software's developers.
This guide as a PDF:বাংলা (PDF)English (PDF)
Getting started
- The hospital's admin signs in to the BedKoi panel and makes an API key on the “Connect software” page. The key is shown once; keep it secret.
- Send the key with every request, in the X-Api-Key header. Every address starts with:
https://api.bedkoi.com/v1 - Fetch your hospital's facilities first, then send counts.
curl https://api.bedkoi.com/v1/partner/hospital \
-H "X-Api-Key: bk_live_…"Endpoints
GET/partner/hospitalYour hospital and its facilities: ids, kinds, totals and free countsPUT/partner/availabilitySend free-bed countsPOST/partner/availability/confirmNothing changed: every count is still rightGET/partner/bookingsBookings (status=PENDING, CONFIRMED, open or closed)GET/partner/bookings/{id}One bookingPOST/partner/bookings/{id}/confirmKeep the bed (holdMinutes: 15 to 720, 120 by default)POST/partner/bookings/{id}/declineDecline (reason)POST/partner/bookings/{id}/admitThe patient camePOST/partner/bookings/{id}/cancelCancel (the bed is free again)
Sending counts
Name each facility by its id, or by facility (its kind) and variant. Counted kinds take available; yes/no kinds take isAvailable. A count sent again unchanged still counts as “checked just now”, so send at least every 30 minutes even when nothing changed, or the counts show as old. Change totals and prices in the panel. With dryRun: true, nothing is saved and the answer says what would change.
curl -X PUT https://api.bedkoi.com/v1/partner/availability \
-H "X-Api-Key: bk_live_…" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "facility": "icu", "available": 3 },
{ "facility": "cabin", "variant": "single-ac", "available": 7 },
{ "facility": "oxygen", "isAvailable": true }
]
}'Facility kinds (facility)
icuIntensive Care Unit · counted: availableccuCoronary Care Unit · counted: availablehduHigh Dependency Unit · counted: availablenicuNeonatal ICU · counted: availablepicuPaediatric ICU · counted: availablescanuSpecial Care Newborn Unit · counted: availablecabinCabin · counted: availableroomRoom · counted: availablegeneral_wardGeneral ward bed · counted: availableisolationIsolation / dengue ward · counted: availableventilatorVentilator · counted: availabledialysisDialysis · counted: availableoxygenOxygen supply · yes/no: isAvailableblood_bankBlood bank / platelets · yes/no: isAvailabledengue_testDengue test (NS1 / CBC) · yes/no: isAvailableemergencyEmergency department · yes/no: isAvailable
Bookings
When a family asks for a bed, the request is PENDING; with no answer in 30 minutes it runs out by itself. Confirming takes one off the free count and texts the family.
curl -X POST https://api.bedkoi.com/v1/partner/bookings/<id>/confirm \
-H "X-Api-Key: bk_live_…" \
-H "Content-Type: application/json" \
-d '{ "holdMinutes": 120, "note": "Come to the ICU desk, 3rd floor" }'Booking news (webhooks)
Give an https address in the panel and BedKoi POSTs each booking's news there, with the whole booking. Without a 2xx answer it tries 5 more times, over about 15 minutes.
Events
booking.createdSomeone asked for a bed (answer it)booking.confirmedThe bed is keptbooking.declinedThe request was declinedbooking.admittedThe patient was admittedbooking.cancelledCancelled (by the family or the hospital)booking.expiredNo answer in time, or the hold ran outping“Send a test” in the panel
POST https://your-hms.example.com/bedkoi
X-BedKoi-Event: booking.created
X-BedKoi-Delivery: 01a1…
X-BedKoi-Timestamp: 1760603400
X-BedKoi-Signature: v1=5d41…
{
"event": "booking.created",
"occurredAt": "2026-10-16T08:30:00.000Z",
"by": "family",
"viaPartner": false,
"booking": {
"id": "01a1…",
"reference": "BK7Q2XD",
"status": "PENDING",
"hospitalFacilityId": "01a0…",
"facility": { "key": "icu", "shortEn": "ICU", "shortBn": "আইসিইউ" },
"patientName": "…",
"patientAge": 58,
"phone": "+8801…",
"answerBy": "2026-10-16T09:00:00.000Z"
}
}Check the signature
X-BedKoi-Signature is v1= followed by HMAC-SHA256(secret, timestamp + "." + body), with the timestamp in X-BedKoi-Timestamp. Drop a message whose signature doesn't match or that is more than 5 minutes old. The same message can arrive twice: X-BedKoi-Delivery tells them apart.
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto"
function fromBedKoi(rawBody, headers, secret) {
const ts = headers["x-bedkoi-timestamp"]
const sent = headers["x-bedkoi-signature"] ?? ""
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false
const expected =
"v1=" + createHmac("sha256", secret).update(ts + "." + rawBody).digest("hex")
return (
sent.length === expected.length &&
timingSafeEqual(Buffer.from(sent), Buffer.from(expected))
)
}<?php
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_BEDKOI_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_BEDKOI_SIGNATURE'] ?? '';
$expected = 'v1=' . hash_hmac('sha256', $ts . '.' . $raw, getenv('BEDKOI_WEBHOOK_SECRET'));
if (abs(time() - (int) $ts) > 300 || !hash_equals($expected, $sig)) {
http_response_code(401);
exit;
}
$event = json_decode($raw, true);
http_response_code(200);Errors
400What you sent isn't right; the message says why.401No key, or a wrong or revoked one (api_key_missing, api_key_invalid).404No such booking at your hospital.409The booking already changed (booking_closed), or no bed is free (no_bed).429More than 120 requests a minute; try again shortly.
Need help?
Write to [email protected]