@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.
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_ERRORvsPARSE_ERRORvsREFUSAL, 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 for fanning events to OTel, Datadog, or your own collector alongside the Boundary dashboard.What happens after the event leaves your process
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 tohttps://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 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 and the runtime platform pages for the per-runtime patterns.
Safe by default
Two things make it safe to leave the SDK wired up in every environment:- Null logger in dev. When neither
apiKeynorwriteis configured,createBoundaryLoggerreturnsnull. PassingnulltodefineContract({ logger })is a no-op — the contract runs normally, no events sent, no errors. - 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 and Security & data handling.
Where to go next
Quickstart
Install and see your first event
Production observability
Decide what to capture and how to roll it out
Capture policy
Control what leaves the process
Redaction
Scrub PII before events are sent