Blue Banana

Blue Banana EHR

A sandbox EHR: FHIR R4 API, webhook triggers and an MCP server over synthetic Synthea data. Every resource carries the extension http://bluebananaehr.com/synthetic-data; there is no real PHI.

Open the API playground → (sign in once; a Playground key is minted for you)

Quickstart

  1. Sign up. A private tenant dev-<id> is created and seeded with 3 near-future Appointments, 3 Practitioners with Schedules, and open Slots.
  2. Mint an API key on /account. Copy the bb_… value; it is shown once.
  3. Read the reference patient:
    curl -H "Authorization: Bearer bb_…" \
         "https://bluebananaehr.com/api/fhir/r4/Patient/eb1f768e-226a-c047-0f2f-8331341167c2"

Auth

  • Send Authorization: Bearer bb_… on every API call. Exceptions: /api/fhir/r4/metadata, /api/webhooks/echo, /f/{token} and /api/forms/submit (the signed token is the credential).
  • The key decides the tenant. There is no tenant header or parameter.
  • Responses echo the tenant in X-EHR-Tenant-Resolved.
  • MCP clients can use OAuth instead; the access token is a new API key named MCP · <client>, listed and revocable on /account.

Limits

ScopeLimitWhen exceeded
Named API key (minted on /account)30 req/min429 with Retry-After + X-RateLimit-*
Playground key (auto-managed by /docs/api)10 req/min429 with Retry-After + X-RateLimit-*
MCP OAuth key (MCP · <client>)60 req/min429 with Retry-After
Tenant requests, all keys combined50 req/min429, no rate-limit headers
Tenant writes (create, update, patch, delete)2,000 lifetime429 until reset from /account (waiting does not reset it)
Webhook subscriptions per tenant (enabled or disabled)25429 on create
  • Successful responses carry X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset(epoch seconds) for the key's window.
  • "Reset playground data" on /accountdeletes your tenant's resources and subscriptions and resets the write counter.

Errors

Every error body is a FHIR OperationOutcome.

StatusMeaning
400Invalid JSON body, unknown or malformed search parameter, bad operation argument.
401Missing, invalid or revoked API key.
404Unknown resource type, or the resource is not visible to your tenant (never existed or deleted).
409POST with an id that already exists.
415PATCH with a content type other than the two patch types.
422The patch could not be applied to the current version.
429A rate limit or quota was hit — see Limits.

Tenant model

  • Readsmerge your tenant's overlay over the shared canonical seed pool. Your version of a resource wins.
  • Writes go to your overlay only. The canonical seed is never modified and other tenants never see your writes.
  • DELETE of a seed resource writes a tombstone in your overlay: it disappears for you and stays for everyone else. DELETE of your own resource removes it.

Writes

  • POST creates (server-assigned id unless the body has one). PUT updates, or creates at that id.
  • PATCH accepts JSON Patch (application/json-patch+json) or JSON Merge Patch (application/merge-patch+json).
  • Bodies are normalised before storage: null-valued properties are dropped, and doubled reference prefixes (Patient/Patient/123) collapse to Patient/123.
  • Every write sets meta.versionId ("1" on create, +1 per update) and meta.lastUpdated.
  • Every write fires matching webhook subscriptions, whether it came from the REST API, MCP or the clinician workspace.

Surface map

PathWhatGuide
/api/fhir/r4/*FHIR R4 CRUD + PATCH + search on 43 resource types; _include (max 5); Patient/{id}/$everything; Appointment/$find (open slots).API reference
/api/fhir/r4/metadataCapabilityStatement. No auth.Open
/api/subscriptions*Webhook subscriptions (events, FHIR criteria, timers, cron), event catalogue, per-subscription delivery log.Webhooks
/api/webhooks/echoPOST sink that answers 200 and stores nothing. Point a test subscription at it.Webhooks
/api/eligibility/$checkMock insurance eligibility check.API reference
/api/forms/links, /api/forms/submit, /f/{token}Patient forms: mint a signed 30-day link to a Questionnaire; submissions become QuestionnaireResponses. /f/{token} and submit need no key.API reference
/api/testing/*Graded test scenarios and evals for agents and workflows.Testing
/api/mcpMCP server (Streamable HTTP) for Claude, Codex and any MCP client. API key or OAuth.MCP
Keragon connectorEvery Blue Banana trigger and action in Keragon and the endpoint behind each.Keragon
/openapi.jsonOpenAPI 3.1 spec for every documented endpoint and outbound webhook.Open
/llms.txt, /llms-full.txtThe docs in llms.txt format.Open