No-Spec Vendor JSON API Response Drift Watcher avatar

No-Spec Vendor JSON API Response Drift Watcher

Pricing

from $20.00 / 1,000 run starteds

Go to Apify Store
No-Spec Vendor JSON API Response Drift Watcher

No-Spec Vendor JSON API Response Drift Watcher

Watch public JSON GET endpoints for response-shape drift without an OpenAPI spec. The Actor learns the shape from the response, compares it against a stored baseline, and reports each field-level change with a breaking flag.

Pricing

from $20.00 / 1,000 run starteds

Rating

0.0

(0)

Developer

kingii98

kingii98

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Watch public JSON GET endpoints of a third party for response-shape drift without an OpenAPI spec and without authentication.

The Actor sends one plain GET to each endpoint, learns the response shape from the body, and compares that shape against a baseline that it keeps between runs. It reports each field-level change with a JSON path, a change class, and a breaking flag. The first run creates the baseline and reports no drift.

Who this is for

The integration engineer whose product calls the public JSON endpoints of a vendor, who has no OpenAPI file for those endpoints, and who does not want to add authentication to a monitor.

What the Actor does

  1. Fetches each endpoint with one GET. No browser, no proxy, no authentication, no paid API.
  2. Infers the shape: every field gets a JSON pointer, a set of types, a nullable flag, and, when the field is a small repeated string set, an enum.
  3. Loads the baseline from the named key-value store json-api-shape-baseline.
  4. Diffs the new shape against the baseline and marks each change breaking or not.
  5. Writes one dataset record for each endpoint, one summary record, and the new baseline.

Input

Every field has a default, so a run with an empty input {} works.

FieldTypeDefaultMeaning
endpointsarray of URL stringstwo public demo endpoints1 to 25 public JSON GET URLs. No authentication.
baselineStorestringSHAPE_BASELINERecord key of the shape baseline in the named store json-api-shape-baseline.
ignorePathsarray of JSON pointers[]Pointers to ignore, for example /meta/timestamp. A pointer also ignores everything below it.
sampleDepthinteger 1–126Maximum object depth for shape inference.
arraySampleSizeinteger 1–20020Maximum number of elements read from each array.
breakingRulesarray of change classes["removed", "type-changed", "nullability-changed"]Which change classes count as breaking.
concurrencyinteger 1–255Endpoints fetched at the same time.
timeoutSecsinteger 2–12020Per-request timeout.
maxRedirectsinteger 0–205Redirect hops followed. Every hop is checked again.
maxResponseBytesinteger 1000–50000005000000Per-endpoint body cap.

JSON pointers

A pointer names one field, for example /data/user/id. All elements of one array share the token -, so /items/-/price is the price field of any element of items. ~1 stands for / inside a key, and ~0 stands for ~.

Change classes

ClassMeaningBreaking by default
addedA field that the baseline does not have.No
removedA field of the baseline that the response no longer has.Yes
type-changedThe type set of the field changed, for example integer to string.Yes
nullability-changedThe field started, or stopped, being null.Only when it started being null
enum-changedThe inferred small string set of the field changed.No

A field becomes an enum only when it is seen at least 3 times, is always a string, has at most 12 distinct values, and each value is at most 64 characters. This keeps free-form text out of the enum diff.

Output

The dataset holds one summary record and one endpoint record for each endpoint.

endpoint record: url, finalUrl, ok, reasonCode, httpStatus, bytesRead, responseTimeMs, shapeHash, baselineShapeHash, baselineStatus (created, compared or unavailable), fieldCount, shapeTruncated, changeCount, breakingCount, diffTruncated, diff, error, checkedAt. Each diff item has path, changeClass, from, to and breaking.

summary record: endpointsRequested, endpointsChecked, endpointsFailed, baselinesCreated, endpointsCompared, endpointsWithDrift, changeCount, breakingCount, changeCounts, gatePass, gateFailReasons, baselineStore, baselineKey, checkedAt.

gatePass is false when the run found a breaking change (BREAKING_CHANGE) or could not read an endpoint (ENDPOINT_UNAVAILABLE).

Reason codes

OK, HTTP_ERROR, NOT_JSON, RESPONSE_TOO_LARGE, TIMEOUT, DNS_FAIL, CONNECT_FAIL, BLOCKED_TARGET, REDIRECT_LOOP.

The run always succeeds

Drift, a failed gate, an unreachable endpoint and a body that is not JSON are results, not faults. They go into the dataset and into the run status message, and the run ends SUCCEEDED. A FAILED run means a real malfunction.

State between runs

The baseline lives in the named key-value store json-api-shape-baseline, under the record key that baselineStore gives. A named store outlives the run; the default store of a run does not. The record is written once, at the end of the run, so an aborted run leaves the previous baseline intact. An endpoint that the run could not read keeps its stored baseline.

The record holds at most 200 endpoints, and each endpoint shape holds at most 2000 fields.

Schedule it

The value of a baseline grows with the number of comparisons. Run the Actor on a schedule, for example every hour or every day, against the same baselineStore key.

Pricing (pay per event)

EventUnitCounted as
run-startedone Actor runCharged once for each run, before any endpoint is fetched. It pays for the container start and the summary write.
endpoint-checkedone endpoint fetched and shape-comparedCharged once for each endpoint whose body was read and whose shape was inferred. An endpoint that timed out, was blocked, or did not answer JSON is not charged.
drift-report-emittedone endpoint with one or more changesCharged once for each checked endpoint whose diff has at least one item.

The run never checks more endpoints than its maximum charge allows. When the limit covers fewer endpoints than the input asks for, the Actor logs a warning, checks the endpoints it can pay for, and leaves the baseline of the others as it is.

Safety limits

  • GET only, http and https only.
  • URLs with credentials, localhost targets, and hosts that resolve to a private or reserved address are rejected. Each redirect hop is checked again.
  • Bounded input (25 endpoints, 50 ignore paths), concurrency, redirects, response bytes, timeout, shape fields (2000), diff items (200), and baseline entries (200).

Development

uv sync
uv run pytest
uv run ruff check .