Skip to main content
BedKoi

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

  1. 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.
  2. Send the key with every request, in the X-Api-Key header. Every address starts with: https://api.bedkoi.com/v1
  3. 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 counts
  • PUT/partner/availabilitySend free-bed counts
  • POST/partner/availability/confirmNothing changed: every count is still right
  • GET/partner/bookingsBookings (status=PENDING, CONFIRMED, open or closed)
  • GET/partner/bookings/{id}One booking
  • POST/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 came
  • POST/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: available
  • ccuCoronary Care Unit · counted: available
  • hduHigh Dependency Unit · counted: available
  • nicuNeonatal ICU · counted: available
  • picuPaediatric ICU · counted: available
  • scanuSpecial Care Newborn Unit · counted: available
  • cabinCabin · counted: available
  • roomRoom · counted: available
  • general_wardGeneral ward bed · counted: available
  • isolationIsolation / dengue ward · counted: available
  • ventilatorVentilator · counted: available
  • dialysisDialysis · counted: available
  • oxygenOxygen supply · yes/no: isAvailable
  • blood_bankBlood bank / platelets · yes/no: isAvailable
  • dengue_testDengue test (NS1 / CBC) · yes/no: isAvailable
  • emergencyEmergency 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 kept
  • booking.declinedThe request was declined
  • booking.admittedThe patient was admitted
  • booking.cancelledCancelled (by the family or the hospital)
  • booking.expiredNo answer in time, or the hold ran out
  • ping“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]