Diffy API
Snapshot + diff
SSRF guarded
Client-held state

Watch pages. Keep the tokens.

Snapshot a URL into Markdown, blocks, or a tree, then diff against client-held state. Agents get only what changed.

Markdown · blocks · treeStatic · Chromium fallbackmax_chars · 1k to 100kStateless · you store state

Snapshot a page into Markdown.

This demo posts POST /snapshot with render=static and max_chars=2000. Only example.com and datpaq.com are allowed. Chromium is not used here.

Request builder
Allowlisted URLs only. Click to run.
POST /snapshot
format: markdown · render: static · max_chars: 2000
Output preview
Live response from the API, plus the exact request to reproduce it.

Click run to snapshot the allowlisted URL with render=static.

Why Diffy API

Watch pages without rereading them.

Snapshot then diff

POST /snapshot returns Markdown, blocks, or a tree plus compact state. POST /diff returns only what changed.

Token-cheap Markdown

Readability strips chrome. max_chars truncates at block boundaries so agents stay inside a budget.

Semantic block diffs

Added, removed, and modified blocks with a change ratio. Pure reorders are not reported as changes.

SSRF on every hop

Private, loopback, and metadata destinations are blocked, including redirect hops.

Static first

render=auto tries a fast static fetch, then Chromium only when the page is script-heavy.

You hold the state

Nothing is stored server-side. Keep state and state_etag, then send previous_state on the next check.

/api/v1/diffy

Endpoints, at a glance.

Two POSTs: snapshot a page into LLM-ready content, then diff against the state you keep.
POST/api/v1/diffy/snapshot

Snapshot

Fetch a URL as markdown, blocks, or tree, plus compact client-held state.

PRIMARY
POST/api/v1/diffy/diff

Diff

Compare the live page against previous_state and return added, removed, and modified blocks.

ParameterTypeRequiredDescription
urlstringyeshttp or https URL, max 2048 chars, SSRF-guarded on every hop.
formatstringnomarkdown, blocks, or tree. Default markdown. Snapshot only.
renderstringnoauto, static, or browser. Default auto. Demo uses static.
max_charsintegernoContent cap 1000 to 100000, default 20000. Truncates at block boundaries.
include_statebooleannoInclude the diffable state object. Default true. Snapshot only.
previous_stateobjectdiffState previously returned by Diffy (schema 1). Required on POST /diff.

Error reference

Failures you can plan for.

Private destinations return BLOCKED_URL. Stale state schema returns 409.
400VALIDATION / BLOCKED_URL

Invalid body, or the destination failed SSRF policy including a blocked redirect hop.

401Authentication Error

Missing or invalid gateway API key. Send x-api-key or api_key with every request.

409STATE_SCHEMA_MISMATCH

previous_state.schema is not supported. Re-snapshot to obtain the current schema.

422FETCH_FAILED

The page could not be processed (unsupported type, too many redirects, size exceeded).

429Rate Limit Error

More than 30 requests in a 15-minute window.

503PoolSaturated

Chromium pool is at capacity. Retry-After is 5 seconds.

Example error response

{
  "success": false,
  "code": "BLOCKED_URL",
  "error": "Destination is not allowed.",
  "correlationId": "req_error123"
}

FAQ

API questions developers ask first.

Does Diffy store pages server-side?

No. The service is stateless. You keep the state object from a snapshot and send it back as previous_state on POST /diff.

When does Chromium run?

render=auto tries a fast static fetch first and falls back to headless Chromium for script-heavy pages. You can force static or browser. The live demo uses static only.

What does a matching etag mean?

If state_etag matches, nothing changed. Pure reorders of identical blocks are not reported as changes.

How do I keep snapshots small?

Set max_chars between 1,000 and 100,000 (default 20,000). Content truncates at block boundaries. Tree output also caps links, buttons, and forms.

How do I authenticate requests?

Send your Datpaq API key as an x-api-key header or an api_key query parameter. Keys are created in the Datpaq dashboard and a free tier is included.

Watch pages for a fraction of the tokens.

Snapshot once, store compact state on the client, and receive only what changed on the next check.