Blue Banana

Keragon connector

The Blue Banana EHR connector in Keragon holds one of your API keys: its actions call the FHIR API and its triggers register webhook subscriptions.

Every write — from a workflow, the API, the MCP server or the clinician workspace — fires the same subscriptions. Schemas are in the API reference; quotas under Limits.

1 · Connect

  1. Create a named API key on /account. The Playground key has a lower rate limit.
  2. In Keragon: Authentications → Create new → Blue Banana EHR, paste the key, save.
  3. Everything runs in the key owner's tenant: tenant in trigger payloads, the X-EHR-Tenant-Resolved response header.

2 · Triggers

  • Publishing a workflow calls POST /api/subscriptions with Keragon's signal URL as the http destination; unpublishing deletes it.
  • Each enabled trigger uses one subscription from the tenant quota.
  • List them with GET /api/subscriptions or the MCP tool list_webhook_subscriptions.
  • Payloads: criteria.matched for write triggers, template.fired for timed ones — fields in Webhooks · Payload.
ComponentSubscription triggerNotes
Patient createdcriteria · Patient · meta.versionId = '1'Every new Patient in your tenant, whatever wrote it.
Patient updatedcriteria · Patient · meta.versionId != '1'Payload adds data.previous and data.changes for branching on what changed.
Appointment createdcriteria · Appointment · meta.versionId = '1'Patient is data.resource.participant[0].actor.reference (Patient/<id>).
Appointment updatedcriteria · Appointment · meta.versionId != '1'Any change, including status transitions.
Before appointment startstemplate · appointment_reminder · offsetMinutesOnce per appointment at start − offset. The connector offers 30, 60 or 1440 minutes; for another lead time register the subscription yourself (§5).

3 · Actions

Paths are relative to https://bluebananaehr.com/api/fhir/r4. Writes count against the tenant write quota and fire subscriptions like any API write.

ComponentRequestNotes
Get patientGET /Patient/{id}The raw FHIR Patient.
Get patientsGET /Patient?family=&given=&name=&birthdate=&gender=&identifier=&_lastUpdated=Name searches are prefix matches on each name part. For phone, email, _count or _offset, use an HTTP step.
Get patient chartGET /Patient/{id}/$everythingEvery resource in the patient compartment. Can be large.
Get appointmentGET /Appointment/{id}—
Get appointmentsGET /Appointment?date=&status=&patient=&practitioner=&_lastUpdated=For patient details in the same call, add _include=Appointment:patient in an HTTP step.
Create appointmentPOST /AppointmentInputs: patient, status, start, end, description, duration, practitioner.
Create patientPOST /PatientFamily and given name required; gender, birth date, phone, email and address optional.
Update patientPUT /Patient/{id}Replaces the whole record: blank inputs clear fields. Run Get patient first and pass every field, or PATCH from an HTTP step.
Update appointmentPUT /Appointment/{id}Replaces the whole record, like Update patient.
Delete appointmentDELETE /Appointment/{id}To cancel instead, PATCH { "status": "cancelled" } from an HTTP step.
Create clinical documentPOST /DocumentReferenceHosted URL or Base64. Fires note.created. A document with docStatus: final (HTTP step) fires note.signed.
Create observationPOST /ObservationLOINC code plus a numeric or text value.

4 · Configuration notes

  • Ids, not references. Actions take a bare id (1a44bf5d-…). Triggers give references (Patient/1a44bf5d-…). Write actions accept either, since the API collapses Patient/Patient/… to Patient/…; Get actions need the bare id.
  • Blank optional inputs are safe. The API drops null properties on every write. A blank required field is still a 400.
  • Update actions replace. Read first and send everything back, or PATCH from an HTTP step (§6).
  • Keep appointment text Latin-1 (e.g. -, not an em dash) so the appointment pickers in Update and Delete appointment load.
  • Timestamps are UTC, YYYY-MM-DDTHH:mm:ssZ. Dates are YYYY-MM-DD.
  • Synthetic data only. Every resource carries http://bluebananaehr.com/synthetic-data = true. Never route it into a real clinical workflow.

5 · More triggers: register a subscription

Create a Keragon Webhook trigger, then register a subscription pointing at its URL (with curl or an HTTP step). This is what the connector does on publish.

