> For the complete documentation index, see [llms.txt](https://docs.tryterra.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tryterra.co/developer-tools/example-apps/terra-dispatch.md).

# Terra Dispatch

A white-label diagnostics storefront with an operations console behind it, built on the [Vantage API](https://docs.tryterra.co/vantage-api/overview). It covers the full kit lifecycle: browse a catalog, place an order, activate a kit, track fulfilment, and deliver results with the acknowledgment step Vantage requires.

It runs against the hosted sandbox, with no cloud accounts to set up. Without credentials it starts in demo mode on captured sandbox data.

```bash
npm create tryterra-app -- --template vantage-web-app
cd my-app && npm install && npm run dev
```

`/shop` is the storefront your end users would see. `/ops` is your team's console: analytics, orders, lifecycle simulation, the results queue, and a webhook inbox. The switch between them is a demo device, and the example deliberately ships no auth framework.

## What it demonstrates

* Catalog browse and curation, plus [`AT_HOME` and `GO_TO_LAB` ordering](https://docs.tryterra.co/vantage-api/test-collection-methods) with draw-site lookup
* Kit activation, both hosted and programmatic
* [Signed webhooks](https://docs.tryterra.co/vantage-api/webhooks) with verification, an inbox, and delivery-outcome debugging
* Order tracking with full status history
* [FHIR result parsing](https://docs.tryterra.co/vantage-api/results) and display
* The mandatory [results acknowledgment flow](https://docs.tryterra.co/vantage-api/acknowledging-results) and escalations
* [Sandbox lifecycle simulation](https://docs.tryterra.co/vantage-api/working-with-sandbox), to drive an order through every state without a real kit

## Run it yourself

{% hint style="info" %}
**Prerequisites:** [Node.js](https://nodejs.org/) v20+. Demo mode needs nothing else. For the sandbox you need a Terra **Dev ID** and **API key** with Vantage access, which the Terra team enables. See [account setup](https://docs.tryterra.co/vantage-api/account-setup-and-api-keys).
{% endhint %}

{% stepper %}
{% step %}

#### Start in demo mode

```bash
npm create tryterra-app -- --template vantage-web-app
cd my-app
npm install
npm run dev
```

The API runs on port 8787 and the SPA on 5173. Open <http://localhost:5173> for a read-only walkthrough on real captured sandbox data.
{% endstep %}

{% step %}

#### Point it at the sandbox

Copy `.env.example` to `.env` and fill in `TERRA_DEV_ID` and `TERRA_API_KEY`. You can now browse the live catalog and place sandbox orders. `npm run setup` checks your env and names every key.
{% endstep %}

{% step %}

#### Drive an order

Place an order in `/shop`, then use the **simulate** panel in `/ops` to move it through collection, lab receipt, and results. Updates arrive by polling unless you set up webhooks.
{% endstep %}

{% step %}

#### Receive webhooks

Add `TERRA_SIGNING_SECRET` to `.env`, install the [ngrok CLI](https://ngrok.com/download), then run `npm run webhook:tunnel`. It opens a tunnel, registers the URL with Vantage, and events land in `/ops/webhooks`.
{% endstep %}
{% endstepper %}

## How the integration works

`src/server/lib/vantage/` holds one capability per file, each dependency free so you can lift it into your own backend.

Webhook verification is the piece most worth copying. Vantage sends `X-Terra-Signature: t=<unix_seconds>,v1=<hex>`, where `v1` is an HMAC-SHA256 of `${t}.${rawBody}`. Three details matter: `t` is in seconds, not milliseconds; the HMAC covers the raw body, so verify before parsing JSON; and the comparison has to be constant time.

{% code title="src/server/lib/vantage/webhook-signature.ts" %}

```typescript
const nowSeconds = (opts.now ?? (() => Date.now() / 1000))();
if (Math.abs(nowSeconds - t) > (opts.toleranceSeconds ?? DEFAULT_TOLERANCE_SECONDS)) {
  return false;
}

const expected = createHmac("sha256", signingSecret)
  .update(`${t}.${rawBody}`)
  .digest("hex");

const a = Buffer.from(expected, "utf8");
const b = Buffer.from(received, "utf8");
return a.length === b.length && timingSafeEqual(a, b);
```

{% endcode %}

If you already use the `terra-api` SDK for the Unified API, its `verifyTerraWebhookSignature` covers the same scheme.

## Explore the code

<a href="https://github.com/tryterra/terra-examples/tree/main/packages/cli/templates/vantage-web-app" class="button primary" data-icon="github">View the source</a>

Includes tests over signature verification, FHIR parsing, and error triage. `AGENTS.md` carries a "copy this, not that" map.

| Path                                          | What it holds                         |
| --------------------------------------------- | ------------------------------------- |
| `src/server/lib/vantage/webhook-signature.ts` | Signature verification; start here    |
| `src/server/lib/vantage/client.ts`            | API client and typed responses        |
| `src/server/lib/vantage/orders.ts`            | Order creation and status history     |
| `src/server/lib/vantage/results.ts`           | Result retrieval and acknowledgment   |
| `src/server/lib/vantage/fhir.ts`              | FHIR parsing into displayable results |
| `src/server/lib/vantage/simulate.ts`          | Sandbox lifecycle simulation          |
| `src/server/lib/vantage/reconcile.ts`         | Reconciliation against Vantage        |
