bridge · v1

Sandwich Pipe

A single signed webhook for care data. Agencies, EHRs, and home-health platforms push structured events at Sandwich Pipe — visits, notes, medications, incidents — and Sandwich lights up the right loved-one record for the right family in real time. HMAC-signed, institution-scoped, forward-compatible.

What it is

Sandwich Pipe is the private-link layer between care-data producers and Sandwich's family-facing app. Think of it as Plaid for caregiving: agencies, EHRs, and home-health platforms push structured events at Sandwich Pipe, and Sandwich lights up the right loved-one record for the right family in real time.

Sandwich Soft agencies don't need to integrate. If you're running Sandwich Soft, Sandwich Pipe is already wired into clock-in and clock-out — just toggle family-share on a client to start streaming. The integration spec below is for outside partners (other agency platforms, EHRs, hospital discharge systems) who want to push events into Sandwich.
About the URL: the canonical partner-facing endpoint is api.joinsandwich.com/sandwichpipe/v1/events. The api. subdomain is being deployed; while it's being set up, sandbox partners receive a Cloud Run *.run.app URL during onboarding. Code against the canonical URL — we'll route DNS to the right backend before you go live. Earlier drafts of the docs referenced pipe.joinsandwich.com and ingest.joinsandwich.com; both have been retired.

Why a pipe

  • Neutral shape. One event schema — institution_id, subject_ref, event_type, payload — lets us onboard any partner without redesigning the app.
  • Signed and replayable. Every request carries X-SandwichPipe-Signature: sha256=…, computed over the raw body with a per-partner secret. Replays are cheap; forgeries are not.
  • Fire-and-forget on the partner side. Partners never block their own workflow waiting on Sandwich. If Sandwich Pipe is down, events are queued and retried with exponential backoff.
  • Family-controlled visibility. Events flow only when the loved one's family-share is on. Partners don't need to know who can see what — Sandwich enforces it on the receiving side.

Which providers fit this lane?

Sandwich Pipe is a push-style webhook ingest. It’s the right lane for any provider that can sign and POST events when something happens on their side. It’s not the right lane for portals that families log into themselves — those need a different shape (see below). Three lanes, by category:

Sandwich Pipe (this page)
Home-care agencies (clock-in / clock-out, observations, med passes), modern care platforms with webhook support, EHR or scheduling vendors that can sign HMAC POSTs. Anyone running Sandwich Soft is already on this lane — no integration work needed; just toggle family-share per client.
FHIR & patient-portal pull (roadmap)
MyChart, Epic, Cerner / Oracle Health, athenahealth patient portals, Apple Health Records — these expose data via OAuth-based pull (typically FHIR R4). Sandwich plans a separate lane for these, with per-loved-one consent and token management. They will land alongside Pipe events in the family timeline but go through a different connector pattern, not this webhook spec.
Family Inbox (today’s catch-all)
For any provider Sandwich does not have a direct integration with — primary-care offices, specialists, pharmacies, hospital discharge desks, attorneys — each loved one gets a private email address. Families forward provider mail to it and every sibling sees the same inbox. See the Family Inbox docs.

Quick test: does the provider make data available by sending it to you when it changes, or only by letting the family log in to view it? If they push, the Pipe is the right lane. If they only let the family log in, that’s patient-portal pull (FHIR roadmap). If they only send email, that’s the Family Inbox.

Event envelope

POST https://api.joinsandwich.com/sandwichpipe/v1/eventsjson
{
  "institution_id": "sandwichsoft-sunrise-home-care",
  "subject_ref":    "client_8c1f",
  "event_type":     "visit_ended",
  "occurred_at":    "2026-04-16T21:04:00Z",
  "payload": {
    "caregiver_id":      "caregiver_maria_r",
    "actual_end":        "2026-04-16T21:04:00Z",
    "duration_minutes":  92
  }
}

Field reference:

institution_id
Stable identifier for your organization. Issued by Sandwich during partner onboarding.
subject_ref
Your internal ID for the client. Sandwich uses this to map to the right loved-one record. Stable across events for a given client.
event_type
One of the v1 event types listed below. Forward-compatible — additional types may appear; clients should ignore unknown ones.
occurred_at
ISO 8601 timestamp for when the event actually happened (not when you sent it).
payload
Event-specific data. Schema varies by event_type — see Event types below.

Signing requests

Compute HMAC-SHA256(raw_body, partner_secret) and send the hex digest prefixed with sha256=. Sandwich verifies in constant time and rejects anything older than 5 minutes (clock-skew tolerant).

