| <article class="doc" id="doc-engineering-api" aria-hidden="true"> |
| <div class="strip"> |
| <span class="tag">Engineering</span> |
| <span class="sep">·</span> |
| <span>API Reference</span> |
| </div> |
| <h1>API Reference & Integration Spec</h1> |
| <p style="font-size:15px;color:var(--slate);margin-bottom:28px;max-width:700px;line-height:1.6;"> |
| A lightweight integration specification covering the FHIR R4 endpoints Travi consumes and exposes, authentication flow, webhook contracts, and a self-assessment checklist for hospital IT teams evaluating integration complexity. |
| </p> |
|
|
| |
| <h2 id="api-auth">Authentication</h2> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:18px 20px;margin:16px 0 24px;"> |
| <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px;"> |
| <div> |
| <div style="font-size:11px;font-weight:700;color:#38bdf8;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px;">SMART on FHIR 2.0</div> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">Travi registers as a SMART on FHIR app in the hospital's EHR App Gallery. OAuth 2.0 authorization code flow with PKCE. Scopes requested: <code>patient/*.read</code>, <code>user/Task.write</code>, <code>user/Communication.write</code>, <code>user/ClinicalImpression.write</code>.</p> |
| </div> |
| <div> |
| <div style="font-size:11px;font-weight:700;color:#38bdf8;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px;">JWT Bearer Tokens</div> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">All Travi API endpoints require a signed JWT bearer token. Tokens are scoped per hospital, expire in 1 hour, and are rotated automatically. Hospital IT teams receive a client ID and client secret during onboarding β no API keys are shared with clinical staff.</p> |
| </div> |
| <div> |
| <div style="font-size:11px;font-weight:700;color:#38bdf8;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px;">Mutual TLS (mTLS)</div> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">For hospitals that require it, Travi supports mTLS on the FHIR ingest endpoint. The hospital provides a client certificate during onboarding; Travi pins the certificate and rejects connections from any other source.</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <h2 id="api-inbound">Inbound: FHIR Resources Travi Reads</h2> |
| <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0 28px;"> |
| <table style="width:100%;border-collapse:collapse;min-width:580px;"> |
| <thead> |
| <tr style="background:var(--surface);border-bottom:2px solid var(--border);"> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">FHIR Resource</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Trigger</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Key Fields Used</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Encounter</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">status = <code>finished</code>, class = <code>IMP</code> (inpatient)</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">period.end, subject, hospitalization.dischargeDisposition</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(239,68,68,0.12);color:#f87171;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">YES</span></td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Patient</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Pulled on discharge event</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">name, telecom (phone), birthDate, address, language</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(239,68,68,0.12);color:#f87171;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">YES</span></td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">MedicationRequest</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">status = <code>active</code>, linked to Encounter</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">medication.code, dosageInstruction, dispenseRequest.numberOfRepeatsAllowed</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(239,68,68,0.12);color:#f87171;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">YES</span></td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">DocumentReference</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">type = discharge summary (LOINC 18842-5)</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">content.attachment (base64 or URL), context.encounter</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(239,68,68,0.12);color:#f87171;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">YES</span></td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Appointment</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">status = <code>booked</code>, linked to Patient</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">start, end, participant, serviceType</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">OPTIONAL</span></td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Observation</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">category = vital-signs or laboratory, last 30 days</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">code (LOINC), valueQuantity, effectiveDateTime</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">OPTIONAL</span></td> |
| </tr> |
| <tr> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Condition</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">clinicalStatus = <code>active</code>, linked to Patient</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">code (ICD-10), severity, onsetDateTime</td> |
| <td style="padding:10px 14px;"><span style="background:rgba(245,158,11,0.12);color:#fbbf24;font-size:11px;font-weight:700;padding:2px 8px;border-radius:4px;">OPTIONAL</span></td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
|
|
| |
| <h2 id="api-outbound">Outbound: FHIR Resources Travi Writes</h2> |
| <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0 28px;"> |
| <table style="width:100%;border-collapse:collapse;min-width:580px;"> |
| <thead> |
| <tr style="background:var(--surface);border-bottom:2px solid var(--border);"> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">FHIR Resource</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Purpose</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Trigger</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Frequency</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Task</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Care plan task status (completed, in-progress, failed)</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Patient SMS response or daily batch</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Daily or on event</td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Communication</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Log of all patient-Travi SMS interactions</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Each SMS sent or received</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Real-time</td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">ClinicalImpression</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">AI-generated risk assessment with score and rationale</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Risk score threshold crossed or daily</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Daily + on escalation</td> |
| </tr> |
| <tr> |
| <td style="padding:10px 14px;font-size:13px;font-weight:600;color:var(--ink);font-family:monospace;">Flag</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">High-risk patient alert visible in EHR patient banner</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Escalation engine fires</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">On escalation only</td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
|
|
| |
| <h2 id="api-webhooks">Webhook Contract</h2> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:18px 20px;margin:16px 0 24px;"> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0 0 14px;">Travi exposes a single inbound webhook endpoint for EHR systems that push rather than allow polling:</p> |
| <pre style="background:rgba(0,0,0,0.3);border:1px solid var(--border);border-radius:8px;padding:14px 16px;overflow-x:auto;margin:0 0 14px;"><code style="font-size:12px;color:#e2e8f0;font-family:'JetBrains Mono',monospace;">POST https://api.travi.ai/v1/fhir/webhook |
| Authorization: Bearer <hospital_jwt> |
| Content-Type: application/fhir+json |
| X-Travi-Signature: sha256=<hmac_signature> |
|
|
| { |
| "resourceType": "Bundle", |
| "type": "transaction", |
| "entry": [ |
| { "resource": { "resourceType": "Encounter", ... } }, |
| { "resource": { "resourceType": "Patient", ... } } |
| ] |
| }</code></pre> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">All webhook payloads are HMAC-SHA256 signed using the hospital's shared secret. Travi validates the signature before processing. Idempotency key: <code>Encounter.id</code> β duplicate discharge events for the same encounter are deduplicated automatically. Response: <code>202 Accepted</code> within 200ms; processing is async.</p> |
| </div> |
|
|
| |
| <h2 id="api-analytics">Analytics API (Hospital Read-Only)</h2> |
| <div style="overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0 28px;"> |
| <table style="width:100%;border-collapse:collapse;min-width:540px;"> |
| <thead> |
| <tr style="background:var(--surface);border-bottom:2px solid var(--border);"> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Endpoint</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Returns</th> |
| <th style="padding:10px 14px;text-align:left;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);">Auth</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:12.5px;font-family:monospace;color:var(--ink);">GET /v1/analytics/readmissions</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">30-day readmission rate by cohort, DRG, and month</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Hospital admin JWT</td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:12.5px;font-family:monospace;color:var(--ink);">GET /v1/analytics/adherence</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Medication fill rate, appointment attendance, task completion by cohort</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Hospital admin JWT</td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);"> |
| <td style="padding:10px 14px;font-size:12.5px;font-family:monospace;color:var(--ink);">GET /v1/analytics/hrrp</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Projected HRRP penalty reduction and estimated dollar savings</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Hospital admin JWT</td> |
| </tr> |
| <tr style="border-bottom:1px solid var(--border);background:rgba(255,255,255,0.015);"> |
| <td style="padding:10px 14px;font-size:12.5px;font-family:monospace;color:var(--ink);">GET /v1/analytics/tcm-billing</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">TCM-eligible encounters, billed vs. unbilled, CPT code breakdown</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Hospital admin JWT</td> |
| </tr> |
| <tr> |
| <td style="padding:10px 14px;font-size:12.5px;font-family:monospace;color:var(--ink);">GET /v1/patients/{id}/timeline</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Full 30-day task and interaction timeline for a single patient</td> |
| <td style="padding:10px 14px;font-size:13px;color:var(--slate);">Care coordinator JWT (own cohort only)</td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
|
|
| |
| <h2 id="api-checklist">Hospital IT Self-Assessment Checklist</h2> |
| <p style="font-size:13.5px;color:var(--slate);margin:8px 0 16px;line-height:1.6;">Use this checklist to estimate integration complexity before the first call with Travi's integration team. All "YES" answers indicate a standard 6β8 week integration. Each "NO" adds 1β3 weeks.</p> |
| <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;margin-bottom:28px;"> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">FHIR R4 endpoint available</div><div style="font-size:12px;color:var(--slate);">EHR exposes a FHIR R4 API (Epic FHIR, Oracle FHIR, or equivalent)</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">SMART on FHIR app registration supported</div><div style="font-size:12px;color:var(--slate);">IT team can register a third-party SMART app in the EHR app gallery</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">ADT events accessible via FHIR Subscription or webhook</div><div style="font-size:12px;color:var(--slate);">Discharge events can be pushed or polled in near-real-time</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">Discharge summaries in DocumentReference</div><div style="font-size:12px;color:var(--slate);">Discharge summary text accessible as FHIR DocumentReference (LOINC 18842-5)</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">Task resource write-back permitted</div><div style="font-size:12px;color:var(--slate);">Third-party apps can write Task, Communication, and ClinicalImpression resources back to the EHR</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">Patient phone numbers in telecom field</div><div style="font-size:12px;color:var(--slate);">Patient.telecom contains a mobile phone number for SMS delivery</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">BAA can be executed with Travi</div><div style="font-size:12px;color:var(--slate);">Legal and compliance team can sign a Business Associate Agreement before go-live</div></div> |
| </div> |
| <div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 14px;display:flex;align-items:flex-start;gap:10px;"> |
| <span style="font-size:16px;flex-shrink:0;">β</span> |
| <div><div style="font-size:12.5px;font-weight:600;color:var(--ink);margin-bottom:2px;">Sandbox / test environment available</div><div style="font-size:12px;color:var(--slate);">EHR has a non-production sandbox with synthetic patient data for integration testing</div></div> |
| </div> |
| </div> |
|
|
| <div style="background:color-mix(in srgb,#0ea5e9 8%,var(--surface));border:1px solid color-mix(in srgb,#0ea5e9 30%,var(--border));border-radius:10px;padding:16px 20px;"> |
| <div style="font-size:11px;font-weight:700;color:#38bdf8;letter-spacing:.08em;text-transform:uppercase;margin-bottom:8px;">Integration Support</div> |
| <p style="font-size:13px;color:var(--slate);line-height:1.6;margin:0;">Travi provides a dedicated integration engineer for every pilot and contract customer. The integration engineer handles SMART app registration, data mapping, UAT coordination, and go-live monitoring. A sandbox environment with synthetic patient data is available for testing before any production data is accessed. Full integration documentation is available under NDA.</p> |
| </div> |
|
|
| <p style="margin-top:20px;font-size:13px;color:var(--slate);"> |
| <strong>See also:</strong> |
| <a href="#doc-engineering-dataflow" style="color:var(--accent);text-decoration:none;" onclick="showDoc('doc-engineering-dataflow')">FHIR R4 Data Flow</a> β architecture diagram showing how these resources move through the pipeline, and |
| <a href="#doc-engineering-security" style="color:var(--accent);text-decoration:none;" onclick="showDoc('doc-engineering-security')">Security Architecture</a> β for PHI handling and compliance details. |
| </p> |
| </article> |
|
|