Install MedWorks

Add to your home screen for quick access

MedWorks - Healthcare Without Borders
Clinic Connect · Developer Docs

Three ways to plug into Clinic Connect.

Use whichever integration mode fits the way your clinic already works — signed webhooks for modern EHRs, iCal feeds for calendar-driven shops, or a magic-link email + admin dashboard fallback for everyone else. Same booking events, three transports.

Booking webhook contract
Subscribe one HTTPS endpoint and we’ll POST every booking event your clinic should react to. PHI is minimized — only the data you need to staff the visit.

Events you’ll receive:

  • appointment.confirmed — patient’s appointment is confirmed and assigned to your clinic
  • appointment.reassigned — an existing appointment has been moved to your clinic (from another partner)

Future event types (appointment.cancelled, appointment.updated) are reserved and will follow the same payload shape.

Headers we send on every request:

Content-Type:           application/json
X-MedWorks-Event:       appointment.confirmed
X-MedWorks-Signature:   sha256=<hex hmac of raw body>
User-Agent:             MedWorks-ClinicConnect/1.0
headers

Sample appointment.confirmed payload:

{
  "event": "appointment.confirmed",
  "appointment_id": "a9d6f16c-1234-4f87-8b6e-aa11bb22cc33",
  "booking_number": "A9D6F16C",
  "service_type": "telemedicine",
  "country": "mexico",
  "appointment_date": "2026-06-26",
  "appointment_time": "14:00",
  "walk_in": false,
  "patient": {
    "first_name": "Jane",
    "last_name": "Lopez",
    "email": "jane.lopez@example.com",
    "phone": "+1 555 123 4567"
  },
  "reason_for_visit": "Sore throat, mild fever 38C",
  "clinic_notes_required": true,
  "language": "en",
  "timezone": "America/Mexico_City",
  "status": "confirmed",
  "timestamp": "2026-06-26T13:30:00Z"
}
json
Event names you will see:
  • appointment.confirmed   — initial confirmation
  • appointment.reassigned  — admin moved this appointment to your clinic from another

Field reference:
  • appointment_id   — stable UUID for the booking (also used in the Admin retry tool)
  • booking_number   — short 8-char code shown to patients (e.g. "A9D6F16C")
  • service_type     — telemedicine | in_clinic | dental | mental_health
  • country          — mexico | canada
  • walk_in          — true for Mexico walk-in / waiting-room bookings (appointment_time = "ASAP")
  • status           — confirmed (always confirmed when we POST appointment.* events)
  • reason_for_visit — patient-supplied free-text complaint, may be empty
  • clinic_notes_required — true when the patient asked for written clinic notes after the consult (to submit to their insurance). Deliver the notes to the patient via your usual channel; MedWorks records this on the appointment.
  • timestamp        — when MedWorks fired the webhook (ISO-8601 UTC)
text
Signature verification
Every request carries X-MedWorks-Signature: sha256=<hex>. Verify against the raw request bytes using the secret we issued you in your integration pack.
import hmac, hashlib
from fastapi import Request, HTTPException

CLINIC_WEBHOOK_SECRET = "<provided in your integration pack>"

async def verify_medworks(request: Request):
    sent = request.headers.get("X-MedWorks-Signature", "")
    body = await request.body()
    expected = "sha256=" + hmac.new(
        CLINIC_WEBHOOK_SECRET.encode(), body, hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(sent, expected):
        raise HTTPException(401, "bad signature")
python
import crypto from "node:crypto";

const CLINIC_WEBHOOK_SECRET = process.env.MW_WEBHOOK_SECRET;

export function verifyMedWorks(req) {
  const sent = req.header("X-MedWorks-Signature") || "";
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", CLINIC_WEBHOOK_SECRET)
          .update(req.rawBody)              // unparsed bytes
          .digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(sent), Buffer.from(expected))) {
    throw new Error("bad signature");
  }
}
node
Responding
Acknowledge the delivery with any 2xx response.

The appointment is already confirmed when it reaches your endpoint — there is no accept/decline step. Persist the booking in your system and return200 OK. Anything outside the 2xx range is logged as a failed delivery on the MedWorks admin side.

# MedWorks treats any 2xx as a successful delivery — your endpoint should
# acknowledge as soon as you have persisted the booking. There is no
# separate accept/decline call for appointment.* events; the appointment
# is already confirmed when it reaches you.

HTTP/1.1 200 OK
Content-Type: application/json

{ "ack": true }
http
Retry policy & idempotency

Every fire attempt is recorded in the admin Webhook Deliveries log against theappointment_id. If your endpoint returns a non-2xx (or times out after 10 seconds), MedWorks support can re-fire the same event manually from the admin console — your handler will see the same appointment_idagain, so treat it as idempotent and de-duplicate on that field.

Automatic retry / dead-letter fallback to email is on the roadmap — for now, the “Retry” button in the admin Webhook Deliveries card is the source of truth.

Common HTTP behaviour

Each webhook is a single POST attempt with a 10-second timeout. On failure, MedWorks staff can re-fire the same event from the admin Webhook Deliveries card — your handler should be idempotent onappointment_id.

  • 2xx — delivery considered successful
  • 3xx — not followed; treated as failure
  • 4xx/5xx — logged with the response body in the admin console; retry on demand
  • timeout — 10 second hard limit per attempt