curl -X POST https://bluebananaehr.com/api/subscriptions \
  -H "Authorization: Bearer bb_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Appointment cancelled → Keragon",
    "trigger": { "kind": "event", "events": ["appointment.cancelled"] },
    "destination": { "kind": "http", "url": "https://webhooks.us-1.keragon.com/…" }
  }'

One event trigger can list several of the 47 named events. Fields and ranges for every kind: Webhooks · Trigger kinds. To check a subscription fires before wiring Keragon, point it at https://bluebananaehr.com/api/webhooks/echo.

ComponentSubscription triggerNotes
Appointment booked / cancelled / rescheduled / completed / no-showevent · appointment.booked | .cancelled | .rescheduled | .completed | .no_showStatus events fire when the status becomes that value.
Patient arrived / checked inevent · appointment.arrived | appointment.checked_inFired by front-desk check-in in /app or a status PATCH.
Form submittedevent · form.submittedA completed QuestionnaireResponse.
Lab result / note signed / encounter finishedevent · lab_result.created | lab_result.final | note.signed | encounter.finished—
Inbox task / order / referral / prescription / insurance / claim / charge / invoice / paymentevent · task.created | order.created | referral.created | medication.prescribed | coverage.* | claim.* | charge.created | invoice.* | payment.receivedFired by the matching FHIR write.
Appointment reminder, any lead timetemplate · appointment_reminder · offsetMinutes—
No-show (timed)template · appointment_no_show · offsetMinutesAfter start, only if still booked.
Patient birthday / every day at / crontemplate · patient_birthday | daily_at · hourUtc; cron · expressionOne delivery per patient for birthdays.
Any resource writecriteria · resourceType, interactions, changed, fhirpathAny of the 43 resource types.

6 · Do more with an HTTP step

Keragon's HTTP request step reaches the whole API. Send Authorization: Bearer bb_… and, with a body, Content-Type: application/json. FHIR paths are relative to https://bluebananaehr.com/api/fhir/r4; /api/… paths to https://bluebananaehr.com.

ComponentRequestNotes
Search / read / create / delete any resourceGET /{type}?… · GET /{type}/{id} · POST /{type} · DELETE /{type}/{id}Any of the 43 resource types.
Partial updatePATCH /{type}/{id}application/merge-patch+json: only the fields you send change; null removes a field. JSON Patch (application/json-patch+json) also works.
Find available slotsGET /Appointment/$find?practitioner=&start=&end=&duration=Free Slots as a Bundle. Default: next 7 days, 30 minutes. Pass any returned id to Create appointment as the Slot ID.
Cancel / reschedule / check in / check out / no-showPATCH /Appointment/{id} { status } (+ start, end to reschedule)Each fires the matching appointment.* event.
Providers / visit types / locationsGET /Practitioner?name= · GET /HealthcareService · GET /Location?name=Visit types: New Patient 45, Follow Up 20, Annual Physical 30, Sick Visit 15, Telehealth 20. Locations: Cambridge, Boston, Telehealth.
Send a form / read responses / submitPOST /api/forms/links · GET /QuestionnaireResponse?patient= · POST /api/forms/submitLinks are signed and valid 30 days. Submissions write a QuestionnaireResponse.
Create / complete inbox taskPOST /Task · PATCH /Task/{id} { "status": "completed" }Category in code.coding[0], system http://bluebananaehr.com/inbox-category: message, refill-request, result-review, general. Shows in /app/inbox.
Check insurance eligibilityPOST /api/eligibility/$check { patient_id, coverage_id?, payer_id?, member_id? }Deterministic mock 270/271 response.
Clinical writesPOST /ServiceRequest · /MedicationRequest · /AllergyIntolerance · /Condition · /Encounter · GET /DiagnosticReportStandard FHIR R4 shapes.
BillingPOST /ChargeItem · /Invoice · /PaymentReconciliation · GET /Claim?patient=—
Webhook delivery logGET /api/subscriptions/{id}/deliveriesStatus code, duration and error per attempt.

7 · Verify a workflow end to end

  1. Publish, then confirm the subscription: GET /api/subscriptions.
  2. Cause the event: book an appointment in /app/schedule, through the API, or through the MCP server (its write tools report which triggers fired).
  3. Check delivery: GET /api/subscriptions/{id}/deliveries. A 2xx means Keragon accepted it.
  4. Check the effect: the run in Keragon, and the resource in /app or via GET /{type}/{id}.

For graded, repeatable checks, use the testing scenarios.