Skip to main content

Quickstart Guide

Quickstart: Your First Bounded Health API Integration

Last updated: 2026-02-18

Time to complete: ~10 minutes

This guide takes you from zero to a working API integration. By the end you will have:

  1. Created an API key
  2. Made your first API call
  3. Set up a webhook subscription
  4. Verified a webhook signature

Prerequisites

  • An employer admin account on Bounded Health (sign up at /sign-up)
  • Your employer must be approved for API access
  • Node.js 18+ installed (for code examples)
  • A tool to make HTTP requests (curl, Postman, or your code)

Step 1: Create an API key

Sign in to Bounded Health as an employer admin, then create an API key:

Via the UI: Navigate to your employer dashboard → API Keys → Create Key.

Via the API (using your browser session):

bash
curl -X POST https://<YOUR_HOST>/api/employer/api-keys \
  -H "content-type: application/json" \
  -H "cookie: <YOUR_SESSION_COOKIE>" \
  -d '{
    "name": "My First Integration",
    "scopes": ["cohort:read", "export:read", "fhir:read", "webhook:manage"]
  }'

Expected response:

json
{
  "id": "clu1abc...",
  "name": "My First Integration",
  "rawKey": "mt_live_a1b2c3d4e5f6...",
  "scopes": ["cohort:read", "export:read", "fhir:read", "webhook:manage"],
  "createdAt": "2026-02-18T12:00:00.000Z"
}

⚠️ Copy rawKey now! It is shown exactly once and cannot be retrieved later. Store it in a secret manager — never commit it to source control.

Set up your environment:

bash
export MT_API_KEY="mt_live_a1b2c3d4e5f6..."
export MT_HOST="https://your-instance.Bounded Health.com"

Step 2: Make your first API call

Fetch the FHIR capability statement to verify your key works:

bash
curl -s "$MT_HOST/api/fhir/metadata" \
  -H "x-api-key: $MT_API_KEY" \
  -H "x-api-version: 2026-02-01" \
  -H "accept: application/fhir+json" | head -20

Expected response (truncated):

json
{
  "resourceType": "CapabilityStatement",
  "status": "active",
  "fhirVersion": "4.0.1",
  "format": ["application/fhir+json"],
  "rest": [...]
}

If you get an error:

StatusMeaningFix
401Key is invalid or revokedDouble-check the mt_live_ key value
403Missing scope or IP blockedAdd fhir:read scope; check IP allowlist
400Unsupported API versionUse x-api-version: 2026-02-01

Step 3: Fetch real data

Search for FHIR Patient resources in your employer tenant:

bash
curl -s "$MT_HOST/api/fhir/Patient?_count=5" \
  -H "x-api-key: $MT_API_KEY" \
  -H "x-api-version: 2026-02-01" \
  -H "accept: application/fhir+json"

Expected response:

json
{
  "resourceType": "Bundle",
  "type": "searchset",
  "total": 42,
  "entry": [
    {
      "resource": {
        "resourceType": "Patient",
        "id": "user_abc123",
        "identifier": [{ "value": "user_abc123" }],
        "telecom": [{ "system": "email", "value": "patient@example.com" }]
      }
    }
  ]
}

Node.js equivalent:

typescript
const response = await fetch(`${process.env.MT_HOST}/api/fhir/Patient?_count=5`, {
  headers: {
    "x-api-key": process.env.MT_API_KEY!,
    "x-api-version": "2026-02-01",
    "accept": "application/fhir+json",
  },
});

const bundle = await response.json();
console.log(`Found ${bundle.total} patients`);

for (const entry of bundle.entry ?? []) {
  console.log(`  Patient: ${entry.resource.id}`);
}

Step 4: Set up a webhook

Create a webhook subscription to receive real-time events:

bash
curl -X POST "$MT_HOST/api/employer/webhooks" \
  -H "x-api-key: $MT_API_KEY" \
  -H "x-api-version: 2026-02-01" \
  -H "content-type: application/json" \
  -d '{
    "url": "https://your-server.example.com/webhooks/Bounded Health",
    "events": ["cohort.uploaded", "export.ready", "simulation.completed"],
    "description": "My first webhook"
  }'

Expected response:

json
{
  "id": "whk_abc123...",
  "url": "https://your-server.example.com/webhooks/Bounded Health",
  "events": ["cohort.uploaded", "export.ready", "simulation.completed"],
  "signingSecret": "whsec_...",
  "status": "active"
}

⚠️ Copy signingSecret now! Like API keys, it is shown once. You will need it to verify webhook signatures.


Step 5: Send a test webhook

Verify your endpoint receives events correctly:

bash
curl -X POST "$MT_HOST/api/employer/webhooks/<WEBHOOK_ID>/test" \
  -H "x-api-key: $MT_API_KEY" \
  -H "x-api-version: 2026-02-01"

Expected response:

json
{
  "success": true,
  "statusCode": 200,
  "latencyMs": 142
}

Step 6: Verify webhook signatures

Every webhook delivery includes an HMAC-SHA256 signature. Always verify it before processing.

Node.js / Express handler:

typescript
import crypto from "crypto";
import express from "express";

const app = express();

// IMPORTANT: Use raw body for signature verification
app.post(
  "/webhooks/Bounded Health",
  express.raw({ type: "application/json" }),
  (req, res) => {
    const signature = req.headers["x-webhook-signature"] as string;
    const rawBody = req.body.toString("utf8");

    // Compute expected signature
    const expected = `sha256=${crypto
      .createHmac("sha256", process.env.WEBHOOK_SECRET!)
      .update(rawBody)
      .digest("hex")}`;

    // Timing-safe comparison to prevent timing attacks
    const isValid =
      signature.length === expected.length &&
      crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));

    if (!isValid) {
      console.error("Invalid webhook signature — rejecting");
      return res.status(401).send("Invalid signature");
    }

    // Parse and process the verified payload
    const event = JSON.parse(rawBody);
    console.log(`Received event: ${event.event}`, event.data);

    // Always respond 200 quickly — process async if needed
    res.status(200).send("OK");
  }
);

app.listen(3001, () => console.log("Webhook receiver running on :3001"));

Key headers to inspect:

HeaderPurpose
x-webhook-signatureHMAC-SHA256 signature for verification
x-webhook-idUnique delivery ID (use for idempotency)
x-webhook-eventEvent type (e.g., cohort.uploaded)
x-webhook-timestampISO timestamp of the event

What comes next

GoalGuide
Sync employee roster from your HRISRECIPES.md → HRIS Roster Sync
Export patient data for analyticsRECIPES.md → Bulk FHIR Export
Set up SSO with Okta or Azure ADRECIPES.md → SSO Setup
Troubleshoot errorsTROUBLESHOOTING.md
Full API key reference01-API-KEY-AUTHENTICATION.md
Full webhook reference02-OUTBOUND-WEBHOOKS.md
Full FHIR reference03-FHIR-HL7-INTEROPERABILITY.md
OpenAPI spec (machine-readable)/api/openapi