request headershttp
POST /sandwichpipe/v1/events HTTP/1.1
Host: api.joinsandwich.com
Content-Type: application/json
X-SandwichPipe-Institution: sandwichsoft-sunrise-home-care
X-SandwichPipe-Signature: sha256=4f8a9b2e…
X-SandwichPipe-Timestamp: 2026-04-16T21:04:01Z
signing — pseudocodets
const sig = "sha256=" + hmacSha256Hex(secret, rawBody);
headers["X-SandwichPipe-Signature"]   = sig;
headers["X-SandwichPipe-Institution"] = institutionId;
headers["X-SandwichPipe-Timestamp"]   = new Date().toISOString();

Per-partner secrets are issued at onboarding and rotated quarterly. A second secret window is provided during rotation so you can roll keys without dropped events.

Event types (v1)

visit_started
A caregiver clocked in at a client's home. Payload: caregiver_id, scheduled_start, actual_start, optional location.
visit_ended
Clock-out. Payload: caregiver_id, actual_end, duration_minutes.
note_added
A caregiver observation was logged. Payload: caregiver_id, note_text, optional structured_summary.
med_administered
A medication dose was administered. Payload: medication_name, dose_amount, dose_unit, administered_by, optional scheduled_at.
vital_recorded
A vital sign was recorded. Payload: vital_type, value, unit, recorded_by, optional secondary_value.

Future event types will be added without breaking changes. Partners should send unknown types as new ones become available; Sandwich will accept and forward to families based on family-share configuration.

Family share

Family share is opt-in per client. An agency using Sandwich Soft toggles family-share on a client record, which provisions a per-client shared secret and starts forwarding that client's events to Sandwich Pipe. Toggle it off and events stop at the agency boundary — no events ever cross into the family app, and prior data is purged on request.

For outside partners, family-share is established by the agency that owns the client relationship. Sandwich will not display events to a family unless the agency has affirmatively opted that client in. This keeps the partner's compliance posture clean — you forward events to Sandwich Pipe, and Sandwich enforces the family-side authorization.

What it can & can’t do

Sandwich Pipe handles:

  • Signed, partner-pushed events about clients whose family-share is on.
  • Five core event types — visit start/end, observations, medications administered, vitals recorded — with room for partner-specific extensions in the payload.
  • Idempotency — duplicate events with the same partner-side identifier are de-duplicated before they reach the family timeline.
  • Replay-safe retries with exponential backoff if Sandwich Pipe is briefly unavailable.

Sandwich Pipe does not:

  • Pull data on its own. If a partner doesn’t POST it, it doesn’t exist. There is no scraper, no polling, no portal-login impersonation.
  • Authenticate end-users. Partners authenticate themselves with a per-partner secret. The family side is authenticated separately by Sandwich.
  • Bridge MyChart, Epic, or other patient portals. Those are read-by-portal-login, not push, and need a different connector pattern (FHIR — on the roadmap).
  • Replace clinical systems. Sandwich is the family-visible layer. Partners’ own clinical systems remain the source of truth.
  • Cross caregivers. Family-share is opt-in per client. An agency turning off family-share stops the data flow immediately.

Errors & retries

Sandwich Pipe responds with one of these statuses. Partners should treat 5xx as retriable with exponential backoff and 4xx as terminal (fix the request and resend, but don't retry the original).

202 Accepted
Event was queued. The response body returns event_id for your audit log.
400 Bad Request
Body could not be parsed, required field missing, or occurred_at not ISO 8601. Fix the request and resend.
401 Unauthorized
Signature verification failed or timestamp older than 5 minutes. Check the secret and clock skew.
403 Forbidden
Institution does not have an active integration. Check with Sandwich ops if this appears.
404 Not Found
No mapping exists for the subject_ref. The agency hasn't opted that client in to family-share, or the subject was deleted. Treat as terminal — do not retry.
429 Too Many Requests
Rate limit exceeded. Backoff and retry per the Retry-After header.
5xx Server Error
Sandwich temporary issue. Retry with exponential backoff (recommended: 1s, 2s, 4s, 8s, 16s, 32s, then drop after ~5min total).

Becoming a partner

Sandwich Soft agencies get Sandwich Pipe for free — it's wired into clock-in and clock-out. Outside partners (EHRs, hospital discharge systems, other agency platforms) can email hello@joinsandwich.com to start the onboarding conversation.

What you'll need:

  • A signed Business Associate Agreement (BAA) — Sandwich will provide a template.
  • A list of institution_id namespaces you want issued (one per tenant on your platform if you're multi-tenant).
  • A short security review on your end — we'll run one too — confirming the receiving system handles redacted PHI per HIPAA.

Sandbox secrets are typically issued within a week of the security review.

Looking for the rest of the stack? MCP · Sandwich Soft · All docs