> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withboundary.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Overview

> Capture production contract runs for the Boundary dashboard

Local logs are enough while one developer is tuning a contract. The SDK is for production: shared traces, acceptance rates, top failing rules, retries, and alerts across real traffic.

`@withboundary/sdk` captures each contract run as a structured event, batches events in memory, and sends them to the Boundary dashboard when you configure an API key or custom sink.

```typescript theme={null}
import { defineContract } from "@withboundary/contract";
import { createBoundaryLogger } from "@withboundary/sdk";

const logger = createBoundaryLogger({
  apiKey: process.env.BOUNDARY_API_KEY,
  environment: "production",
});

const contract = defineContract({
  name: "lead-scoring",
  schema,
  rules,
  logger,
});
```

Every `contract.accept(run)` call now produces a `BoundaryLogEvent` with the outcome, attempt count, duration, failure category, repair messages, and rule attribution.

## What you get on the dashboard

* **Acceptance rate** per contract, per environment, per model — track regressions when you swap prompts or models.
* **Top failing rules** — the named rules driving most retries, with example messages.
* **Repair patterns** — what the model needed to be told to fix on the second pass.
* **Latency breakdown** — wall-clock per run including retries, broken down by attempt count.
* **Failure category mix** — `RULE_ERROR` vs `PARSE_ERROR` vs `REFUSAL`, so you know whether to tune your schema, your rules, or your prompt.
* **SDK + runtime attribution** — version + runtime stamped on every event for debugging.

## Why a contract logger and not a generic tracer

Generic observability shows you that an HTTP request was slow. Boundary shows you *which rule rejected the output and what the repair was*. Because the SDK is wired into the contract loop, it knows about attempts, repairs, and rule attribution that a generic OpenTelemetry span never sees. Use both — see [Custom sinks](/sdk/custom-sinks) for fanning events to OTel, Datadog, or your own collector alongside the Boundary dashboard.

## What happens after the event leaves your process

```mermaid theme={null}
flowchart LR
  run[contract.accept] --> evt[BoundaryLogEvent]
  evt --> queue[in-memory batcher]
  queue -- size 20 or 5s --> http[POST /v1/ingest]
  http --> dash[dashboard]
```

The SDK queues events in memory and flushes them in batches — by default whenever the queue hits 20 events or 5 seconds elapse. One flush is one HTTPS POST to `https://api.withboundary.com/v1/ingest`. The dashboard typically reflects the run within a few seconds of flush.

If the network or the backend hiccups, the transport retries with exponential backoff and a circuit breaker so a temporary outage doesn't turn into a retry storm. See [Resilience](/sdk/resilience) for the full failure model.

For short-lived runtimes (Lambda, Edge, Workers, browser), drain the queue before the process exits so events don't sit in a dead container. The SDK wires up the right lifecycle hooks per runtime — see [Shutdown](/sdk/shutdown) and the [runtime platform pages](/sdk/platforms/node) for the per-runtime patterns.

## Safe by default

Two things make it safe to leave the SDK wired up in every environment:

1. **Null logger in dev.** When neither `apiKey` nor `write` is configured, `createBoundaryLogger` returns `null`. Passing `null` to `defineContract({ logger })` is a no-op — the contract runs normally, no events sent, no errors.
2. **Conservative capture policy.** Raw LLM inputs and outputs are **off by default**. Only the run shape, repair messages, and failure attribution leave the process. Opt into raw data explicitly — see [Capture policy](/sdk/capture-policy) and [Security & data handling](/concepts/security).

## Where to go next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/sdk/quickstart">
    Install and see your first event
  </Card>

  <Card title="Production observability" icon="chart-line" href="/guides/production-observability">
    Decide what to capture and how to roll it out
  </Card>

  <Card title="Capture policy" icon="filter" href="/sdk/capture-policy">
    Control what leaves the process
  </Card>

  <Card title="Redaction" icon="eye-slash" href="/sdk/redaction">
    Scrub PII before events are sent
  </Card>
</CardGroup>

## Contract library docs

Looking for the correctness engine itself? See [Contracts](/concepts/contracts) and [Rules](/concepts/rules) in Core Concepts.
