Skip to main content
This section is a pure reference. It holds exhaustive signatures, parameters, return values, and semantics for every public API across every Bitfab SDK. No narrative, no “how to use”, no walkthroughs. For tutorials and getting started, see the individual SDK guides: TypeScript, Python, Ruby, Go.

Pages

Instrumentation Primitives

The client exposes three instrumentation primitives, not just spans. A span is an explicit boundary you write yourself. A trace records a root plus every first-party call beneath it, with no decorators on those calls. A node applies trace-owned policy (name, type, capture, replay mocking) to one call the trace discovered, and never creates a span or trace on its own. Subtree capture is experimental. TypeScript needs a compatible @bitfab/sdk/transform adapter and Python needs 3.12 or newer. Without them the root span still records and descendants are skipped.

Trace Seeding

Seeding writes a replayable trace from a case you already hold, so replay has something to select before production has produced a trace for it. A seeded trace carries ingestion_type: seeded and no database pin, so a database branch is refused for it. Seeding records its one call whether capture is on or off, so a seeding script can run against a capture-off client and record exactly the calls it seeds and nothing else. A run-seeded trace has a full recorded subtree, so replay mocking works on it as it does on a captured trace. A case-seeded trace (TypeScript only) has no child spans, so there is nothing recorded to mock. See the TypeScript and Python guides.

Datasets

Every SDK exposes the dataset operations the Bitfab MCP tools give a coding agent. Scripts and CI jobs use them to build or maintain datasets with no agent in the loop. All four namespaces cover the same ten operations over the same HTTP routes. These semantics hold across all four SDKs.
  • save is an upsert. It reports whether it created the dataset.
  • Adds are idempotent and accept 1 to 100 ids.
  • An id from outside the organization, or under another trace function, comes back as skipped rather than failing the call.
  • Removing a trace drops its membership and never deletes the trace.
  • A grader re-run waits up to 90 seconds by default. Pass an option to return immediately instead.
  • A dataset id from another organization is a 404.
See Datasets. Every SDK can search the authenticated organization’s traces by caller metadata or by trace name. Caller metadata matches exactly, a name matches either by its words in order or by substring, and all of it is case-insensitive. Multiple filters use AND semantics, at least one is required, and results are cursor-paginated.

Assertions and verdicts

An assertion says what a trace SHOULD do the next time it is replayed. A verdict says how a run that already happened turned out. Every SDK exposes both, so a replay process can read what the case was supposed to do, judge its own run, and write the verdict back with no coding agent in the loop. These semantics hold across all four SDKs.
  • Assertions are written against the original trace. A replay with none of its own reads its original’s assertions, naming that trace in inheritedFrom.
  • Saving with an entry’s id edits that assertion in place.
  • saveAssertionsAll / save_assertions_all takes one update per trace, so covering many traces is one request in one transaction. A rejected batch writes nothing. The singular delegates to it.
  • A field omitted from that save keeps its previous value.
  • Each assertion that carries new text is checked against the writing rules after it is saved. When it breaks one (two claims in one, a condition, a value pointed at instead of stated, an id from the recorded run, wording with no clear pass line), one rewritten assertion replaces it in place, usually within a minute. The save returns as soon as the text is saved, with rewrite.status pending on each assertion being checked and not_checked on the rest. Read the result later from the assertion reads, where each assertion carries its latest rewrite: rewritten, unchanged, check_failed (a check that cannot run, or has not finished 15 minutes after the save), or still pending, with the text you sent, what changed, and any other claim the sent text bundled under separateAssertions. Those were not saved, so save each as its own assertion. Skip the rewrite to save text exactly as sent. Every assertion in a batch is checked.
  • Editing an assertion never changes its original author, which is always the API key’s user.
  • A verdict is keyed by traceId, or by originalTraceId plus the experiment ID and attempt for a replay.
  • skip withholds a verdict for a crashed or punctured attempt, and for an assertion whose target could not be resolved. A FAIL in either case would read as a behavior regression rather than a check that never ran.
Same HTTP routes as the MCP tools.

Replay execution and results

Every SDK returns a common set of fields on each replay result.
  • The replayed output and the original output.
  • Distinct trace-code and replay-setup errors.
  • Duration and token comparisons.
  • Source lineage.
  • Database branch metadata.

Framework Integrations

Per-framework signatures (handlers, processors, wrappers) are documented in the Frameworks section. Language-specific signatures are mirrored in each SDK reference’s Framework Integrations subsection.

Invariants Across SDKs

Behavior that is guaranteed to match across all SDKs:

Common Span Types

Every SDK accepts the same enum for span type:
See Span Types for full semantics.