JSON Content Checker avatar

JSON Content Checker

Pricing

from $1.00 / 1,000 results

Go to Apify Store
JSON Content Checker

JSON Content Checker

Check and validate a list of JSON URLs or API endpoints in bulk: confirm each response is valid JSON, inspect its structure, assert that required fields and values are present, and get a stable content hash to detect when a feed changes.

Pricing

from $1.00 / 1,000 results

Rating

0.0

(0)

Developer

Nicolas van Arkens

Nicolas van Arkens

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

6 days ago

Last modified

Share

Fetch any list of JSON endpoints or .json files and get a clean, structured check of each one — is it valid JSON, what's its shape, has it changed, and do the values you expect actually hold? Built for bulk: pass one URL or a thousand, and every URL becomes one check record. No API key required (optional custom headers let you check protected endpoints).

What it's for

  • API & endpoint monitoring — confirm a JSON API still returns 200 and valid JSON on a schedule, and catch the moment it breaks.
  • Change detection — every record includes a stable contentHash. Diff the hash across scheduled runs to know instantly when a feed's content changed.
  • Data-contract / schema checks — assert that required paths exist (data.results, meta.total) and that values are in range (data.total > 100, status == "ok") across many endpoints at once.
  • Bulk QA & pipelines — validate a whole list of JSON files or microservice responses in one run and export clean JSON for your dashboards.

Input

FieldTypeDescription
urlsarrayJSON endpoints / .json URLs to check. A missing scheme defaults to https://. Each URL produces one record.
requiredPathsarrayOptional. Dot/bracket paths that must exist in each document, e.g. data.results, items[0].id. Reported as present/missing with type + preview.
expectationsarrayOptional. Value assertions, e.g. status == "ok", data.total > 100, items contains "foo", meta.next missing. Each is reported as passed/failed with the actual value.
requestHeadersobjectOptional. Extra HTTP headers sent with every request (e.g. an Authorization token for protected JSON).
followRedirectsbooleanFollow redirects and check the final destination. Default true.
timeoutSecsintegerPer-request timeout in seconds. Default 30.
maxResultsintegerSafety cap on URLs checked per run. Default 1000.

Expectation syntax

One assertion per entry. The left side is a path; the right side a JSON literal (number, "string", true/false/null).

status == "ok" data.total > 100 items[0].id exists
version != "0" meta.count <= 50 results missing
title contains "Report" tags contains "news" data.ok == true

Supported operators: exists, missing / present, ==, !=, >, <, >=, <=, contains.

Output

One record per URL:

{
"url": "https://jsonplaceholder.typicode.com/todos/1",
"finalUrl": "https://jsonplaceholder.typicode.com/todos/1",
"success": true,
"statusCode": 200,
"contentType": "application/json; charset=utf-8",
"declaredJson": true,
"validJson": true,
"jsonError": null,
"rootType": "object",
"topLevelKeys": ["userId", "id", "title", "completed"],
"topLevelKeyCount": 4,
"arrayLength": null,
"itemCount": 4,
"sizeBytes": 83,
"depth": 1,
"contentHash": "sha256:8e3f...c1",
"hashMode": "canonical-json",
"pathChecks": [
{ "path": "title", "exists": true, "type": "string", "valuePreview": "\"delectus aut autem\"" }
],
"expectationResults": [
{ "expression": "id == 1", "path": "id", "operator": "==", "expected": 1, "actual": 1, "passed": true }
],
"checksPassed": 2,
"checksTotal": 2,
"allChecksPassed": true,
"fetchedAt": "2026-06-14T00:00:00+00:00",
"error": null
}

How the content hash works

For valid JSON, contentHash is a SHA-256 of the canonicalized document (keys sorted, whitespace removed), so cosmetic reordering or reformatting never registers as a change — only real content does. For non-JSON responses, the hash falls back to the raw bytes (hashMode: "raw-bytes"). Run the actor on a schedule and compare contentHash between runs to detect when a feed actually changed.

Notes

  • A non-JSON response is not an error — it's a real result: validJson is false, jsonError explains why, and the row is still returned (and charged).
  • A URL that fails to fetch (timeout, DNS error, connection refused, bad URL) is recorded with success: false and the reason — it never crashes the run and is never charged.
  • Paths support dot and bracket notation, including array indices (items[0].id) and quoted keys (data["weird.key"]).
  • topLevelKeys is capped at the first 100 keys for very wide objects; topLevelKeyCount always reflects the true total.