Reference
FAQ
Common questions about StateAnchor. For architecture details see how it works. For setup see the quick start.
What is StateAnchor?
Git-native API contract enforcement. You commit a stateanchor.yaml spec to your repo; on every push StateAnchor diffs it against the prior snapshot, runs a gate (ERR blocks the merge, WARN alerts, INFO passes), and optionally generates typed SDKs and MCP server artifacts when the gate passes.
Do I need to replace Speakeasy or Fern to use StateAnchor?
No. Gate-only mode sits on top of your existing generator -- same SDK output, with contract enforcement added. "Speakeasy builds your MCP server. StateAnchor ensures it never drifts." See gate-only mode for setup details.
How is StateAnchor different from oasdiff?
oasdiff tells you what changed. StateAnchor tells you whether it's safe to ship. StateAnchor uses oasdiff internally for its diff primitives -- the two aren't competitors. oasdiff Pro (launched April 2026) adds GitHub PR integration with 450+ rule-based checks and one-click approve/reject. StateAnchor adds the next layer: LLM-evaluated verdicts that catch semantic breaking changes that rules miss, an anergic two-signal exception ledger (dual-control, not one-click), SOC 2 compliance export, and gain margin confidence reporting on gate reliability. See the full comparison.
How is StateAnchor different from Speakeasy's contract testing?
Different questions, complementary tools. Speakeasy's contract testing (GitHub Actions, shipped Jan-Feb 2026) asks whether your schema still generates a valid SDK -- it's SDK-generation-centric. StateAnchor asks whether the change is safe to ship to all consumers -- it's spec-governance-centric. A schema can pass Speakeasy's contract testing while still containing a consumer-breaking change (a field removed, a type tightened, a required parameter added to an existing endpoint). StateAnchor catches those. See the full comparison.
What happens during the first 20 syncs before the OOD baseline is established?
The gate still evaluates and blocks normally -- the OOD (out-of-distribution) detector is the only signal that's suspended during the cold-start period. OOD novelty detection works by comparing a spec's topology signature against a reference distribution of previously-seen specs. That reference distribution doesn't exist until around 20 sync runs, so the OOD signal is suppressed for the first ~20 syncs on any new installation. The gate's LLM-evaluated verdict, ERR/WARN/INFO classification, and all rule-based detection work from sync #1. The gain margin confidence modifier also has no reference distribution until history builds -- confidence bands will be wider in early syncs. This is the same cold-start behavior as any anomaly detector in a new installation: the enforcement works immediately; the statistical confidence accumulates over time.
What's the difference between gate-only and full pipeline mode?
Gate-only: enforcement only. Bring your own generator (Speakeasy, Fern, anything). Full pipeline: StateAnchor runs the gate AND generates typed TypeScript, Python, Go SDKs plus an MCP server artifact on every passing sync. Both start free. See pricing for what each plan includes.
How does the gate decide what to block?
Three categorical lanes -- ERR always blocks (breaking changes), WARN alerts at a configurable threshold (degradations), INFO always passes (additive changes). No arbitrary score -- the lane is the verdict. See gate engine for the full classification logic.
What counts as a breaking change?
16 ERR kinds including: endpoint removed, required field added, type changed, auth scheme changed, response shape changed, enum value removed. Full list with examples at gate kinds reference.
What is the Near-Miss Ledger?
Every sync run that passed but came within one change of blocking is recorded as a near-miss. Drift that almost broke you is as important to track as drift that did. The Near-Miss Ledger surfaces these on the project cockpit so you can address accumulating risk before the gate fires.
Does StateAnchor work with GitHub Actions?
Yes -- one workflow file, two lines of config. The gate runs on every push and annotates the PR with results. See the quick start for the exact workflow to copy.
Is there a free tier?
Yes. Gate-only: free forever for unlimited gate runs. Full pipeline: free for 3 syncs/month (SDK + MCP generation). Paid plans unlock more syncs and team features. No credit card required to start. See pricing.
What languages does SDK generation support?
TypeScript, Python, Go, Rust, and PHP. The gate works for any OpenAPI-described API regardless of language -- gate-only mode has no language requirement at all.
What happens when a required parameter is added to an existing endpoint?
The gate returns ERRand blocks the merge. Adding a required parameter breaks every existing caller that doesn't send it -- those requests fail with a validation error without any code change on the consumer side. This is the required_param_added kind in the gate kinds reference. If the change is intentional (e.g., a major-version bump), file a drift exception with a reason and expiry to suppress the finding.
What is the Merkle log?
Every gate decision is appended to a public, append-only Merkle log (RFC 6962 Certificate Transparency model). You can prove any historical gate result to a third party without trusting StateAnchor's servers. Each sync run has a programmatic inclusion proof endpoint. See trust & security.
How does StateAnchor handle false positives?
Drift exceptions. You can file an exception on any change kind with a reason and expiry (max 90 days). Exceptions go through a two-signal activation model -- they don't suppress the gate until a second independent signal confirms intent (code owner ack, consumer test, or manual confirmation). The exception is recorded, signed, and auditable. See drift exceptions.
Is my API spec stored by StateAnchor?
StateAnchor stores the intermediate representation (IR) of your spec -- a structured diff, not the raw YAML. Raw spec content is processed transiently and not retained beyond the sync run. See data handling for the full retention policy.
What happens if StateAnchor is down?
By default the gate is fail-closed: if StateAnchor is unreachable, the Action exits non-zero and the push is blocked. To allow CI to continue during outages, set outage-policy: fail-open in your workflow -- the Action then passes with a soft-pass result and only local YAML validation runs.
How do I see StateAnchor's full build history?
stateanchor.dev/changelog -- every shipped item since day one, logged in full.
Is StateAnchor SOC 2 certified?
SOC 2 Type I audit is in progress. All sub-processors (Supabase, Clerk, Trigger.dev, Anthropic, Vercel) are SOC 2 Type II certified. See trust & security for the full sub-processor list and security architecture.
Billing & plans
How does billing work?
StateAnchor uses a subscription model. Gate-only plans start at $29/month (Pro) or $99/month (Team). Full pipeline plans start at $49/month. Paid plans include unlimited syncs. New accounts get 3 free sync credits to explore the product -- no time limit, no credit card required.
What happens when I run out of free credits?
Your gate continues to evaluate pushes and report results in the dashboard, but syncs stop running automatically. Upgrade to any paid plan to resume unlimited syncing.
Can I cancel my subscription?
Yes, anytime. Your access continues until the end of the billing period. No proration, no penalties.
What's the difference between Gate-Only and Full Pipeline pricing?
Gate-Only($29/$99/month) runs the breaking-change gate and exception ledger -- it works alongside any SDK generator you're already using (Speakeasy, Fern, etc.). Full Pipeline ($49/$199/month) adds TypeScript, Python, and Go SDK generation and MCP server artifact generation on each gate pass.
Do you offer trials or discounts?
Every account starts with 3 free sync credits -- enough to see the gate in action on a real repo. We don't currently offer time-based trials. For enterprise pricing ($499/month, volume discounts, SLAs), contact us at hello@stateanchor.dev.
Detection Details
How accurate is StateAnchor's detection compared to other tools?
StateAnchor's spec-diff engine detects 100% of breaking changes in our 34-scenario ground-truth corpus, with a 0% false positive rate. For comparison, we benchmarked api-smart-diff (the library underlying oasdiff) on the same corpus — it catches 65% of breaking scenarios (13/20 OpenAPI fixture pairs). The gap comes from semantic context: structural diff tools track shape changes at the JSON path level but apply conservative rules not tuned for contract enforcement. StateAnchor applies contract-specific rules: required field removals, auth scheme changes, and response type changes all block regardless of whether the structural shape technically changed. See the full scenario breakdown at /docs/compare.
Does StateAnchor catch breaking changes in response schemas, not just request schemas?
Yes. After the April 2026 spec-diff upgrade, StateAnchor distinguishes request from response context. A field removed from a response schema emits response_field_removed (ERR, score 25) — distinct from field_removed (ERR, score 30) for request fields. Response type changes emit response_field_type_changed. Response constraint relaxations (previously strict, now looser) emit response_constraints_relaxed (WARN). This context awareness reduces false positives: relaxing a response constraint is not the same severity as tightening a request constraint. See the gate kinds reference for the full list with examples.
What is the 34-scenario benchmark corpus?
We maintain a ground-truth corpus of 34 OpenAPI diff scenarios — 28 breaking changes and 6 non-breaking changes — covering auth scheme changes, field removals, type changes, constraint tightening, nested object changes, param additions, response shape changes, and oneOf/anyOf variant modifications. The corpus runs in CI on every push via a Vitest suite, ensuring regressions in detection are caught before they ship. You can see the full scenario breakdown at /docs/compare.
How does StateAnchor handle nested object schemas?
spec-diff recursively diffs nested object schemas. If a field contains sub-properties (e.g., an address object with street, city, zip), changes within those sub-properties are detected at the leaf level. A type change on address.street fires type_changed for that specific field, not a generic change on address. This recursive diffing was added in PR #313. See the gate kinds reference for the full list of kinds emitted on field-level changes.
What is the difference between field_removed and optional_field_removed?
field_removed (ERR) fires when a required field is removed from a request schema -- callers depending on sending that field will break. optional_field_removed (WARN) fires when an optional field is removed -- callers sending it may find it no longer accepted, but callers omitting it (which is valid for an optional field) are unaffected. The distinction allows gate configuration to treat optional field removal as a warning rather than an automatic block. See gate kinds reference for both kinds with examples.
Does StateAnchor detect validation constraint changes?
Yes. If a request field's constraints tighten -- minLength increased, maximum decreased, pattern added -- spec-diff emits validation_constraints_tightened (ERR). Previously-valid values may now be rejected. If constraints relax -- maximum increased, minLength decreased -- spec-diff emits constraints_relaxed (INFO), since this is an additive change. Constraint detection covers: minimum, maximum, minLength, maxLength, exclusiveMinimum, exclusiveMaximum, pattern, and multipleOf.
How does StateAnchor handle response schema changes differently from request schema changes?
spec-diff is context-aware. Removing a required field from a response schema emits response_field_removed (ERR) -- clients reading the field will encounter missing data. Removing a required field from a request schema emits field_removed (ERR). The distinction matters for gate reasoning: response changes break consumers reading data; request changes break consumers sending data. Type changes on response fields emit response_field_type_changed; on request fields, type_changed. Constraint tightening is tracked on request fields (callers' inputs are rejected); constraint relaxation on response fields is tracked as a WARN (response_constraints_relaxed) because consumers with exhaustive validation may break on unexpected values.