# StillTrue – Freshness & Claim Verification (`oliverostech/stilltrue`) Actor

The reality-check layer for AI agents & RAG. Give it a URL and a fact: StillTrue tells you if the page is still live, if its content changed since the last check, and whether your claim still holds — with confidence and the exact evidence. You bring the URL; it remembers and detects changes.

- **URL**: https://apify.com/oliverostech/stilltrue.md
- **Developed by:** [Ricardo Oliveros](https://apify.com/oliverostech) (community)
- **Categories:** AI, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 verifications

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## StillTrue — the freshness & claim-verification layer for AI

**One line:** give StillTrue a URL (and optionally a fact you believe is true), and it tells you whether the page is **still live**, whether its content **changed since the last check**, and whether your **claim still holds** — with confidence, a change summary, and supporting evidence.

**Why it wins:** AI agents and RAG pipelines hallucinate because they act on stale data. StillTrue is the "reality check" an agent calls *before* it commits to a fact or an action. It isn't a scraper fighting anti-bot walls — you bring the URL. And the moat compounds: **every check stores a snapshot, so over time we own the change-history of the URLs the market cares about.** That can't be copied overnight.

---

### The contract (what every call returns)

```json
{
  "url": "https://en.wikipedia.org/wiki/Python_(programming_language)",
  "checked_at": "2026-06-08T14:33:42+00:00",
  "is_live": true,
  "http_status": 200,
  "first_seen": true,
  "changed_since_last_check": false,
  "changed_at": null,
  "change_magnitude": 0,
  "change_summary": null,
  "claim": "Python was created by Guido van Rossum",
  "claim_status": "supported",
  "claim_confidence": 0.64,
  "claim_evidence": "Guido van Rossum began working on Python in the late 1980s as a successor to the ABC programming language.",
  "content_hash": "3ea21d77d6338320",
  "error": null
}```

`claim_status` ∈ `supported | contradicted | unverifiable | no_claim`.
Design principle: returning **`unverifiable`** when we can't tell is a feature — a verifier you can trust beats one that guesses.

---

### Run the demo (offline, no network needed)

```bash
pip install trafilatura httpx
python demo.py
````

It serves two versions of the same product page and proves the full pipeline:
first-seen → supported, then page-changed → contradicted, while ignoring
nav/footer noise.

### Use as a library

```python
from stilltrue import check
result = check("https://example.com/product", claim="The price is $29.00")
print(result.to_dict())
```

***

### Project structure

```
stilltrue/            ## the tested core engine (558 lines)
  models.py           ## the result contract
  fetcher.py          ## HTTP layer (injectable for tests / Apify proxy)
  extractor.py        ## main-content extraction (kills false-positive diffs)
  diffing.py          ## change detection + summary
  claims.py           ## claim verification (v1 deterministic; strong on prices/numbers)
  store.py            ## snapshot store (local JSON now; Apify KVS at deploy = the moat)
  engine.py           ## orchestration: check(url, claim) -> CheckResult
demo.py               ## offline proof
src/                  ## Apify Actor entry (async, KVS-backed)
.actor/               ## Apify config (actor.json, input_schema.json)  [DRAFT — verify at deploy]
Dockerfile            ## Apify build  [DRAFT]
requirements.txt
```

***

### Roadmap to sale

- \[x] **1. Spec & wedge** — freshness + claim verification, price/number case first.
- \[x] **2. Core MVP** — engine built and tested (this package).
- \[ ] **3. Wrap** — finalize Apify Actor + MCP server; verify `.actor` config vs current docs; first deploy.
- \[ ] **4. Moat** — persist snapshots in Apify KVS; add `changes/timeline` output + "notify me when X changes" webhook.
- \[ ] **5. Pricing & packaging** — pay-per-call + free tier; write the Store listing copy.
- \[ ] **6. Distribution** — publish to Apify Store + list on MCP directories. Launch.
- \[ ] **7. Iterate** — add the optional LLM verifier to upgrade free-text claims.

### Honest limitations (v1)

- Claim verification is deterministic and strongest on **numeric/price/quantity** claims; free-text semantic claims degrade to `unverifiable` until the LLM verifier (step 7) lands.
- `.actor/` config + Dockerfile are a **deploy-ready draft** — confirm field names against current Apify docs before the first push.
- The sandbox can't fetch arbitrary sites, so the engine is proven on injected fixtures; real fetching runs on Apify (with proxies).

# Actor input Schema

## `urls` (type: `array`):

One or more web page URLs to verify. For each URL, StillTrue checks whether it is still live, whether its main content changed since the last time it was checked, and (if a claim is provided) whether that claim still holds. Use this when an AI agent or RAG pipeline needs to confirm that a web source is still valid before trusting or acting on it.

## `claim` (type: `string`):

An optional factual statement to verify against the current content of the URL(s). StillTrue returns claim\_status (supported, contradicted, or unverifiable), a confidence score, and the exact supporting evidence. Works best for numeric, price, quantity, or availability facts, e.g. 'The price is $29.00' or 'Python was created by Guido van Rossum'.

## Actor input object example

```json
{
  "urls": [
    "https://en.wikipedia.org/wiki/Python_(programming_language)"
  ],
  "claim": "Python was created by Guido van Rossum"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://en.wikipedia.org/wiki/Python_(programming_language)"
    ],
    "claim": "Python was created by Guido van Rossum"
};

// Run the Actor and wait for it to finish
const run = await client.actor("oliverostech/stilltrue").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urls": ["https://en.wikipedia.org/wiki/Python_(programming_language)"],
    "claim": "Python was created by Guido van Rossum",
}

# Run the Actor and wait for it to finish
run = client.actor("oliverostech/stilltrue").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://en.wikipedia.org/wiki/Python_(programming_language)"
  ],
  "claim": "Python was created by Guido van Rossum"
}' |
apify call oliverostech/stilltrue --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=oliverostech/stilltrue",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "StillTrue – Freshness & Claim Verification",
        "description": "The reality-check layer for AI agents & RAG. Give it a URL and a fact: StillTrue tells you if the page is still live, if its content changed since the last check, and whether your claim still holds — with confidence and the exact evidence. You bring the URL; it remembers and detects changes.",
        "version": "0.0",
        "x-build-id": "Z7xbytwYpKwbgejdq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/oliverostech~stilltrue/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-oliverostech-stilltrue",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/oliverostech~stilltrue/runs": {
            "post": {
                "operationId": "runs-sync-oliverostech-stilltrue",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/oliverostech~stilltrue/run-sync": {
            "post": {
                "operationId": "run-sync-oliverostech-stilltrue",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "URLs to verify",
                        "type": "array",
                        "description": "One or more web page URLs to verify. For each URL, StillTrue checks whether it is still live, whether its main content changed since the last time it was checked, and (if a claim is provided) whether that claim still holds. Use this when an AI agent or RAG pipeline needs to confirm that a web source is still valid before trusting or acting on it.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "claim": {
                        "title": "Claim to verify (optional)",
                        "type": "string",
                        "description": "An optional factual statement to verify against the current content of the URL(s). StillTrue returns claim_status (supported, contradicted, or unverifiable), a confidence score, and the exact supporting evidence. Works best for numeric, price, quantity, or availability facts, e.g. 'The price is $29.00' or 'Python was created by Guido van Rossum'."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
