Probezen
Catch when an API changes without going down.
GET /products → 200 OK
Yesterday: {"price": 19.99}
Today: {"price": "19.99"}
HTTP status: 200 OK
Probezen: type drift detected at price
Probezen watches the observed behavior of APIs your software depends on. It is particularly useful when you do not control the API and need to know when a successful response changes underneath your application.
See it in 10 seconds
uvx probezen demo
The demo is offline and creates no files. It runs Probezen's real inference and enforcement engine against deterministic built-in responses:
Probezen demo
Learning normal API behavior...
✓ user.id integer
✓ user.plan {"pro"}
✓ user.email present
Simulating an upstream response change...
HTTP 200 OK
DRIFT DETECTED
user.id: integer → string
user.email: required → missing
The API never went down. Its behavior changed.
How it works
- Probezen observes repeated JSON responses without storing their raw bodies.
- It proposes a small set of consistent behaviors: required fields, stable types, nullability, enum-like values, and historically nonempty arrays.
- You review and approve the proposed contract stored in
probezen.lock.json. - Future checks report when a response violates that approved behavior, even if the request still succeeds.
The contract stays with your code, produces readable Git diffs, and is never changed silently. Probezen complements existing tests and monitoring by focusing specifically on drift in external API responses.
Install
Python 3.12+ is required. Install the released CLI in an isolated environment:
uv tool install probezen
or:
pipx install probezen
pip install probezen also works. Source and contributor setup is documented in
CONTRIBUTING.md.
Monitor your first API
From the application that depends on the API:
probezen discover
probezen discover --write
probezen learn api-github-com-users-octocat
discover statically inspects supported JavaScript and TypeScript call sites and reports the
third-party host, method, normalized path, source location, confidence, safe-monitoring status,
and consumer assumptions Probezen can associate confidently. It never executes a discovered
request. --write explicitly creates a human-editable probezen.yml containing only fully
resolved GET candidates, never secrets, and refuses to overwrite an existing configuration. In
this example, the first command reports supported calls and assumptions; the second creates the
starter check named on the third line.
If discovery cannot resolve the endpoint safely, configure it through the normal manual workflow:
probezen init
probezen add github https://api.github.com/users/octocat
probezen learn github
probezen check github
That is the recommended workflow: add → learn → check.
learn collects three new observations by default, displays every candidate invariant and its
evidence, then asks before writing probezen.lock.json. Use --count 10 when you also want
enum-like and operational candidates. For a reviewed noninteractive workflow:
probezen learn github --count 10 --approve-all
The lower-level sample, infer, and approve commands remain available when you want control
over each step.
Inspect and accept intentional changes
The observed contract lives with your code. Inspect it at any time:
probezen show github
probezen show github --json
When a provider change is legitimate, Probezen never accepts it silently:
probezen update github
git diff -- probezen.lock.json
update first displays the current drift, asks for confirmation, collects fresh evidence for
that endpoint, and rewrites only its approved contract. Review the deterministic lock-file diff
before committing it. show reports both the baseline observation count and when it was learned.
Authenticated APIs
Store the environment-variable name, never the secret, in configuration:
export GITHUB_AUTH_HEADER="Bearer <token>"
probezen add private-api https://api.example.com/v1/account \
--header-env Authorization=GITHUB_AUTH_HEADER
probezen learn private-api
The environment variable contains the complete header value. Probezen supports arbitrary
non-secret headers with --header NAME=VALUE and secret or credential-like headers with
--header-env NAME=ENV_VAR. Resolved values are used only for the request; they are never written
to configuration, history, contracts, JSON output, or logs.
Diagnose configuration and missing CI variables without making a live request:
probezen doctor
CI in one step
Commit probezen.yml and probezen.lock.json, but not .probezen/. Then add:
name: Probezen
on:
pull_request:
push:
branches: [main]
schedule:
- cron: "0 */6 * * *"
permissions:
contents: read
jobs:
probezen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: HemVadgama/probezen@v1
with:
command: check
fail-on: high
env:
GITHUB_AUTH_HEADER: ${{ secrets.GITHUB_AUTH_HEADER }}
check checks every configured endpoint when no name is supplied. The compatible --all flag
remains available in generic CI:
probezen check --all
Exit codes are stable:
0: approved contract satisfied (warnings do not fail by default)1: breaking drift, or a finding at/above--fail-on2: configuration, authentication, network, or Probezen error
For machine consumers, probezen check --json emits a versioned, deterministic structure with
schema_version, health, threshold, violations, warnings, and a multi-endpoint summary. See the
stable JSON reference and
complete CI example.
probezen discover --json has a separate stable JSON reference.
What gets learned
Probezen requires repeated consistent evidence and explicit approval:
- structural candidates require at least 3 observations;
- required fields must be present in every observation and every item of an observed array;
- enum-like values require at least 10 values, no more than 8 unique short members, and low variability;
- nullability is enforced only after consistent non-null evidence;
- nonempty-array warnings apply only if every baseline observation was nonempty;
- latency and response-size warnings require 10 observations and use wide thresholds;
- changing scalar values, optional fields, and additive fields do not fail checks by default.
Nothing is enforced until it appears in the readable probezen.lock.json and you approve it.
Raw bodies are never stored; local SQLite history retains only response metadata and structural
path summaries. From a repository checkout, run the honest regression benchmark with:
python -m probezen.benchmark
See benchmarks/README.md for scope and results.
Supported drift
- HTTP status and JSON/content-type changes
- required fields disappearing
- stable JSON types changing
- historically non-null values becoming null
- small enum-like sets gaining a value
- historically nonempty arrays becoming empty
- large latency or response-size changes after sufficient evidence
Human output explains the path, expected and observed behavior, severity, why it matters, likely affected JavaScript/TypeScript code when discoverable, and the suggested action.
Limitations
- Active monitoring currently supports HTTP GET endpoints and JSON response inference.
- Discovery and code-impact analysis currently target JavaScript and TypeScript.
- Discovery is conservative and incomplete by design. V1 recognizes direct
fetch, direct Axios method calls, and Axios instances with a staticbaseURL; it does not trace arbitrary wrappers, dependency injection, generated SDKs, or deeply dynamic URLs. - Probezen cannot infer semantic business correctness;
19.99 → 99.99is invisible if the type and approved invariants remain valid. - It focuses on observed response drift; it does not provide broad request generation, complete API specification validation, or hosted availability alerting.
- Authenticated APIs require ordinary credentials supplied by your environment.
- Live checks inherit provider outages, rate limits, and response variability.
- Inference protects only conservative patterns supported by enough observations; uncertain behavior is intentionally missed rather than over-enforced.
- History is local; scheduled monitoring is ordinary CI, not a hosted scheduler.
More examples:
- Public API
- Authenticated API
- Intentional drift update
- Product fit and boundaries
- GitHub Marketplace and release guide
- Security policy
Probezen is MIT licensed and has no telemetry.
Metadata
Release files for probezen 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| probezen-1.2.0.tar.gz | 59.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| probezen-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.3 kB
Release files / probezen-1.2.0.tar.gz
| Download URL | probezen-1.2.0.tar.gz |
|---|---|
| Size | 59.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2e50798ca3e5a7fa68851399860721dca5b4fbf1f8fb321ca46bc8201452026c
|
|
BLAKE2b-256 checksum How to use checksums |
09cef852c09d99d5c94ba0b5610434d44f74d6bb838944efe0bdc9613bef3d77
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.
Transparency logRelease files / probezen-1.2.0-py3-none-any.whl
| Download URL | probezen-1.2.0-py3-none-any.whl |
|---|---|
| Size | 48.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f48a829aae81e3e15254fcac43493ddce47059ad01f9d565d9c6dd99bfd8fa12
|
|
BLAKE2b-256 checksum How to use checksums |
e2652e1b75bd9f9997009a7af56eaac95a5dd41cd8cd1eacb8c0d81fbd82cdb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.
Transparency log