# Authentication
Source: https://docs.factagora.com/api-reference/authentication
How to authenticate with the Factagora API
## API Keys
All requests to the Factagora API must include an API key as a Bearer token in the `Authorization` header.
```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```
API keys follow the format `fa_...`. Get your free API key at [Settings → API Keys](https://factagora.com/en/playground/tokens).
**A default API key is issued automatically on your first sign-in to Factagora.** You can copy it from [Settings → API Keys](https://factagora.com/en/playground/tokens), or create additional keys for separate environments (e.g., development vs. production).
## Example Request
```bash cURL theme={null}
curl -X GET "https://api.factagora.com/api/v1/fact-search?q=bitcoin" \
-H "Authorization: Bearer fa_your_api_key"
```
```python Python theme={null}
import requests
response = requests.get(
"https://api.factagora.com/api/v1/fact-search",
params={"q": "bitcoin"},
headers={"Authorization": "Bearer fa_your_api_key"}
)
print(response.json())
```
```typescript TypeScript theme={null}
const response = await fetch(
"https://api.factagora.com/api/v1/fact-search?q=bitcoin",
{
headers: { Authorization: "Bearer fa_your_api_key" },
}
);
const data = await response.json();
```
## Error Responses
| Status | Error | Description |
| ------ | ---------------------- | ----------------------------------- |
| `401` | `Missing Bearer token` | `Authorization` header not provided |
| `401` | `Invalid API key` | The provided API key is not valid |
# Causality Graph
Source: https://docs.factagora.com/api-reference/best-practices/causality-graph
Best practices for Causality Graph
## Use URLs with analytical or causal content
URLs pointing to research reports, news articles, or policy documents with explicit cause-and-effect language (e.g., "leads to", "causes", "results in") produce richer and more accurate graphs.
```json theme={null}
{ "url": "https://imf.org/en/Publications/WEO" }
```
For documents you have locally, use the `/api/v1/causality-graph/file` endpoint instead.
```bash theme={null}
curl -X POST "https://api.factagora.com/api/v1/causality-graph/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@analysis.pdf"
```
## Visualize as a directed graph
The `edges` array is directional: `from` is the cause, `to` is the effect. Use this to render a DAG (directed acyclic graph) in your UI.
```javascript theme={null}
edges.forEach(edge => {
graph.addEdge(edge.from, edge.to, { label: edge.label });
});
```
## Filter isolated nodes
Nodes without any edges are likely extraction artifacts. Filter them out before rendering.
```javascript theme={null}
const connectedNodeIds = new Set([
...edges.map(e => e.from),
...edges.map(e => e.to),
]);
const filteredNodes = nodes.filter(n => connectedNodeIds.has(n.id));
```
## Combine with Timeseries
Use Causality Graph alongside [Timeseries](/api-reference/timeseries) to answer both "what happened?" and "why did it happen?".
```
Timeseries (what happened) → Causality Graph (why it happened)
```
# Deep Research
Source: https://docs.factagora.com/api-reference/best-practices/deep-research
Best practices for Deep Research
## Frame queries as research questions
Queries phrased as investigative questions produce more structured, comprehensive reports.
```bash theme={null}
# Good
{"query": "What are the economic impacts of generative AI on the labor market?"}
# Also good, topic phrase works too
{"query": "generative AI impact on labor market"}
```
## Be specific about scope
Overly broad queries return surface-level results. Narrow the scope with qualifiers like time period, geography, or industry.
```bash theme={null}
# Too broad
{"query": "climate change"}
# Better
{"query": "economic cost of climate change on Southeast Asian agriculture 2020-2025"}
```
## Use sections for structured output
The `sections` array in the response is designed for rendering structured reports. Map each section to a heading in your UI.
```javascript theme={null}
sections.forEach(section => {
renderSection(section.title, section.content);
});
```
## Cite sources in your output
Always surface the `sources` array to end users for transparency and credibility. Each source has a `title` and `url` field. Factagora internal sources link directly to verified claims or predictions.
```javascript theme={null}
sources.forEach(source => {
renderCitation(source.title, source.url);
});
```
## Use Deep Research after Fact Checker
If a claim is `UNCERTAIN`, use Deep Research to explore the context in depth before drawing conclusions.
```
Fact Checker → UNCERTAIN → Deep Research (explore context)
```
# Evidence Finder
Source: https://docs.factagora.com/api-reference/best-practices/evidence-finder
Best practices for Evidence Finder
## Use specific, declarative claims
Evidence Finder works best with concrete, specific statements rather than open-ended questions.
```bash theme={null}
# Good, specific and declarative
claim=Bitcoin price will exceed 200000 dollars in 2025
# Avoid, open-ended question
claim=Will Bitcoin hit 200k?
```
## Use stance to build balanced views
Each result includes a `stance` field indicating whether the source `SUPPORTS`, `CONTRADICTS`, or is `NEUTRAL` toward your claim. Use this to present multiple perspectives.
```json theme={null}
// Show supporting evidence
const supporting = results.filter(e => e.stance === 'SUPPORTS');
// Show contradicting evidence
const contradicting = results.filter(e => e.stance === 'CONTRADICTS');
```
## Filter by credibility score
`credibility` is an AI-generated confidence score (0–1) for how strongly a source supports or contradicts the claim, not a static measure of outlet reputation. A score above `0.8` means the source directly and clearly addresses the claim, while lower values indicate a weaker or more indirect connection. Use it to prioritize the most relevant evidence.
```json theme={null}
// Only show credibility >= 0.8
results.filter(e => e.credibility >= 0.8)
```
## Use evidence types to understand the source
| Type | Description |
| ------------ | ---------------------------------------------------------------------------------- |
| `FACT_CHECK` | Verified claims and predictions from the Factagora database with AI agent verdicts |
| `DATA` | Government statistics, research datasets, official reports |
| `EXPERT` | Academic papers, think tank reports, peer-reviewed journals |
| `NEWS` | Recent news coverage from reputable outlets |
`FACT_CHECK` sources link directly to Factagora claims or predictions at `https://factagora.ai/claims/{uuid}` or `https://factagora.ai/predictions/{uuid}`.
## Combine with Fact Checker or Deep Research
Use Evidence Finder to gather raw supporting/contradicting sources, then feed the claim into Fact Checker for a verdict or Deep Research for a full report.
```
Evidence Finder (multi-angle sources + stance) → Fact Checker (TRUE/FALSE/UNCERTAIN verdict)
Evidence Finder (quick citations) → Deep Research (full structured report)
```
# Fact Checker
Source: https://docs.factagora.com/api-reference/best-practices/fact-checker
Best practices for Fact Checker
## Submit one claim at a time
The API verifies a single claim per request. For multiple claims, send them as separate requests.
```bash theme={null}
# Good, one specific claim
{"claim": "The global average temperature has risen by 1.1°C since pre-industrial times."}
# Avoid, multiple claims in one request
{"claim": "Temperature has risen 1.1°C and CO2 levels are at record highs."}
```
## Be specific and factual
Vague or opinionated statements produce lower confidence scores. Frame the claim as a concrete, verifiable statement.
```bash theme={null}
# Good, specific and verifiable
{"claim": "Apple became the first US company to reach a $3 trillion market cap in 2022."}
# Avoid, too vague
{"claim": "Apple is very successful."}
```
## Use confidence score as a filter
A `confidence` below `0.5` means the evidence is insufficient. Treat these as `UNCERTAIN` regardless of the verdict label.
```json theme={null}
{
"verdict": "TRUE",
"confidence": 0.3
}
```
A confidence of `0.3` or below should be surfaced to users as `UNCERTAIN`, not `TRUE`.
## Expected response time
The endpoint performs a database search and an AI inference step. Expect **4–7 seconds** per request depending on the number of related items found.
## Combine with Evidence Finder
After receiving a verdict, use [Evidence Finder](/api-reference/evidence-finder) to surface broader supporting sources beyond what Factagora has indexed.
```
Fact Checker → verdict → Evidence Finder (for additional supporting sources)
```
# Fact Search
Source: https://docs.factagora.com/api-reference/best-practices/fact-search
Best practices for Fact Search
## Use focused keywords
Short, specific keywords return better results than full sentences.
```bash theme={null}
# Good
q=bitcoin+ETF+approval
# Avoid
q=what+is+the+latest+news+about+bitcoin+ETF+approval
```
## Filter by language and country
If your use case targets a specific region, always pass `language` and `country` to reduce noise.
```bash theme={null}
# Korean news only
q=삼성전자&language=korean&country=KR
# US English news only
q=federal+reserve&language=english&country=US
```
## Use `sortBy=date` for breaking news
When recency matters more than relevance, switch the sort order.
```bash theme={null}
q=earthquake&sortBy=date×pan=24h
```
## Limit results for performance
The default `limit` is 10. For real-time use cases, reduce it to 3–5 to keep response times low.
```bash theme={null}
q=nvidia&limit=3
```
## Combine with Fact Checker
Use Fact Search to surface recent articles, then pass the key claims to [Fact Checker](/api-reference/fact-checker) for verification.
```
Fact Search → extract claim from article → Fact Checker
```
# DeepStamp
Source: https://docs.factagora.com/api-reference/best-practices/fingerprint
Best practices for DeepStamp's Embed & Detect APIs
**DeepStamp is the product name; the API paths still say `fingerprint`.** Endpoints are `/api/v1/fingerprint/embed` and `/api/v1/fingerprint/detect`, and responses return `fingerprint_id`. There is no `/api/v1/deepstamp/*` endpoint.
## Embed at publish time, not retroactively
Watermark content as early as possible, ideally at the moment of publication or distribution. Embedding after content has already circulated reduces the provenance window.
```json theme={null}
{
"content": "...",
"content_type": "news",
"metadata": {
"published_at": "2024-03-15T09:00:00Z",
"source_id": "article_98765"
}
}
```
## Always store the fingerprint\_id
The `fingerprint_id` returned by `/embed` is your key for retrieval and detection. Store it alongside your internal document record.
```json theme={null}
{
"internal_id": "article_98765",
"fingerprint_id": "fp_l1p8OPCwGhvu"
}
```
## Distribute watermarked\_content, not the original
The `watermarked_content` in the response contains invisible zero-width Unicode characters. Distribute this version instead of the original, it is visually identical but carries the cryptographic watermark that enables detection.
## Choose the right content\_type
Scoring weights are automatically tuned per content type. Choosing the correct type improves detection accuracy:
| Content type | Entity weight | Time weight | Causal weight | Best for |
| ---------------- | ------------- | ----------- | ------------- | ----------------------------------------- |
| `news` (default) | 0.5 | 0.2 | 0.3 | News articles, press releases |
| `legal` | 0.3 | 0.1 | 0.6 | Legal documents, contracts, court filings |
| `report` | 0.4 | 0.3 | 0.3 | Research reports, analysis, whitepapers |
| `internal` | 0.5 | 0.2 | 0.3 | Internal memos, communications |
## Use custom weights for specialized use cases
Override the default weights when your detection scenario is unusual. For example, if you only care about whether the same entities appear (regardless of causal structure):
```json theme={null}
{
"content": "...",
"weights": { "entity": 0.8, "time": 0.1, "causal": 0.1 }
}
```
Weights must sum to `1.0`. The weights used are echoed back in `meta.weights` for auditability.
## Use filters to narrow detection scope
Pass `filters` to reduce the candidate set and speed up detection:
```json theme={null}
{
"content": "...",
"filters": {
"author_id": "journalist_042",
"date_from": "2024-01-01",
"date_to": "2024-12-31",
"content_type": "news"
}
}
```
## Understand the two detection layers
Detection runs two independent checks, use both signals together:
| Layer | How it works | What it proves |
| --------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| **Watermark** | Extracts invisible zero-width bits and correlates them against stored seeds | Near-certain provenance, the exact watermarked content was used |
| **TKG Jaccard** | Compares entities, timelines, and argument chains using word-level fuzzy matching | Semantic similarity, the same story, even if completely rewritten |
Check `watermark_match` and `watermark_correlation` on each match to see if the watermark layer fired. The `meta.watermark_detected` field tells you whether any watermark was found in the input at all.
## Interpret confidence scores carefully
| Score range | Interpretation | Recommended action |
| ----------- | -------------- | ---------------------------------------- |
| 0.8 – 1.0 | Strong match | High confidence, safe to automate |
| 0.5 – 0.8 | Partial match | Review the `overlap` lists before acting |
| 0.3 – 0.5 | Weak signal | Likely coincidental overlap |
| Below 0.3 | Filtered out | Not returned (below default `min_score`) |
When `watermark_match: true`, the match is near-certain regardless of the TKG score.
## Audit matches with overlap lists
Every match includes `overlap.entities`, `overlap.timeseries`, and `overlap.relations`, the specific items shared between the query and the candidate. Use these to explain *why* two articles matched, not just *that* they matched.
```json theme={null}
{
"overlap": {
"entities": ["bank of korea", "interest rate"],
"timeseries": ["2024-03-15"],
"relations": ["bank of korea|raises|interest rate"]
}
}
```
## Use fingerprint\_id for re-scoring
If you've already embedded content and want to re-score it against the registry (e.g., periodically checking for new matches), pass the `fingerprint_id` directly instead of the content:
```json theme={null}
{
"fingerprint_id": "fp_l1p8OPCwGhvu"
}
```
This skips content extraction and uses the stored TKG snapshot, making it faster and idempotent.
## Combine with other Factagora APIs
| Workflow | APIs | Purpose |
| -------------------------- | -------------------------------------------------------------------- | ------------------------- |
| Was my content reused? | DeepStamp Detect | Provenance tracking |
| Was it reused accurately? | DeepStamp Detect + [Fact Checker](/api-reference/fact-checker) | Detect misrepresentation |
| What changed in the story? | DeepStamp Detect + [Causality Graph](/api-reference/causality-graph) | Track narrative evolution |
# Ingest
Source: https://docs.factagora.com/api-reference/best-practices/ingest
Best practices for the Ingest API
## Use URLs for public articles
The fastest way to ingest is to pass a URL directly. The API fetches and parses the content automatically using Mozilla Readability.
```json theme={null}
{ "url": "https://www.reuters.com/article/..." }
```
## Use the file endpoint for internal documents
For PDFs, reports, or markdown documents, use the `/api/v1/ingest/file` endpoint. Supports PDF, Markdown, and TXT files.
```bash theme={null}
curl -X POST "https://api.factagora.com/api/v1/ingest/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@quarterly-report.pdf" \
-F "visibility=private"
```
## Keep private data private
Ingested content defaults to `private`. Only set `visibility=public` if the content is already publicly available. Private content is only searchable by the token owner.
## Search your knowledge graph after ingesting
After ingesting, use `fact-search` with `source=ingest` to semantically search across your knowledge graph. See [Searching Ingested Content](/api-reference/ingest#searching-ingested-content) for the request format.
## Use the ingest\_source\_id to trace back
The `ingest_source_id` in the response links every extracted claim and prediction back to its source document. Store it if you need provenance tracking.
## Combine with Fact Checker
After ingesting claims, pass them to [Fact Checker](/api-reference/fact-checker) to verify them against live news.
```
Ingest (extract claims) → Fact Checker (verify each claim)
```
# Timeseries
Source: https://docs.factagora.com/api-reference/best-practices/timeseries
Best practices for Timeseries
## Works with any time-based content
Timeseries organizes content chronologically, it works on both event-based content (news articles, reports, announcements) and structured data pages. Each data point captures what happened at a specific point in time as a text description, not a numeric value.
```json theme={null}
{ "timestamp": "2023-03", "label": "Italy temporarily bans ChatGPT over privacy concerns" }
{ "timestamp": "2024-08", "label": "EU AI Act enters into force" }
```
## Timestamps are pre-normalized
Timestamps are always returned in one of three formats: `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`. You can sort and compare them safely as strings.
```javascript theme={null}
// Timestamps are already normalized, no conversion needed
dataPoints.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
```
## Use URLs pointing to content-rich pages
URLs pointing to articles, reports, or data pages with clear time-based information yield the best results. Sparse or navigation-only pages may return fewer data points.
```json theme={null}
{ "url": "https://en.wikipedia.org/wiki/Timeline_of_artificial_intelligence" }
```
## Use the file endpoint for PDFs and reports
For annual reports, whitepapers, or research documents, upload the file directly with the `/api/v1/timeseries/file` endpoint rather than passing a URL.
```bash theme={null}
curl -X POST "https://api.factagora.com/api/v1/timeseries/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@annual-report-2024.pdf"
```
## Combine with Causality Graph
After extracting a timeseries, use [Causality Graph](/api-reference/causality-graph) to understand the causal relationships behind the sequence of events.
```
Timeseries (event sequence) → Causality Graph (why did each event happen?)
```
# Causality Graph
Source: https://docs.factagora.com/api-reference/causality-graph
POST https://api.factagora.com/api/v1/causality-graph
Analyze cause-and-effect relationships from a given URL or file, and return a structured causality graph.
Analyze cause-and-effect relationships from a URL or uploaded file (PDF, Markdown). Returns nodes (concepts/events) and directed edges (causal relationships) that can be used to visualize cause-and-effect chains.
## Endpoints
| Method | Path | Input |
| ------ | ------------------------------ | --------------------------------- |
| `POST` | `/api/v1/causality-graph` | JSON body with `url` |
| `POST` | `/api/v1/causality-graph/file` | `multipart/form-data` with `file` |
***
## POST /api/v1/causality-graph
### Request Body
URL of the page or document to extract causal relationships from.
Language for the extracted node and edge labels (e.g. `english`, `korean`). Node `id` values remain in English/ASCII for graph integrity. Defaults to English.
Maximum number of nodes to extract. Range: 1–100. Edge count is naturally bounded by node count.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/causality-graph" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/economic-analysis"}'
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/causality-graph",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"url": "https://example.com/economic-analysis"},
)
graph = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/causality-graph", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com/economic-analysis" }),
});
const graph = await resp.json();
```
***
## POST /api/v1/causality-graph/file
### Request Body (multipart/form-data)
PDF or Markdown file to extract causal relationships from.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/causality-graph/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@analysis.pdf"
```
***
## Response
List of concept or event nodes in the graph.
Unique node identifier
Human-readable label for the node
List of directed causal relationships between nodes.
Source node ID (cause)
Target node ID (effect)
Optional description of the relationship
Total number of nodes
Total number of edges
Response time in milliseconds
```json 200 theme={null}
{
"nodes": [
{ "id": "n1", "label": "Rising interest rates" },
{ "id": "n2", "label": "Lower consumer spending" },
{ "id": "n3", "label": "Reduced GDP growth" },
{ "id": "n4", "label": "Higher unemployment" }
],
"edges": [
{ "from": "n1", "to": "n2", "label": "causes" },
{ "from": "n2", "to": "n3", "label": "leads to" },
{ "from": "n3", "to": "n4", "label": "leads to" }
],
"meta": {
"total_nodes": 4,
"total_edges": 3,
"executionTimeMs": 640
}
}
```
# Claim Detection
Source: https://docs.factagora.com/api-reference/claims-detect
POST https://api.factagora.com/api/v1/claims/detect
Find the verifiable factual claims inside a block of text.
Given a block of text, such as the body of an article, this returns the statements in it that can actually be fact-checked. Opinions, questions, and rhetoric are left out.
Each detected claim carries a verbatim excerpt copied from your input, never a paraphrase, so you can locate it in the original text by substring match and highlight it.
Pair this with [Fact Checker](/api-reference/fact-checker): detect first, then verify each claim you care about.
## Request Body
The text to scan. Maximum 20,000 characters.
Source URL of the text. Recorded with the result.
Title of the source page. Recorded with the result.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/claims/detect" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"text": "The European Central Bank raised interest rates by 25 basis points on Thursday. Analysts think this was overdue. Eurozone inflation has stayed above 2% for eleven straight months.",
"url": "https://example.com/ecb-article",
"title": "ECB raises rates again"
}'
```
## Response
The detected claims, in the order they appear in the text.
Identifier for this detected claim
The sentence copied verbatim from your input. Use this for substring matching against the original text
The same sentence with pronouns and references resolved from the surrounding context, so it stands on its own. Send this to Fact Checker rather than `text`. Identical to `text` when there was nothing to resolve
One of `FACTUAL`, `STATISTICAL`, `QUOTE`, `EVENT`
Short label for the claim
Longer description of what is being claimed
How confident the detector is that this is a checkable claim, 0 to 1
Topic category of the claim
```json 200 theme={null}
{
"claims": [
{
"id": "ck_01H8X2",
"text": "The European Central Bank raised interest rates by 25 basis points on Thursday.",
"normalized_claim": "The European Central Bank raised interest rates by 25 basis points on Thursday.",
"claim_type": "EVENT",
"title": "ECB raised rates by 25bp",
"description": "A 25 basis point rate increase by the European Central Bank.",
"confidence": 0.94,
"category": "economy"
},
{
"id": "ck_01H8X3",
"text": "Eurozone inflation has stayed above 2% for eleven straight months.",
"normalized_claim": "Eurozone inflation has stayed above 2% for eleven straight months.",
"claim_type": "STATISTICAL",
"title": "Eurozone inflation above 2% for 11 months",
"description": "Inflation in the eurozone remained over the 2% target for eleven consecutive months.",
"confidence": 0.88,
"category": "economy"
}
]
}
```
The sentence "Analysts think this was overdue" is not returned. It is an opinion, so there is nothing to verify.
# Crawl
Source: https://docs.factagora.com/api-reference/crawl
POST https://api.factagora.com/api/v1/crawl
Fetch a URL and get its main content back as clean Markdown.
Fetch a page and get the article body back as Markdown, with the boilerplate stripped out. Useful when you want to run your own processing over a page before sending anything to the other APIs.
By default you also get the title, author, published date, and description. Pass a `prompt` to extract something specific instead.
## Request Body
URL to crawl.
Custom extraction instruction. When provided, the response returns plain text matching your instruction and the metadata fields come back as `null`.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/crawl" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.reuters.com/business/example-article"}'
```
## Response
The URL that was crawled.
Page title. `null` when `prompt` was provided.
The extracted content. Markdown by default, or plain text matching your instruction when `prompt` was provided.
Published date in ISO 8601. `null` when `prompt` was provided, or when the page has no date.
Author. `null` when `prompt` was provided, or when the page has no author.
Page description. `null` when `prompt` was provided.
When the page was fetched, in ISO 8601.
```json 200 theme={null}
{
"url": "https://www.reuters.com/business/example-article",
"title": "ECB raises rates by 25 basis points",
"markdown": "The European Central Bank raised interest rates by 25 basis points on Thursday...",
"publishedAt": "2026-06-15T08:00:00Z",
"author": "Jane Editor",
"description": "The ECB cited persistent core inflation in the eurozone.",
"fetchedAt": "2026-06-15T09:12:04.221Z"
}
```
## Extracting one section
Use `prompt` when you only want part of the page. The metadata fields come back `null` and `markdown` holds plain text.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/crawl" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/pricing",
"prompt": "Extract only the FAQ section."
}'
```
# Deep Research
Source: https://docs.factagora.com/api-reference/deep-research
POST https://api.factagora.com/api/v1/deep-research
Comprehensive multi-source research on a topic
Perform in-depth research on any topic. Aggregates verified claims and predictions from the Factagora database (with AI agent perspectives), live news, and time-series event data, then generates a structured report with sections and cited sources.
## Request Body
The topic or question to research. Max 1000 characters.
Response language for the report summary and section content (e.g. `english`, `korean`). Section titles remain in English for stable parsing. Defaults to English.
Maximum number of sources in the response after deduplication. Range: 1–30. Actual count may be lower if available results fall short.
Start of preferred date range for sources (ISO 8601). Also passed to the internal news search. Example: `2025-01-01T00:00:00Z`
End of preferred date range for sources (ISO 8601). Also passed to the internal news search. Example: `2025-12-31T23:59:59Z`
## Response
The original query that was submitted.
A concise executive summary of the research findings.
Structured report sections generated by AI based on the aggregated context.
Section title. Typically: Background, Current State, Key Debates, Conclusion
Section content (2–5 sentences)
Chronological sequence of key events extracted from relevant sources, if available. Returns `null` if no time-ordered event data was found. Each data point represents a significant event or development at a specific point in time, not numeric measurements.
Title describing what the event sequence covers
Normalized timestamp: `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`
Short description of what happened at this point in time
Sources referenced in the report. Factagora internal claims and predictions are listed first, followed by news sources.
Title of the source
Source URL. Factagora internal sources follow the format `https://factagora.ai/claims/{uuid}` or `https://factagora.ai/predictions/{uuid}`.
Total response time in milliseconds, including database search, news fetch, and AI inference
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/deep-research" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"query": "Impact of US tariffs on global semiconductor supply chains"}'
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/deep-research",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"query": "Impact of US tariffs on global semiconductor supply chains"},
)
report = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/deep-research", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "Impact of US tariffs on global semiconductor supply chains",
}),
});
const report = await resp.json();
```
```json 200 theme={null}
{
"query": "Bitcoin price history in 2024",
"summary": "Bitcoin experienced significant price movements in 2024, driven by the approval of spot ETFs, the fourth halving event, and growing institutional demand.",
"sections": [
{
"title": "Background",
"content": "Bitcoin has been subject to cyclical price patterns tied to halving events and macroeconomic conditions. The 2024 cycle was anticipated as particularly significant due to pending ETF decisions."
},
{
"title": "Current State",
"content": "In January 2024, the SEC approved spot Bitcoin ETFs, triggering a rally that pushed prices above $73,000 by March. The fourth halving in April further constrained supply."
},
{
"title": "Key Debates",
"content": "Analysts debate whether the ETF-driven rally reflects sustainable institutional adoption or a short-term demand shock. Some agents forecast prices exceeding $200,000 by 2025, while others expect a correction."
},
{
"title": "Conclusion",
"content": "Bitcoin's 2024 trajectory suggests continued institutionalization, though volatility remains a defining characteristic. The confluence of ETF approval and halving creates an unprecedented demand-supply dynamic."
}
],
"timeseries": {
"title": "Bitcoin key events in 2024",
"dataPoints": [
{ "timestamp": "2024-01", "label": "SEC approves spot Bitcoin ETFs, price surges past $46,000" },
{ "timestamp": "2024-03", "label": "Bitcoin reaches new all-time high above $73,000" },
{ "timestamp": "2024-04", "label": "Fourth halving reduces block reward from 6.25 to 3.125 BTC" },
{ "timestamp": "2024-11", "label": "Post-election rally pushes Bitcoin above $90,000" }
]
},
"sources": [
{
"title": "Will Bitcoin exceed $100,000 by end of 2024?",
"url": "https://factagora.ai/predictions/6e3abcb2-6fea-42e3-bac8-599301a6357d"
},
{
"title": "Bitcoin ETF approval accelerates institutional adoption",
"url": "https://factagora.ai/claims/c5558d16-3625-4136-b62b-44b7df600239"
},
{
"title": "Bitcoin hits record high after ETF launch",
"url": "https://www.reuters.com/markets/currencies/bitcoin-etf-launch-2024"
}
],
"meta": {
"executionTimeMs": 8340
}
}
```
# Evidence Finder
Source: https://docs.factagora.com/api-reference/evidence-finder
POST https://api.factagora.com/api/v1/evidence-finder
Find credibility-scored evidence for any claim
Search for evidence related to a claim from real news sources. Returns AI-analyzed, credibility-scored sources categorized by type, each with a stance indicating whether the source supports, contradicts, or is neutral toward the claim.
## Request Body
The claim or topic to find evidence for. Max 500 characters.
Maximum number of results to return. Range: 1–20.
Filter news source language for evidence retrieval. Examples: `english`, `korean`
Filter news source country code for evidence retrieval. Examples: `US`, `KR`
Sort order for news-based evidence sources. Options: `relevance`, `date`
Data source for evidence. Options:
* `default`: public news sources only (default)
* `ingest`: personal ingested knowledge base only (requires personal access token)
* `all`: news + personal ingested knowledge base combined (requires personal access token)
Start of date range (ISO 8601) for news-based evidence. Example: `2025-01-01T00:00:00Z`
End of date range (ISO 8601) for news-based evidence. Example: `2025-05-01T23:59:59Z`
## Response
The claim that was searched.
List of evidence items. When `sortBy` is `relevance` (default), items are ordered by search relevance. When `sortBy` is `date`, items are ordered by publication date descending.
Title of the news article or source.
AI-generated explanation of how this source relates to the claim.
Original text excerpt from the source. Empty string when no excerpt is available.
Source URL.
Publication date of the source in ISO 8601 format. May be absent for some sources.
Evidence type: `DATA`, `EXPERT`, `NEWS`, or `FACT_CHECK`
AI-generated confidence score for how strongly this source supports or contradicts the claim. Higher values mean the source directly and clearly addresses the claim. Range: 0–1.
Whether the source supports or challenges the claim. One of: `SUPPORTS`, `CONTRADICTS`, `NEUTRAL`
Total number of evidence items found before the `limit` was applied.
Total response time in milliseconds, including database search and AI inference
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/evidence-finder" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"claim": "Carbon pricing reduces industrial emissions.", "limit": 5}'
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/evidence-finder",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"claim": "Carbon pricing reduces industrial emissions.", "limit": 5},
)
data = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/evidence-finder", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
claim: "Carbon pricing reduces industrial emissions.",
limit: 5,
}),
});
const data = await resp.json();
```
```json 200 theme={null}
{
"claim": "Bitcoin price will exceed 200000 dollars in 2025",
"results": [
{
"title": "Bitcoin surges past $100,000 as institutional demand accelerates",
"summary": "Reuters reports a surge in institutional Bitcoin purchases in early 2025, which analysts cite as a key demand driver toward higher price targets.",
"snippet": "Bitcoin climbed above $100,000 for the first time on Thursday as institutional inflows accelerated...",
"source": "https://www.reuters.com/markets/currencies/bitcoin-surge-institutional-2025",
"publishedAt": "2025-03-14T09:30:00Z",
"type": "NEWS",
"credibility": 0.92,
"stance": "SUPPORTS"
},
{
"title": "Bitcoin's path to $200K: what analysts say",
"summary": "Bloomberg analysis reviews multiple price forecasts, with some projecting Bitcoin could reach $200,000 by late 2025 under favorable macro conditions.",
"snippet": "",
"source": "https://www.bloomberg.com/news/articles/bitcoin-200k-forecast",
"publishedAt": "2025-02-28T14:00:00Z",
"type": "NEWS",
"credibility": 0.88,
"stance": "SUPPORTS"
},
{
"title": "Why Bitcoin may not hit $200,000 this cycle",
"summary": "The Guardian outlines bearish scenarios including regulatory headwinds and macro tightening that could prevent Bitcoin from reaching $200,000 in 2025.",
"snippet": "Analysts warn that tightening monetary policy and regulatory uncertainty could cap Bitcoin's gains this year...",
"source": "https://www.theguardian.com/technology/bitcoin-200k-skeptics",
"publishedAt": "2025-01-20T11:00:00Z",
"type": "NEWS",
"credibility": 0.88,
"stance": "CONTRADICTS"
}
],
"meta": {
"total": 8,
"executionTimeMs": 4821
}
}
```
# Fact Checker
Source: https://docs.factagora.com/api-reference/fact-checker
POST https://api.factagora.com/api/v1/fact-checker
Verify the truthfulness of a claim with AI verdicts
Verify whether a given claim is TRUE, FALSE, or UNCERTAIN. Searches the Factagora database for related claims and predictions, then uses AI to produce a verdict based on verified agent perspectives and evidence.
## Request Body
The claim or statement to verify. Max 1000 characters.
Response language for the `summary` field (e.g. `english`, `korean`). The `verdict` field always remains in English (`TRUE` / `FALSE` / `UNCERTAIN`). Defaults to English.
Maximum number of evidence sources to consider when forming the verdict. Range: 1–20.
Start of preferred date range for evidence (ISO 8601). Applied as a soft preference in the AI's reasoning. Example: `2025-01-01T00:00:00Z`
End of preferred date range for evidence (ISO 8601). Applied as a soft preference in the AI's reasoning. Example: `2025-12-31T23:59:59Z`
Data source for evidence collection. Options:
* `default`: public news sources only (default)
* `ingest`: personal ingested knowledge base only (requires personal access token)
* `all`: news + personal ingested knowledge base combined (requires personal access token)
## Response
The original claim that was submitted.
The fact-check result. One of: `TRUE`, `FALSE`, `UNCERTAIN`
Confidence score for the verdict. Range: 0–1. A value of `1` means the AI is fully certain; values below `0.5` should be treated as `UNCERTAIN` regardless of the verdict.
A brief explanation of the verdict based on the evidence found.
Related Factagora claims and predictions used for the verdict. Up to 5 items.
Title of the related claim or prediction
Link to the claim or prediction on Factagora.
Format: `https://factagora.ai/claims/{uuid}` or `https://factagora.ai/predictions/{uuid}`
Credibility score of the source. Range: 0–1.
Total response time in milliseconds, including database search and AI inference.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/fact-checker" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"claim": "The ECB raised interest rates in June 2024."}'
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/fact-checker",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"claim": "The ECB raised interest rates in June 2024."},
)
result = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/fact-checker", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
claim: "The ECB raised interest rates in June 2024.",
}),
});
const result = await resp.json();
```
```json 200 theme={null}
{
"claim": "OpenAI released GPT-5 in 2025",
"verdict": "FALSE",
"confidence": 0.85,
"summary": "The evidence indicates that OpenAI has not released GPT-5 in 2025. There is no verified information supporting the release of GPT-5 during that year, and the consensus from multiple agents suggests the claim is false.",
"sources": [
{
"title": "OpenAI's organizational stabilization following 2023 governance crisis",
"url": "https://factagora.ai/claims/c5558d16-3625-4136-b62b-44b7df600239",
"credibility": 0.7
},
{
"title": "Will OpenAI file for an IPO by end of 2026?",
"url": "https://factagora.ai/predictions/4a61d968-e467-4437-8711-8d27f44f11c6",
"credibility": 0.7
},
{
"title": "OpenAI's organizational restructuring and safety team departures",
"url": "https://factagora.ai/claims/c5b0325e-58fd-4fdb-b58e-3964cf1fddce",
"credibility": 0.7
}
],
"meta": {
"executionTimeMs": 4672
}
}
```
# Fact Search
Source: https://docs.factagora.com/api-reference/fact-search
GET https://api.factagora.com/api/v1/fact-search
Search recent news articles from global sources
Search recent news articles from global news sources including GNews and Naver News. Returns article titles, URLs, publication dates, and source domains.
## Query Parameters
Search query for news articles. Use focused keywords for best results.
Maximum number of results to return. Range: 1–50.
Filter by source language. Examples: `english`, `korean`
Filter by source country code. Examples: `US`, `KR`
Sort order. Options: `relevance`, `date`
Relative time range filter. Examples: `7d`, `30d`, `3months`. Ignored when `from` or `to` is provided.
Start of date range (ISO 8601). Takes precedence over `timespan` when set. Example: `2025-01-01T00:00:00Z`
End of date range (ISO 8601). Takes precedence over `timespan` when set. Example: `2025-05-01T23:59:59Z`
Comma-separated list of source domains to include. Only articles from these domains are returned. Example: `bbc.com,reuters.com`
Data source to search. Options:
* `default`: public news sources only (default)
* `ingest`: personal ingested knowledge base only (requires personal access token)
* `all`: news + personal ingested knowledge base combined (requires personal access token)
## Response
The search query that was used.
List of news articles.
Article title
Article URL
Source domain
Publication datetime (ISO 8601)
Article language
Source country code
Article excerpt (optional)
Article image URL (optional)
`gnews` or `naver`
Total number of results
Response time in milliseconds
Data source used (`gnews`, `naver`, `mixed`)
Whether the response was served from cache
```bash cURL theme={null}
curl -G "https://api.factagora.com/api/v1/fact-search" \
-H "Authorization: Bearer fa_your_api_key" \
--data-urlencode "q=ECB interest rate decision" \
--data-urlencode "limit=5" \
--data-urlencode "timespan=7d"
```
```python Python theme={null}
import requests
resp = requests.get(
"https://api.factagora.com/api/v1/fact-search",
headers={"Authorization": "Bearer fa_your_api_key"},
params={"q": "ECB interest rate decision", "limit": 5, "timespan": "7d"},
)
data = resp.json()
```
```typescript TypeScript theme={null}
const params = new URLSearchParams({
q: "ECB interest rate decision",
limit: "5",
timespan: "7d",
});
const resp = await fetch(
`https://api.factagora.com/api/v1/fact-search?${params}`,
{ headers: { Authorization: "Bearer fa_your_api_key" } },
);
const data = await resp.json();
```
```json 200 theme={null}
{
"query": "bitcoin",
"articles": [
{
"title": "Bitcoin surges past $100,000 amid institutional demand",
"url": "https://reuters.com/...",
"domain": "reuters.com",
"publishedAt": "2026-03-29T10:00:00Z",
"language": "english",
"sourceCountry": "US",
"snippet": "Bitcoin hit a new all-time high as institutional investors...",
"source": "gnews"
}
],
"meta": {
"total": 1,
"executionTimeMs": 312,
"source": "gnews",
"cached": false
}
}
```
# DeepStamp Detect
Source: https://docs.factagora.com/api-reference/fingerprint-detect
POST https://api.factagora.com/api/v1/fingerprint/detect
Score content against every stored fingerprint using the watermark and the causal structure.
Detection scores candidate content against every stored fingerprint, using both the hidden watermark and the causal structure of the text. It catches reuse even when every word has been changed.
**DeepStamp is the product name; the API paths still say `fingerprint`.** Endpoints are `/api/v1/fingerprint/embed` and `/api/v1/fingerprint/detect`, and responses return `fingerprint_id`. There is no `/api/v1/deepstamp/*` endpoint.
## POST /api/v1/fingerprint/detect
### Request Body
Provide exactly one of `content`, `url`, or `fingerprint_id`. Content and URL queries are extracted on the fly and are never stored.
Raw text to scan, typically the article you want to check. Maximum 50,000 characters.
URL of the document to scan.
An already-embedded fingerprint id (`fp_*`) to re-score against the registry. This reuses the stored snapshot instead of re-extracting, which makes it the cheapest option for scheduled monitoring.
Number of matches to return. Range: 1–50.
Minimum combined score for a candidate to be reported. Candidates with no shared signal at all are always excluded, whatever this value is. `match_found` is true only when at least one match clears both gates.
Upper bound on how many stored fingerprints are scanned, newest first. Range: 1–5000.
Custom scoring weights. `entity`, `time`, and `causal` must sum to 1.0. When omitted, content-type defaults apply: news `0.5 / 0.2 / 0.3`, legal `0.3 / 0.1 / 0.6`, report `0.4 / 0.3 / 0.3`, internal `0.5 / 0.2 / 0.3`.
Restrict which stored fingerprints are considered.
Only this author's fingerprints
Inclusive lower bound on `embed_timestamp` (`YYYY-MM-DD`)
Inclusive upper bound on `embed_timestamp` (`YYYY-MM-DD`)
Only one content type
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/fingerprint/detect" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "ECB hiked rates 25bp Thursday due to stubborn inflation.",
"top_k": 5,
"min_score": 0.3
}'
```
### Response
True when at least one candidate cleared `min_score`.
The top match's combined score, or `0` when nothing matched.
The query's fingerprint id. For `content` and `url` queries this is minted during on-the-fly extraction and is not persisted.
Top-K candidates, ranked by combined score descending.
Matched fingerprint id
Content type recorded at embed time
Metadata stored at embed time, may be null
When the candidate was fingerprinted
Weighted combined score
Per-signal scores: `entity_match`, `timeseries_match`, `causal_pattern_match`
The shared entities, time anchors, and `from|rel|to` triples behind the score
True when the input carries a watermark correlating 85% or higher with this candidate. This is near-certain provenance evidence
Bit-level correlation, null when no watermark was detected
How many stored fingerprints were scored after filters
Response time in milliseconds
The weights actually applied to this request
True when a watermark was found in the input and matched a stored fingerprint
```json 200 theme={null}
{
"match_found": true,
"confidence_score": 0.87,
"query_fingerprint_id": "fp_tmpQueryId01",
"matches": [
{
"fingerprint_id": "fp_l1p8OPCwGhvu",
"content_type": "news",
"metadata": { "author_id": "editor_jane", "source_id": "article_12345" },
"embed_timestamp": "2024-06-15T08:01:23.456Z",
"score": 0.87,
"similarity_breakdown": {
"entity_match": 0.92,
"timeseries_match": 1.0,
"causal_pattern_match": 0.78
},
"overlap": {
"entities": ["european central bank", "interest rate", "goldman sachs"],
"timeseries": ["2024-06-15"],
"relations": ["european central bank|raises|interest rate"]
},
"watermark_match": false,
"watermark_correlation": null
}
],
"meta": {
"scanned": 156,
"executionTimeMs": 342,
"weights": { "entity": 0.5, "time": 0.2, "causal": 0.3 },
"watermark_detected": false
}
}
```
Embedding is covered in [DeepStamp Embed](/api-reference/fingerprint-embed).
# DeepStamp Embed
Source: https://docs.factagora.com/api-reference/fingerprint-embed
POST https://api.factagora.com/api/v1/fingerprint/embed
Extract a TKG from your content and embed a structure-based watermark.
DeepStamp proves that a piece of content originated from you, even after it has been rewritten or translated. Embedding extracts a Temporal Knowledge Graph (TKG) from your content and hides a watermark seeded by that structure.
**DeepStamp is the product name; the API paths still say `fingerprint`.** Endpoints are `/api/v1/fingerprint/embed` and `/api/v1/fingerprint/detect`, and responses return `fingerprint_id`. There is no `/api/v1/deepstamp/*` endpoint.
## POST /api/v1/fingerprint/embed
### Request Body
Provide either `content` or `url`, not both.
Raw text to fingerprint. Maximum 50,000 characters.
URL of the source document to fingerprint.
Category of the content. One of `news`, `report`, `legal`, `internal`. This also selects the default scoring weights used at detection time.
Your own identifiers, stored with the fingerprint and echoed back on every match.
Internal author identifier
ISO 8601 publish timestamp
Upstream source identifier, such as a CMS article id
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/fingerprint/embed" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "The European Central Bank raised interest rates by 25 basis points on Thursday, citing persistent core inflation in the eurozone.",
"content_type": "news",
"metadata": {
"author_id": "editor_jane",
"published_at": "2024-06-15T08:00:00Z",
"source_id": "article_12345"
}
}'
```
### Response
Your content with the TKG-seeded zero-width watermark embedded. Distribute this version, not the original.
Unique fingerprint identifier (`fp_*`). Store it alongside your internal article id.
The structure extracted from your content.
Distinct entities found in the content
Normalized time anchors (`YYYY`, `YYYY-MM`, or `YYYY-MM-DD`)
Causal or temporal relations as `from` / `rel` / `to` triples
Premise → evidence → conclusion chains
ISO 8601 timestamp of when the fingerprint was embedded.
```json 200 theme={null}
{
"watermarked_content": "The European Central Bank raised interest rates by 25 basis points...",
"fingerprint_id": "fp_l1p8OPCwGhvu",
"tkg_snapshot": {
"entities": ["European Central Bank", "Interest rate", "Goldman Sachs"],
"timeseries": ["2024-06-15"],
"relations": [
{ "from": "European Central Bank", "rel": "raises", "to": "Interest rate" }
],
"argument_map": [
{
"premise": "Persistent core inflation in the eurozone",
"evidence": "ECB policy meeting decision",
"conclusion": "Interest rates raised by 25 basis points"
}
]
},
"embed_timestamp": "2024-06-15T08:01:23.456Z",
"meta": { "executionTimeMs": 1234 }
}
```
Detection is covered in [DeepStamp Detect](/api-reference/fingerprint-detect).
# Ingest
Source: https://docs.factagora.com/api-reference/ingest
POST https://api.factagora.com/api/v1/ingest
Extract claims, predictions, and causal edges from a URL, text, or file and store them in your knowledge graph.
Ingest external content, such as a URL, raw text, or uploaded file, and automatically extract structured knowledge (claims, predictions, causal edges) into your personal TKG (Temporal Knowledge Graph). Extracted knowledge is also stored as vector embeddings for semantic search.
## Endpoints
| Method | Path | Input |
| ------ | --------------------- | --------------------------------- |
| `POST` | `/api/v1/ingest` | JSON body with `url` or `content` |
| `POST` | `/api/v1/ingest/file` | `multipart/form-data` with `file` |
***
## POST /api/v1/ingest
### Request Body
URL to fetch and ingest. Either `url` or `content` is required.
Raw text content to ingest (max 20,000 characters). Either `url` or `content` is required.
Access control for the ingested content. `private` (default) is only accessible to you. `public` is accessible to anyone with your API key.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/ingest" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/quarterly-report"}'
```
```python Python theme={null}
import requests
resp = requests.post(
"https://api.factagora.com/api/v1/ingest",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"url": "https://example.com/quarterly-report"},
)
data = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/ingest", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com/quarterly-report" }),
});
const data = await resp.json();
```
***
## POST /api/v1/ingest/file
### Request Body (multipart/form-data)
PDF, Markdown, or TXT file to ingest.
Access control. `private` or `public`.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/ingest/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@report.pdf" \
-F "visibility=private"
```
***
## Response
Unique ID of the ingested source document.
ID of the TKG graph created for this document.
Title extracted from the source content.
List of falsifiable factual statements extracted from the content.
Concise claim title
Full claim statement
Domain category (economics, technology, politics, etc.)
Date the claim refers to (YYYY-MM-DD), if mentioned
List of future predictions extracted from the content.
Concise prediction title
Full prediction statement
Domain category
Future deadline date (YYYY-MM-DD), if mentioned
Causal relationships between extracted claims and predictions.
Title of the source node
Title of the target node
Relationship type: `CAUSES`, `SUPPORTS`, `CONTRADICTS`, `TRIGGERS`, `CONTRIBUTING_FACTOR`, `PREVENTS`, `CONCURRENT_SIGNAL`, `QUALIFIES`, `DEPENDS_ON`, `DERIVED_FROM`, `SUPERSEDES`
Confidence score (0.0–1.0)
Brief explanation of the causal relationship
Character length of the original content stored as vector chunks.
Number of vector chunks stored for semantic search.
```json 200 theme={null}
{
"ingest_source_id": "cec6ad87-b783-4b4e-a6f4-65130b5e17a8",
"tkg_id": "a6c36ed6-36e3-4f87-8855-e88484f3a08f",
"source_title": "Iran to Gain Major Financial Relief Under Interim Deal With US",
"claims": [
{
"title": "Iran allowed to start oil exports immediately under interim deal",
"description": "Iran would be allowed to start oil exports immediately under an interim deal with the US.",
"category": "economics",
"claim_date": "2026-06-17"
}
],
"predictions": [
{
"title": "Permanent peace negotiations following interim deal",
"description": "Negotiations for a permanent peace are intended to address Tehran's nuclear activities.",
"category": "politics",
"deadline": null
}
],
"edges": [
{
"from_title": "Iran allowed to start oil exports immediately under interim deal",
"to_title": "Permanent peace negotiations following interim deal",
"edge_type": "TRIGGERS",
"confidence": 0.7,
"mechanism": "Oil export permission is a precondition enabling broader peace negotiations."
}
],
"general_length": 562,
"chunks_count": 1
}
```
***
## Searching Ingested Content
Use `GET /api/v1/fact-search` with `source=ingest` to search your ingested content:
```bash theme={null}
curl "https://api.factagora.com/api/v1/fact-search?q=oil+exports+iran&source=ingest" \
-H "Authorization: Bearer fa_your_api_key"
```
Results include chunks, claims, and predictions from your personal knowledge graph.
# Introduction
Source: https://docs.factagora.com/api-reference/introduction
Base URL, authentication, and response format for the Factagora API
## Overview
The Factagora API gives you programmatic access to the Factagora knowledge graph, a continuously updated database of fact-checked claims, predictions, evidence, and causal relationships extracted from global news and research sources. Call it from any language or framework, on top of the LLM and retrieval stack you already run.
For what FactBlocks and the Temporal Knowledge Graph are, see [What is Factagora?](/index). For picking the right endpoint, see [Choosing an API](/guides/factagora/search-api/overview).
## Base URL
```
https://api.factagora.com
```
## Authentication
All Factagora endpoints are authenticated using API keys. [Get your free API key.](https://factagora.com/en/playground/tokens)
**You don't need to create one to get started.** A default API key is issued automatically the first time you sign in to Factagora. Visit [Settings → API Keys](https://factagora.com/en/playground/tokens) to copy it or create additional keys.
```bash theme={null}
curl -X GET "https://api.factagora.com/api/v1/fact-search?q=bitcoin" \
-H "Authorization: Bearer fa_YOUR_API_KEY"
```
API keys follow the format `fa_...`. See [Authentication](/api-reference/authentication) for details.
## Endpoints
Every endpoint is listed under **Endpoints** in the sidebar. Each page carries the full parameter list, the response fields, and cURL, Python, and TypeScript examples.
If you are not sure which one you need, [Choosing an API](/guides/factagora/search-api/overview) lines them all up by what they do and what they cost.
## Response Format
All responses are JSON. Successful responses return `200`. Errors return `400` (validation) or `401` (authentication).
```json theme={null}
{
"error": "Unauthorized",
"message": "Missing Bearer token",
"statusCode": 401
}
```
See [Rate limits](/rate-limits) for per-key limits and the headers on every response.
# Timeseries
Source: https://docs.factagora.com/api-reference/timeseries
POST https://api.factagora.com/api/v1/timeseries
Extract time-series data from a given URL or file.
Extract time-series data from a URL or uploaded file (PDF, Markdown). Returns a list of timestamped events or facts, organized chronologically.
## Endpoints
| Method | Path | Input |
| ------ | ------------------------- | --------------------------------- |
| `POST` | `/api/v1/timeseries` | JSON body with `url` |
| `POST` | `/api/v1/timeseries/file` | `multipart/form-data` with `file` |
***
## POST /api/v1/timeseries
### Request Body
URL of the page or document to extract time-series data from.
Language for the extracted data point labels (e.g. `english`, `korean`). Timestamps remain in ISO formats (`YYYY`, `YYYY-MM`, `YYYY-MM-DD`). Defaults to English.
Maximum number of time-series data points to extract. Range: 1–100.
```bash cURL (URL) theme={null}
curl -X POST "https://api.factagora.com/api/v1/timeseries" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/ai-act-history"}'
```
```bash cURL (file upload) theme={null}
curl -X POST "https://api.factagora.com/api/v1/timeseries/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@report.pdf"
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/timeseries",
headers={"Authorization": "Bearer fa_your_api_key"},
json={"url": "https://example.com/ai-act-history"},
)
data = resp.json()
```
***
## POST /api/v1/timeseries/file
### Request Body (multipart/form-data)
PDF or Markdown file to extract time-series data from.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/timeseries/file" \
-H "Authorization: Bearer fa_your_api_key" \
-F "file=@report.pdf"
```
***
## Response
Inferred title or description of the time-series.
List of time-series data points, sorted chronologically.
Normalized timestamp in one of: `YYYY`, `YYYY-MM`, or `YYYY-MM-DD`
Description of the event or fact at this point in time
Total number of data points
Response time in milliseconds
```json 200 theme={null}
{
"title": "AI Regulation Timeline",
"dataPoints": [
{ "timestamp": "2023-03", "label": "Italy temporarily bans ChatGPT over privacy concerns" },
{ "timestamp": "2023-06", "label": "EU Parliament passes draft AI Act" },
{ "timestamp": "2023-10", "label": "US Executive Order on AI safety signed by Biden" },
{ "timestamp": "2024-03", "label": "EU AI Act formally adopted" },
{ "timestamp": "2024-08", "label": "EU AI Act enters into force" },
{ "timestamp": "2025-02", "label": "First prohibited AI systems banned under EU AI Act" }
],
"meta": {
"total": 6,
"executionTimeMs": 520
}
}
```
# 2025-05
Source: https://docs.factagora.com/changelog/api/2025-05
Factagora API releases in 2025-05 (v0.1.0)
## Initial Release
First public release of the Factagora API. The following endpoints are available.
**No breaking changes**: this is the initial release.
### Intelligence APIs
| Endpoint | Description |
| ----------------------------------- | ------------------------------------------------------ |
| `GET /api/v1/news/search` | Search recent news articles from global sources |
| `POST /api/v1/fact-checker` | Verify the truthfulness of a claim with AI verdicts |
| `POST /api/v1/evidence-finder` | Find credibility-scored evidence for any topic |
| `POST /api/v1/deep-research` | Run comprehensive multi-source research on a topic |
| `POST /api/v1/timeseries` | Extract timeseries data from a URL or text |
| `POST /api/v1/timeseries/file` | Extract timeseries data from a file upload |
| `POST /api/v1/causality-graph` | Extract a causal relationship graph from a URL or text |
| `POST /api/v1/causality-graph/file` | Extract a causal relationship graph from a file upload |
| `POST /api/v1/fingerprint/embed` | Embed a TKG-based watermark into content |
| `POST /api/v1/fingerprint/detect` | Detect whether content matches a fingerprinted source |
# 2026-05
Source: https://docs.factagora.com/changelog/api/2026-05
Factagora API releases in 2026-05 (v0.1.1)
## Input Parameter Expansion
This release expands the input parameters across all 6 Intelligence APIs to standardize filtering, language, and result-size controls.
**No breaking changes**: all new parameters are optional with sensible defaults. Existing requests continue to work unchanged.
### Added Parameters
| Endpoint | New Parameters |
| ------------------------------ | --------------------------------------------- |
| `GET /api/v1/news/search` | `from`, `to`, `domains` |
| `POST /api/v1/evidence-finder` | `from`, `to`, `language`, `country`, `sortBy` |
| `POST /api/v1/fact-checker` | `language`, `limit`, `from`, `to` |
| `POST /api/v1/deep-research` | `language`, `limit`, `from`, `to` |
| `POST /api/v1/timeseries` | `language`, `limit` |
| `POST /api/v1/causality-graph` | `language`, `limit` |
### Notes
* For `news/search`, when `from` or `to` is provided, the existing `timespan` parameter is ignored (absolute range takes precedence).
* For `news/search`, the new `domains` parameter accepts a comma-separated list of source domains to restrict results to (e.g. `bbc.com,reuters.com`).
* The `language` parameter on `fact-checker` and `deep-research` controls the response text language; structural fields (`verdict` enum, section titles) remain in English for stable parsing.
* For `timeseries` and `causality-graph`, the `language` parameter affects extracted labels only; timestamps and node IDs remain in their canonical formats.
See the [API Reference](/api-reference/introduction) for the full parameter list of each endpoint.
# 2026-06
Source: https://docs.factagora.com/changelog/api/2026-06
Factagora API releases in 2026-06 (v0.1.2 – v0.1.6)
## New: Collections API
Build a **per-brand private knowledge graph** by ingesting multiple URLs into one unified TKG (Temporal Knowledge Graph), then query it with grounded answers and Q\&A verification.
### How it works
1. **Create** a collection for a brand (e.g. Hyundai UK)
2. **Ingest** URLs: each page is extracted into claims, predictions, and causal edges that accumulate in one unified TKG
3. **Ask questions** grounded only in that corpus (`/answer`)
4. **Verify** existing Q\&A pairs against the knowledge graph (`/qa-verify`)
### New endpoints
| Method | Path | Description |
| -------- | --------------------------------------------- | ----------------------------------------- |
| `POST` | `/api/v1/collections` | Create a collection |
| `GET` | `/api/v1/collections` | List your collections |
| `GET` | `/api/v1/collections/{id}` | Get collection + ingested URL list |
| `DELETE` | `/api/v1/collections/{id}` | Delete a collection and all its data |
| `POST` | `/api/v1/collections/{id}/ingest` | Ingest a single URL (synchronous) |
| `DELETE` | `/api/v1/collections/{id}/sources/{sourceId}` | Remove a source URL from the collection |
| `GET` | `/api/v1/collections/{id}/ingest-status` | Poll ingestion progress |
| `GET` | `/api/v1/collections/{id}/graph` | Get the unified knowledge graph |
| `POST` | `/api/v1/collections/{id}/answer` | Ask a question grounded in the collection |
| `POST` | `/api/v1/collections/{id}/qa-verify` | Verify existing Q\&A pairs |
### Key behaviors
* **Synchronous ingestion**: `POST /ingest` processes URLs and returns results per URL including `claims_count` and `predictions_count`. Each URL takes 10–30 seconds.
* **Unified TKG**: all ingested URLs share one knowledge graph per collection. Same-title entities are merged automatically.
* **Semantic search**: `/answer` and `/qa-verify` use pgvector to retrieve the most relevant chunks before generating answers, improving accuracy over naive RAG.
* **Grounded flag**: if the collection does not contain enough information to answer, `grounded: false` is returned instead of hallucinating.
* **Tenant isolation**: collections are scoped to personal access tokens. A master key cannot access collection endpoints.
### Q\&A verification verdicts
| Verdict | Meaning |
| ------------- | --------------------------------------------------------------------- |
| `correct` | Answer is supported by the knowledge graph |
| `incorrect` | Answer contradicts the knowledge, so a `correction` field is provided |
| `unsupported` | Not enough information in the collection to verify |
## Changed: Unified `source` parameter across Evidence Finder, Fact Checker, and Fact Search
`POST /api/v1/evidence-finder`, `POST /api/v1/fact-checker`, and `GET /api/v1/fact-search` now share a consistent `source` parameter for controlling which data sources are used.
### `source` parameter
| Value | Behavior |
| --------- | ------------------------------------------------------------------------------------------ |
| `default` | Public news sources only. This is the default, so there is no change to existing behavior. |
| `ingest` | Personal ingested knowledge base only. Requires a personal access token. |
| `all` | News + personal ingested knowledge base combined. Requires a personal access token. |
**Affected endpoints:**
| Endpoint | Parameter | Default |
| ------------------------------ | --------- | --------- |
| `GET /api/v1/fact-search` | `source` | `default` |
| `POST /api/v1/evidence-finder` | `source` | `default` |
| `POST /api/v1/fact-checker` | `source` | `default` |
**Backward compatibility:** `fact-search` previously accepted `source=news`. This value continues to work as an alias for `source=default`.
## New: Ingest API
Two new endpoints that let you extract structured knowledge from any content source and store it in your personal Temporal Knowledge Graph.
### POST /api/v1/ingest
Ingest a URL or raw text. Automatically extracts:
* **Claims**: falsifiable factual statements
* **Predictions**: future-oriented statements with measurable outcomes
* **Causal edges**: relationships between claims and predictions (CAUSES, SUPPORTS, CONTRADICTS, etc.)
* **Vector chunks**: semantic search index for the full content
### POST /api/v1/ingest/file
Upload a PDF, Markdown, or TXT file directly for ingestion.
### GET /api/v1/fact-search?source=ingest
Search your personal ingested knowledge graph. Returns chunks, claims, and predictions matching your query. Requires a personal access token, so only your own content is returned.
## Bug Fixes and Improvements
This release includes minor bug fixes and internal improvements across the API.
## Fact Search Rename
Renamed the News Search endpoint to Fact Search to better reflect the scope of the API.
### Changed
* `GET /api/v1/news/search` has been renamed to `GET /api/v1/fact-search`
**Migration:** Update any hardcoded endpoint paths from `/api/v1/news/search` to `/api/v1/fact-search`. Query parameters and response schema are unchanged.
# 2026-07
Source: https://docs.factagora.com/changelog/api/2026-07
Factagora API releases in 2026-07 (v0.1.7 – v0.1.20)
## Fixed: temporal annotation format on `PATCH /api/v1/tkgs/{tkgId}/graph/nodes/{nodeId}/annotation`
The request body now uses `{ timestamp: "2026-09-30", precision: "quarter" }` (an ISO 8601 date) instead of the previous loose `{ when: "2026 Q3", precision: "quarter" }` string. This aligns with the annotation format already used elsewhere on the platform.
The endpoint now also merges into any existing annotation data instead of overwriting it, so other fields (like source provenance) are preserved.
`capture_temporal` actions from `POST /api/v1/chat` now return `timestamp` (ISO 8601) instead of `when`, so you can pass it straight through to this endpoint.
## Improved: duplicate-safe graph node creation
`POST /api/v1/collections/{id}/graph/nodes` and `POST /api/v1/tkgs/{tkgId}/graph/nodes` now check for an existing prediction/claim with a substantially overlapping title before creating a new one. If a close match already exists on the platform, that existing FactBlock is reused instead of creating a near-duplicate — and if it's already a node in the same graph, no duplicate node is created either.
The response now includes an optional `reused: boolean` field so you can tell whether your request created something new or matched an existing FactBlock.
## Improved: `tkg_id` grounding in `POST /api/v1/chat`
When chatting with `tkg_id` grounding, the assistant now works much harder to help you build out your knowledge graph:
* **New `capture_temporal` action** — alongside `capture_belief` and `capture_causal`, the assistant can now suggest attaching a time reference (`when` + `precision`: year/quarter/month/day) to an existing belief.
* **Graph-gap awareness** — the assistant is now aware of which beliefs have no causal connections and which predictions have no timeline, and will proactively ask about them.
* **FactBlock reuse** — the assistant checks for related predictions/claims that already exist on the platform before treating something as a brand-new belief.
* **Implicit capture from free text** — if you mention a specific time or a causal reason in your own message (not just by clicking a suggested action), the assistant will include the matching `capture_temporal` or `capture_causal` action even without an explicit request to save it.
* **Session persistence** — `tkg_id` conversations now save session and message history on the server, the same way `collection_id` conversations already do. Pass the returned `session_id` back on your next request to continue the conversation with full context.
* **Consistent language** — responses, follow-up questions, and suggested action titles now consistently match the language you're writing in.
`collection_id` grounding is unchanged.
## Added: `POST /api/v1/chat`
A new streaming (SSE) chat endpoint.
* Pass `collection_id` to ground answers in a collection's knowledge (semantic chunk search with knowledge-graph fallback). Session and message history are persisted.
* Pass `tkg_id` to ground answers in a standalone knowledge graph instead.
* Omit both for a one-off chat with no grounding and no saved session.
* Choose a `model`: `gpt-5-nano`, `gpt-5-mini`, or `gpt-5`.
* Enable `use_fact_search` / `use_evidence_finder` / `use_fact_checker` to let the model autonomously call those research tools during the conversation. Each tool call is billed individually at the same credit cost as its standalone endpoint, only when actually invoked.
* The chat request itself is currently free while pricing for this endpoint is being finalized.
## Added: TKG graph editing endpoints
`POST/PATCH/DELETE /api/v1/tkgs/{tkgId}/graph/nodes` and `POST/DELETE /api/v1/tkgs/{tkgId}/graph/edges` let you manually create, rename, and delete nodes and edges on a knowledge graph that isn't attached to a collection — the same graph-editing capability collections already had, now available standalone. These endpoints are free.
A new `PATCH /api/v1/tkgs/{tkgId}/graph/nodes/{nodeId}/annotation` endpoint lets you attach a temporal annotation (`when` + `precision`: year/quarter/month/day) to a belief node.
## Fixed: qa-verify entity matching
`POST /api/v1/collections/{id}/qa-verify` no longer over-matches on brand or product-family tokens that are common across many entities in the same collection (for example, matching almost any entity just because it shares a common brand name). Matching is now more precise.
## Fixed: entity-connected fact limit
Raised the internal cap on how many connected facts are considered when resolving an entity from 20 to 50. Previously, some genuinely connected facts were cut off before relevance ranking, which could make a verdict appear `unsupported` when better evidence existed.
## Added: `mode` parameter for fact-search
`GET /api/v1/fact-search` now accepts a `mode` parameter:
* `auto` (default) — semantic hybrid search with live fallback. This is the existing default behavior.
* `fast` — keyword-only search that skips query embedding and the live fallback for the lowest latency. Best when you want the quickest results and don't need semantic matching.
Omitting `mode` keeps the existing behavior (`auto`).
## Improved: results when filtering by domain or narrow criteria
Fact-search now reliably returns matching articles when you restrict results (for example, by domain). Previously, narrow filters could return few or no results even when matching articles existed.
## Improved: faster response time
`POST /api/v1/collections/{id}/qa-verify` now resolves entity-linked evidence significantly faster per question/answer pair, reducing overall response time for the endpoint. No request or response shape changed.
## Improved: Q\&A verification evidence retrieval
`POST /api/v1/collections/{id}/qa-verify` now finds relevant evidence more reliably:
* Evidence retrieval considers the claimed answer text as well as the question, so facts that only overlap with wording in the answer are no longer missed.
* Entity matching now recognizes a question that mentions only part of an entity's full name (e.g. a question naming a product's short name is matched against the entity's full name in the graph).
* Vector search results are now filtered to a minimum relevance threshold, so clearly unrelated content is no longer included as evidence.
## Fixed: one failing pair no longer fails the whole request
Previously, if any single question/answer pair in a `qa-verify` request hit an internal error, the entire request failed and no results were returned — even for pairs that would have verified successfully. Each pair is now processed independently: a failing pair now returns as `"verdict": "unsupported"` while the rest of the batch completes normally.
No request or response shape changed.
## Fixed: 500 error on large collections
`GET /api/v1/collections/{id}/graph` could return a `500` error for collections with a few hundred or more claims/predictions/entities combined. Fetching a new collection's graph for the first time after it grew past this size would fail entirely.
Ingesting a new source into an already-large collection could also fail for the same underlying reason, blocking further ingestion into that collection.
### What changed
Internal lookups that resolve node titles now run as a single server-side query instead of passing large ID lists in the request. This removes the size ceiling — collections with any number of nodes now work the same way.
No response shape changed; if you were affected by this, requests that previously failed now simply succeed.
## New: Entities in the knowledge graph
Collections now extract named **entities** (people, organizations, products) from ingested content, in addition to claims and predictions. Entities become nodes in the collection's knowledge graph, connected to every claim or prediction that mentions them — turning previously disconnected facts about the same person, company, or product into a single connected cluster.
### Entity types
| Type | Description |
| -------------- | ---------------------------------------------------------------------- |
| `PERSON` | A specific named individual |
| `ORGANIZATION` | A specific named company, institution, or group |
| `PRODUCT` | A specific named brand or model (generic categories are not extracted) |
### Changed endpoints
| Endpoint | Change |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/v1/collections/{id}/graph` | Response nodes may now have `"type": "ENTITY"` in addition to `CLAIM`/`PREDICTION` |
| `GET /api/v1/collections/{id}/context` | Adds `matched_entities` (entity names/aliases found in the question) and `entity_facts` (claims/predictions linked to those entities) |
| `POST /api/v1/collections/{id}/qa-verify` | Grounding now combines vector search with entity-graph traversal. If a question and a claim share a named entity but are worded very differently, the claim is now found — improving verification accuracy in that case |
### Why this matters
Previously, retrieval relied only on vector similarity between the question and ingested text. If a question mentioned an entity by name but phrased things differently from the source content, relevant claims could be missed. Entities give the graph a second, exact-match retrieval path alongside semantic search.
# 2026-07
Source: https://docs.factagora.com/changelog/extension/2026-07
DeepVerify Chrome extension releases in 2026-07 (v0.1.1)
## Added: Five reliability tiers
The automatic fact-check card on YouTube now describes a video's trust score with one of five tiers, each with its own color, instead of a bare number.
| Score | Tier |
| ------ | ------------------------ |
| 90–100 | Highly Reliable |
| 70–89 | Mostly Reliable |
| 50–69 | Mixed Reliability |
| 30–49 | Low Reliability |
| 0–29 | High Misinformation Risk |
## Added: False-claim alerts during playback
When playback reaches a claim that was judged false, the video pauses and a warning appears over the player. **View Claims** opens the side panel with that claim in view.
## Fixed: Claim markers not appearing
Claim markers and playback alerts now track verification results directly, so they appear reliably.
# 2026-08
Source: https://docs.factagora.com/changelog/extension/2026-08
DeepVerify Chrome extension releases in 2026-08 (v0.1.4 – v0.1.20)
## Added: History is tied to your account, not your browser
Your verification sessions are now stored with your Factagora account. Open the History panel on another computer, or after reinstalling the extension, and your past checks are there. Deleting an entry removes it everywhere.
Until now History lived only in the browser profile, so a session you ran at the office was invisible at home, and signing in as a different person still showed the previous account's records.
## Added: Page preview can be turned off
**Settings** has a new **Page preview** toggle, on by default. The preview card on the entry screen is built by reading the current page's meta tags, and nothing leaves your browser, but redrawing it every time you switch tabs made the panel feel like it was watching you. Turning the toggle off skips the lookup entirely rather than just hiding the card.
## Changed: Favicons no longer leave your browser
Site icons used to come from a Google favicon service, which meant every domain you visited was sent there as you moved around. They are now read from Chrome's own local cache, so no external request is made.
## Changed: One click runs detection and verification
**Check this page** and **Verify** now detect claims and verify all of them in one go. Previously they only detected, and you had to press **Verify all** afterwards. The wait and the credit cost are the same, there is just one less click, and the now-redundant **Verify all** button is gone.
## Changed: Selected text is checked exactly like a page
Highlighting a passage and checking it used to take its own path: the whole selection was sent as a single claim, and the screen stayed empty until everything finished. Selections now run through the same pipeline as a page scan, so each claim appears as it is detected, verdicts attach one by one, and the passage gets the same in-page highlights and hover popovers.
Selections also join the existing History entry for that page instead of creating a new session every time you highlight something. When nothing verifiable is found, you now get a clear "no claims to check" message instead of the full passage being graded as one claim.
## Changed: The hover popover shows sources
Hovering a highlighted sentence now shows the verdict as an icon and a plain-language label, confidence as a bar, and the sources behind the verdict as a favicon stack with a count. The result already carried sources, but this popover was throwing them away, so there was no way to tell a well-supported verdict from a thin one without opening the panel. It also follows your system dark mode now.
## Changed: Check again moved to a bottom bar, with a freshness line
Re-check controls left the header, which is there to tell you what is being checked, and now sit in a fixed bar under the claim list where they stay visible as you scroll. The bar also shows when the result was produced, for example `Checked 2 days ago`, since the whole point of re-checking is that verdicts age.
`Re-verify` and `Re-scan` are both called **Check again**, and while a check is running the bar reads `Checking 3 of 7` with a **Stop** button. Verdicts already produced are kept when you stop.
## Changed: Every detected claim is verified
The caps of 20 claims per video and 20 per automatic page scan are gone. Everything detected gets checked.
## Changed: Re-checking a video keeps the earlier result
Verifying the same video again used to replace its History entry. It now adds a new one, so the Then/Now comparison still has something to compare against. Simply revisiting a video you already checked does not re-run anything.
## Changed: YouTube pages are checked by transcript only
On YouTube, **Check this page** no longer scans the page text. Video pages have a transcript-based pipeline of their own, and home, search, and channel pages are just lists of thumbnail titles, which produced fragments with no context. On pages where a text scan does not apply, the button is hidden with a one-line reason.
## Changed: The panel follows your browser language and system theme
The side panel started in English regardless of your browser language, and in light mode regardless of your system setting, even though the cards drawn on YouTube already followed it. Both are now detected automatically. An explicit choice in **Settings** still wins.
## Changed: The sign-in screen says what DeepVerify does
For a new install this screen is the first thing you see, so it now leads with the product instead of the requirement: "Check what you're reading", with a line naming what can be checked, page, video, and live audio.
## Fixed: Failed checks no longer look like verdicts
When a fact-check request failed, the extension recorded an `Uncertain` verdict instead. That fake verdict went into History and pulled down the Trust Score. Failures now leave the claim unchecked, and a failed re-check from History records nothing at all, so Then/Now no longer reports a verdict as having flipped when it never landed.
## Fixed: The warning card broke on some sites
The card that appears when false claims are detected inherited layout rules from the page it sat on. On sites with certain CSS resets it was squeezed to a fraction of its width, and the title and count wrapped over the artwork. The card is now isolated from the host page's styles.
## Fixed: A failed check left the card stuck in progress
If any single claim failed, the progress bar stopped at something like `7 of 8` forever, the gauge never filled, and the score stayed at `—%`. The card now settles when the run is over and shows `N unchecked` so you can see how many were skipped.
## Fixed: Live claims show what was actually said
Claim cards in the Live session summary showed an expanded sentence with pronouns resolved, which did not match the line you saw scroll past during the session. They now show the original wording.
## Fixed: Microphone sessions include the date
Microphone entries were labeled with a time only, so sessions from different days at a similar hour were indistinguishable in History. They now read like `Microphone Record 2026-08-05 14:34`.
## Fixed: Trust Score card at narrow panel widths
The three verdict counts overflowed their column when the side panel was narrow. They now wrap, and below 380px the gauge is replaced by a score next to the title so the counts fit on one line.
## Fixed: Smaller display issues
The "no transcript" / "no claims" / "check failed" states no longer print the same sentence twice. The session-check loading screen no longer flashes on fast connections.
## Changed: History entries are easier to tell apart
History rows now show the full page URL instead of a shortened `hostname/path`. Previously every YouTube entry read as `www.youtube.com/watch`, because a video's ID lives in the query string — so a list of ten videos looked like ten identical rows.
Microphone sessions no longer borrow the title of whatever tab happened to be open at the time, which was often unrelated to what you were listening to. They are now labeled by start time, for example `Microphone session · 2:34 PM`. Tab-audio sessions still use the real tab title and URL.
## Changed: Live sessions carry the real page context
Live sessions (microphone and tab audio) now pass the actual tab title and URL along with detected claims, instead of a generic `Live session` placeholder.
The Live screen also gained the same header (favicon plus title) that the Page and YouTube screens already had. Until now Live was the only mode with no indication of what was being checked.
## Fixed: YouTube home, search, and channel pages
Opening the extension on a YouTube page with no video — the home feed, search results, or a channel — showed a "Choose a video" prompt instead of working. These pages now behave like any other web page, so you can fact-check the text on them.
## Changed: Unified DeepVerify branding
The extension toolbar icon, the YouTube floating button, and the automatic fact-check card now use the DeepVerify mark.
## Fixed: Preview card showed the previous video
When moving from one YouTube video to another, the preview card kept the previous video's thumbnail, title, and description. YouTube updates the page without rewriting the metadata the extension was reading. The extension now reads the title from the live page and builds the thumbnail from the video ID directly, so the preview always matches what you are watching.
## Changed: YouTube claims stream in
Claims from a video now appear one by one as they are detected, the same way page text already worked. Previously the list stayed empty until the entire transcript had been processed, which felt like nothing was happening on long videos.
## Fixed: Side panel stuck on the previous video
Moving between YouTube videos left the side panel showing the previous video's title, Trust Score, and claims. The panel now refreshes when YouTube navigates.
## Fixed: Real page titles before checking
The pre-check screen showed `youtube.com` instead of the video title while the page preview was still loading. It now falls back to the tab's own title first.
## Fixed: YouTube Shorts and browsing pages
YouTube Shorts, the home feed, search, and channel pages were routed to the generic page view instead of the YouTube panel.
## Added: Full transcript coverage on long videos
Transcripts from long videos, roughly an hour or more, are now split into chunks before claim detection. Previously the transcript was sent in a single request and anything past the server's length limit was silently dropped, so claims near the end of a long video were never checked.
## Fixed: Stale results on similar URLs
Moving between pages that differ only by query string or anchor — for example `article?id=1` to `article?id=2` — could show the previous page's results. Those pages are now treated as distinct.
Results also refresh correctly on sites that navigate without a full page load.
# Overview
Source: https://docs.factagora.com/changelog/overview
How Factagora's API and Extension releases are versioned and what gets recorded
## What is a Changelog?
The changelog tracks notable changes to Factagora products, split into two independent release tracks:
* **API** — the Factagora API, for developers integrating against it
* **Extension** — the DeepVerify Chrome extension, for end users
Each track has its own version numbers and its own release list, so an API release and an Extension release with the same version number are unrelated changes.
***
## API Versioning
The API follows [Semantic Versioning](https://semver.org/): `MAJOR.MINOR.PATCH`.
| Part | When to increment | Examples |
| --------- | ------------------------------------------------- | ------------------------------------------------------------ |
| **MAJOR** | Breaking changes: existing client code will break | Removing a field, renaming an endpoint, changing auth method |
| **MINOR** | New features, backwards-compatible | New endpoint, new optional parameter, new response field |
| **PATCH** | Bug fixes, backwards-compatible | Fixing incorrect response data, performance improvements |
Versions in the `0.y.z` range are considered early development, so anything may change. Stability is guaranteed from `1.0.0` onwards.
Only changes to the publicly documented APIs are recorded here. Internal endpoints are excluded.
***
## Extension Versioning
The DeepVerify Chrome extension is versioned by its `manifest.json` version and auto-updates for all users, so there's no compatibility concern to call out — releases just describe what changed.
***
## What Gets Recorded (API)
Changes to the following endpoints are tracked in the API changelog:
| Endpoint | Description |
| ----------------------------------- | ---------------------- |
| `GET /api/v1/fact-search` | Fact Search |
| `POST /api/v1/fact-checker` | Fact Checker |
| `POST /api/v1/evidence-finder` | Evidence Finder |
| `POST /api/v1/deep-research` | Deep Research |
| `POST /api/v1/timeseries` | Timeseries |
| `POST /api/v1/timeseries/file` | Timeseries (file) |
| `POST /api/v1/causality-graph` | Causality Graph |
| `POST /api/v1/causality-graph/file` | Causality Graph (file) |
| `POST /api/v1/fingerprint/embed` | DeepStamp Embed |
| `POST /api/v1/fingerprint/detect` | DeepStamp Detect |
***
## Change Categories
Each release groups changes into the following categories:
| Category | Meaning |
| ------------ | ------------------------------------------------ |
| `Added` | New feature or endpoint |
| `Changed` | Change to existing behavior |
| `Deprecated` | Feature that will be removed in a future version |
| `Removed` | Feature that has been removed |
| `Fixed` | Bug fix |
| `Security` | Security vulnerability addressed |
# Credits & Pricing
Source: https://docs.factagora.com/credits-pricing
Learn how to get and manage your Factagora API Credits.
This page covers the **Factagora API**, which DeepStamp also draws from. **DeepVerify**, the Chrome extension, is billed separately on its own Free / Pro / Max plans — see the [DeepVerify guide](/guides/deepverify/overview).
## Free API Credits
**Get your free API key**: You get 100 welcome API Credits for free. No credit card required. [Get started](https://factagora.com/en/playground)
## Pricing Overview
Factagora operates on a simple, credit-based model:
* **Free**: 100 welcome credits
* **Pay-as-you-go**: \$0.010 per credit
* **Monthly plans**: \$0.0067 – \$0.010 per credit
* **Enterprise**: Custom pricing and volume
| Plan | Monthly Price | Monthly Credits | Price per Credit |
| ------------- | ------------- | --------------- | ---------------- |
| Free | \$0 | 100 (welcome) | - |
| Pay As You Go | Usage-based | - | \$0.010 |
| Project | \$30 | 3,000 | \$0.010 |
| Bootstrap | \$100 | 12,000 | \$0.0083 |
| Startup | \$220 | 30,000 | \$0.0073 |
| Growth | \$500 | 75,000 | \$0.0067 |
| Enterprise | Custom | Custom | Custom |
## API Credit Costs
Each successful API call deducts the credits listed below from your account.
| API | Credits |
| ---------------- | --------- |
| Fact Search | 1 credit |
| Claim Detection | 1 credit |
| Fact Checker | 2 credits |
| Evidence Finder | 2 credits |
| Deep Research | 2 credits |
| Timeseries | 3 credits |
| Causality Graph | 3 credits |
| Crawl | 1 credit |
| DeepStamp Embed | 2 credits |
| DeepStamp Detect | 1 credit |
| Ingest | 2 credits |
Failed requests (`401` authentication errors and `4xx` validation errors) are not charged. Costs apply per call, not per result returned.
# Integration Guide
Source: https://docs.factagora.com/guides/chatgpt/integration-guide
Connect ChatGPT to Factagora and start fact-checking in minutes.
## Overview
Agora turns claims and predictions into interactive knowledge graphs where adversarial AI agents debate opposing viewpoints and generate transparent verdicts. Don't just get an answer, see how it was reached.
Each node represents a claim, piece of evidence, or argument; each connection shows how they relate. Click through the graph to understand the reasoning behind every conclusion.
## Installation
Go to [chatgpt.com/apps](https://chatgpt.com/apps) and search for **Agora**.
Click **Connect** to link the Agora app to your ChatGPT account.
Click **Start chat** to open a new conversation with the integration enabled.
In the chat, mention `@agora` together with your question. The response is returned as a graph visualization of the result.
## Features
TRUE / FALSE / UNCERTAIN with confidence scores from adversarial AI debate.
Credibility-scored sources supporting or opposing the claim.
Multiple AI agents (Skeptic, Analyst, Optimist) argue their positions with cited reasoning.
Navigate the full argument map visually, not just as a list.
## Sample prompts
* "Is nuclear energy the safest large-scale energy source?"
* "Will AGI be achieved before 2040?"
* "Is Trump making money from his presidency?"
Ideal for researchers, journalists, analysts, students, and anyone who wants to understand *why* something is true, not just *that* it is.
## Requirements
* A ChatGPT account with integrations enabled
* A Factagora account (free tier supported)
* Active internet connection
# Automation
Source: https://docs.factagora.com/guides/deepverify/automation
Keyboard shortcuts and the settings that make DeepVerify check content without being asked
By default DeepVerify only checks what you ask it to. A few settings change that, so pages and videos are checked as you browse.
The two automatic-checking settings, **Auto-detect Claims** and **YouTube Auto-Verify**, are **off** out of the box. If you want hands-free checking, turn them on in **Settings**.
## Keyboard shortcuts
| Shortcut | Action |
| ----------------------------- | -------------------------------------------- |
| Alt + F | Open or close the side panel |
| Alt + D | Run DeepVerify on the selected text |
| Alt + T | Start capturing tab audio for a Live session |
These are Chrome's suggested defaults. If another extension has claimed the same combination, reassign them at `chrome://extensions/shortcuts`.
## Check pages automatically
**Settings → Auto-detect Claims** — *Highlight claims as you browse*
With this on, DeepVerify scans pages as you open them and highlights the claims it finds, so you can see what is worth verifying before you start reading. Off by default.
## Check YouTube videos automatically
**Settings → YouTube Auto-Verify** — *Auto-detect and verify claims on YouTube videos*
Starts verification on its own when you open a video, instead of waiting for **Start Verifying**. Off by default.
**Settings → YouTube Fact-Check Card** — *Show verification card below YouTube videos*
Shows the result card in the page under the video, so you can see the Trust Score without opening the side panel.
Revisiting a video you already checked does not re-run verification — the earlier result is shown instead. Use **Check again** when you want a fresh verdict; the previous result is kept so you can compare them in [History](/guides/deepverify/history).
## Check selected text faster
**Settings → Floating Button** — *Show button on text selection*
Puts a small DeepVerify button next to any text you select, so you can check it in one click instead of using the shortcut or the right-click menu. On by default.
The right-click menu entry **DeepVerify with Factagora** is always available and is not affected by this setting.
## Confirm what is being checked
**Settings → Page preview** — *Show a preview card for the current page*
Shows a card with the page's title and thumbnail before a check starts, so you can confirm you are on the page you meant. On by default.
## Next
Every setting in one place
Find checks you ran earlier
# FAQ
Source: https://docs.factagora.com/guides/deepverify/faq
Account, billing, privacy, and how far to trust a verdict.
## Account
Yes. After installing, sign in with your Factagora account. The free plan starts without a card.
factagora.ai is the platform where claims are collected and settled against sources. DeepVerify is the extension that runs those checks on the screen you are already looking at.
When a verdict comes back Uncertain, or you think it is wrong, you can post the claim from DeepVerify to factagora.ai for a deeper check.
## Billing
3 documents a day and 20 a month, with 5 auto-verified claims per document. Live audio is not included and your history stays in your own browser. See [Pricing](/guides/deepverify/pricing) for the full comparison.
One URL is one document, whether that is a web page, a YouTube video, or a Live session. Opening the same page again does not count against your quota a second time.
Your daily limit resets every day and your monthly limit refills on your next billing cycle. If you would rather not wait, move up a plan.
Yes. Billing starts once the first month ends, and you can cancel at any time.
Yes. Changes take effect immediately and billing is prorated.
Not yet. To hear first when team plans arrive, join the [Discord](https://discord.gg/BFRCETaMT).
## Privacy
No. It reads a page's text only where you have turned on automatic checking. With automatic checking off, it only looks at the sentences you select yourself. On sensitive sites, pause the extension from the toolbar icon. See [What DeepVerify reads](/guides/deepverify/overview).
Only for [Live audio](/guides/deepverify/modes/live-audio). You grant the browser permission yourself the first time, and audio is captured only while that feature is running.
In the extension's [History](/guides/deepverify/history) panel and, on paid plans, on your account so it follows you across devices. You can delete any entry at any time, and only you can see it.
## Verdicts
DeepVerify draws on academic databases, established news organizations, government and regulatory sources, and peer-reviewed journals. Each claim is classified as Verified, False, or Uncertain with a confidence score, and every result links back to the sources actually used so you can check the evidence yourself.
For nuanced or fast-moving topics, especially decisions with real financial or reputational stakes, treat a verdict as a strong starting point rather than the final word. [Understanding results](/guides/deepverify/understanding-results) explains how to read one.
When the evidence is not sufficient, a claim is marked Uncertain rather than true or false. To follow whether it gets resolved, post it on factagora.ai.
Post that claim to factagora.ai to have it checked again. You can post it straight from the verdict card.
Web pages, YouTube videos with captions (both uploads and live streams), text you highlight yourself, and live audio from your microphone or the current tab. See [Ways to check](/guides/deepverify/modes/web-pages).
# History
Source: https://docs.factagora.com/guides/deepverify/history
Revisit earlier checks, re-run them, and see whether a verdict has changed
Every check DeepVerify runs is recorded. Open **History** from the icon rail in the side panel.
## What is recorded
One entry per session, whichever surface it came from — a page scan, a selection, a YouTube video, or a Live session. Each entry keeps the claims that were found and every verdict they have received.
Entries show the page or video they came from, the number of claims, how many are still unchecked, and the session's [Trust Score](/guides/deepverify/understanding-results#trust-score).
Selections made on a page you already scanned join that page's existing entry rather than creating a new one, so checking the same article five times leaves one row, not five.
Where history is kept, and whether it follows you between devices, depends on your plan. See [Pricing](/guides/deepverify/overview#pricing).
## Re-running a check
Any claim in History can be checked again. This is the point of keeping the record: a claim that was unverifiable last month may be settled now, and a claim that looked true may not survive later reporting.
Re-running **adds** a verdict rather than replacing the previous one. The card shows the latest verdict, and the earlier ones stay underneath — so you can see that something changed, and when.
For the same reason, re-checking a YouTube video does not overwrite the earlier entry. Both results are kept.
If a re-check fails — no connection, service unavailable — nothing is recorded. A failure never shows up as a verdict that changed.
## Next
What each verdict and score means
Every setting in one place
# Live audio
Source: https://docs.factagora.com/guides/deepverify/modes/live-audio
Transcribe and check speech in real time, from your microphone or the current tab
Live mode transcribes speech as it happens and checks claims as they are spoken. It is for livestreams, webinars, and calls — situations where there is no time to pause and look something up.
Open the **Live** panel from the icon rail in the side panel.
## Choosing a source
| Source | How to start | Captures |
| ---------- | ----------------------------- | -------------------------------------------------- |
| Microphone | Start in the Live panel | Whatever your microphone hears, including the room |
| Tab audio | Alt + T | The sound playing in the current tab |
Microphone capture asks for permission the first time you use it.
Tab audio has to be started with the keyboard shortcut. Chrome only allows a tab to be captured in response to a direct user action, so there is no button for it.
## During a session
Claims are detected and checked automatically as they arrive — there is no **Verify all** step in this mode, because there is no end to wait for.
While a session is running, the Live icon in the rail shows a red dot, so you can tell it is still listening from any panel.
The panel header shows the tab you started from, so a session that has been running a while still says what is being checked.
## After a session
Live sessions are recorded in [History](/guides/deepverify/history) like any other check, with the claims found and their verdicts.
Microphone sessions are labeled by start time, for example `Microphone session · 2:34 PM`, since there is no page they belong to. Tab audio sessions are labeled with the tab's title and URL.
## Plan limits
Live audio is not included on the Free plan. Paid plans include a monthly transcription allowance — see [Pricing](/guides/deepverify/overview#pricing).
## Next
What each verdict and score means
Revisit and re-run earlier checks
# Selected text
Source: https://docs.factagora.com/guides/deepverify/modes/selection
Check one passage instead of the whole page, without leaving the article
When you only doubt one sentence, you do not have to scan the whole article. Select the passage and check just that.
## Three ways to start
All three do the same thing. Use whichever is closest to hand.
| How | When it helps |
| ---------------------------------------------------- | -------------------------------------- |
| Press Alt + D | Fastest once the text is selected |
| Right-click and choose **DeepVerify with Factagora** | Familiar path, no shortcut to remember |
| Click the button that appears next to your selection | Nothing to press or right-click |
The floating button can be turned off in **Settings → Floating Button** if it gets in the way. The shortcut and the right-click menu keep working either way.
## It is a page scan with a narrower range
Selecting text is not a different kind of check. The passage goes through the same pipeline as a full page scan: it is split into individual claims, and each claim is verified on its own.
So selecting a paragraph with three factual statements gives you three verdicts, not one blended judgment on the paragraph.
If the passage contains nothing checkable — an opinion, a question, a heading — you get a message saying so rather than a verdict on text that cannot have one.
## Results accumulate
Selections merge into the same session as the page they came from. Scan a page and then select part of it, or select first and scan afterwards. Either way results add up instead of replacing each other.
[History](/guides/deepverify/history) keeps one entry for the page rather than one per selection, and checking the same URL again does not spend a second document from your plan. See [Pricing](/guides/deepverify/pricing).
## On the page
Claims found from a selection are highlighted in the article just like scanned ones. Hover a highlight for the verdict, confidence score, and sources without opening the side panel. **Open in panel** jumps to the full card.
## Next
Scan a whole article instead
Verdicts, confidence, and the Trust Score
# Web pages
Source: https://docs.factagora.com/guides/deepverify/modes/web-pages
Check a whole article, or just the part of it you select
On an ordinary web page, DeepVerify reads the text, pulls out the statements that can actually be checked, and verifies each one. You can point it at the whole page or at a passage you select.
## Checking a whole page
Click the DeepVerify icon in the toolbar, or press Alt + F.
A preview card shows which page is about to be checked, so you can confirm you are on the right one.
Claims appear one at a time as they are found, each with its verdict. You do not have to wait for the whole page to finish before reading the first result.
## Checking only part of a page
When you only doubt one passage, select it instead of scanning everything. Selecting is a page scan with the range narrowed by you, and the results merge into the same session. See [Selected text](/guides/deepverify/modes/selection).
## Highlights on the page
Checked claims are marked in the article itself, not only in the side panel.
Hover a highlight to see the verdict, confidence score, and the sources behind it without opening the panel. **Open in panel** jumps to the full card.
## Running without being asked
**Auto-detect Claims** scans pages as you open them and highlights what it finds, so you can see what is worth verifying before you start reading. It is off by default — see [Automation](/guides/deepverify/automation).
## Next
Check a video against its captions
What each verdict and score means
# YouTube
Source: https://docs.factagora.com/guides/deepverify/modes/youtube
Check a video against its captions, with claims tied to the moment they are spoken
On a video page, DeepVerify reads the captions, extracts claims along with the timestamp where each was said, and checks them.
Press **Start Verifying** in the side panel, or turn on auto-verify to have it start on its own.
**A video needs captions.** DeepVerify works from the transcript, so a video with no captions or transcript cannot be checked.
Long videos are handled. Transcripts are split into chunks before claim detection, so claims near the end of a multi-hour video are found the same as those at the start. Claims also appear one at a time as each chunk comes back, rather than all at once when the whole transcript is done.
## Timestamps
Every claim is tied to a moment in the video.
* Clicking a claim seeks the player to that point
* The claim currently being spoken is highlighted in the list
## Playback alerts
When the video reaches a claim judged `FALSE`, playback pauses and a warning appears over the player. **View Claims** opens the side panel focused on that claim.
This only happens on videos scoring below 50 on the [Trust Score](/guides/deepverify/understanding-results#trust-score) — the same boundary that separates *Mixed Reliability* from *Low Reliability*. So the videos that interrupt you are the ones already labeled unreliable, and the alerts do not contradict the tier shown on the card.
## The in-page card
A fact-check card can appear below the video itself, showing the Trust Score without opening the side panel. It is on by default and can be turned off in [Settings](/guides/deepverify/settings).
## Pages without a video
YouTube's home feed, search results, and channel pages have no video to check, so DeepVerify treats them as ordinary web pages — you can still check the text on them. See [Web pages](/guides/deepverify/modes/web-pages).
## Re-checking
Returning to a video you already checked shows the earlier result rather than running again. Use **Check again** for a fresh verdict; the previous one is kept so you can see whether anything changed. See [History](/guides/deepverify/history).
## Next
Check speech as it happens
Verify videos without pressing anything
# Overview
Source: https://docs.factagora.com/guides/deepverify/overview
What DeepVerify is and how to install the Chrome extension
## What is DeepVerify?
DeepVerify is Factagora's Chrome extension for fact-checking content in real time as you browse: highlight a claim, scan a whole page, check a YouTube video against its captions, or follow a live conversation, without leaving the tab.
## Installation
Get DeepVerify from the [Chrome Web Store](https://chromewebstore.google.com/detail/deepverify-ai-fact-checke/eajnhepckmoblclljcnhlcofiamhfeel).
Click the DeepVerify icon in your browser toolbar and sign in with your Factagora account. Checking requires an account.
Open an article, press Alt + F to open the side panel, and press **Check this page**. Claims appear one at a time with their verdicts.
## How it works
DeepVerify splits what it does into three steps, and every mode follows the same three.
Text is read from the page, the video's captions, or live speech, and the statements that can actually be checked are pulled out. Opinions and questions are left alone.
Each claim is verified against sources and gets a verdict, a confidence score, and the documents used to reach it.
The individual verdicts roll up into a Trust Score for the page or video, mapped to one of five reliability tiers.
## The side panel
Everything lives in the side panel, reached with the toolbar icon or Alt + F. The icon rail on the right switches between:
| Panel | What it does |
| -------------- | -------------------------------------------------------- |
| **Fact Check** | Check the current page, a selection, or a YouTube video |
| **Live** | Transcribe and check microphone or tab audio as it plays |
| **History** | Revisit earlier checks and re-run them |
| **Settings** | Account, appearance, and automatic-checking options |
## What DeepVerify reads
DeepVerify does not read every page you visit. It reads a page's text only where you have turned on automatic checking. With automatic checking off, it only looks at the sentences you select yourself.
On sensitive sites such as internal documents or account pages, pause the extension from the toolbar icon.
Microphone and tab audio are captured only while a Live session is running, and only after you grant the browser permission the first time.
## Requirements
* Google Chrome version 114 or later
* A Factagora account (free tier supported)
* Active internet connection
* For YouTube: the video must have captions, since checking works from the transcript
## Pricing
DeepVerify is billed separately from the Factagora API, on its own Free / Pro / Max plans. The free tier covers 3 documents a day. See [Pricing](/guides/deepverify/pricing) for the full comparison.
## Next
Page, selection, YouTube, and live audio
Have checks run without pressing anything
Verdicts, Trust Score, and reliability tiers
Revisit and re-run earlier checks
# Pricing
Source: https://docs.factagora.com/guides/deepverify/pricing
DeepVerify plans and what each tier includes.
DeepVerify is billed separately from the Factagora API. It runs on its own Free / Pro / Max subscription rather than on API credits, so using the extension does not draw down your API credit balance.
## Plans
| | Free | Pro | Max |
| ------------------------------------- | --------------------------------------------------- | ------------------------------------------ | ------------------- |
| **Price** | \$0 | $30/mo · $300/yr | $220/mo · $2,200/yr |
| **Documents** | 3/day, 20/month | 10/day, 150/month | 60/day, 1,000/month |
| **Auto-verified claims per document** | 5 | 20 | Unlimited |
| **Live audio** | Not included | 300 min/month | 1,200 min/month |
| **History** | Stored locally only | Synced across devices, with Then/Now | Synced, plus export |
| **Also** | Free re-checks of the same document on the same day | All sources: YouTube, web, selection, Live | Priority processing |
## What counts as a document
A document is one thing you check: a web page, a YouTube video, or a Live session.
**One URL is one document.** Opening the same page again does not count against your quota a second time.
Your daily limit resets every day. Your monthly limit refills on your next billing cycle. If you would rather not wait, move up a plan.
## Changing plans
You can upgrade or downgrade at any time. Changes take effect immediately and billing is prorated.
Team plans are not available yet. To hear first when they are, join the [Discord](https://discord.gg/BFRCETaMT).
Adding a card makes your first month free. See [deepverify.ai/#pricing](https://deepverify.ai/#pricing) for current prices, which take precedence over this table.
## Related
Control when checks run
Separate billing for API and DeepStamp usage
# Settings
Source: https://docs.factagora.com/guides/deepverify/settings
Every DeepVerify setting, what it does, and its default
Open **Settings** from the bottom of the icon rail in the side panel.
## Account
| Setting | Description |
| -------------------- | ------------------------------------------------------------------------- |
| **Log in / Log out** | Your Factagora account. DeepVerify needs you signed in to check anything. |
| **Product emails** | Occasional updates and tips. Off by default. |
## Appearance
| Setting | Description | Default |
| ------------- | -------------------------------------- | ------------------- |
| **Dark Mode** | Dark theme for the side panel | Follows your system |
| **Language** | Side panel language, English or Korean | English |
## Behavior
| Setting | Description | Default |
| ---------------------- | --------------------------------------------------------- | ------- |
| **Floating Button** | Show a DeepVerify button next to text you select | On |
| **Auto-detect Claims** | Highlight claims as you browse, without pressing anything | **Off** |
| **Page preview** | Show a preview card for the current page before checking | On |
## YouTube
| Setting | Description | Default |
| --------------------------- | ------------------------------------------------- | ------- |
| **YouTube Auto-Verify** | Start checking a video as soon as you open it | **Off** |
| **YouTube Fact-Check Card** | Show the result card in the page, below the video | On |
## Keyboard shortcuts
Listed in Settings for reference. To change them, go to `chrome://extensions/shortcuts`.
| Shortcut | Action |
| ----------------------------- | -------------------------------------------- |
| Alt + F | Open or close the side panel |
| Alt + D | Run DeepVerify on the selected text |
| Alt + T | Start capturing tab audio for a Live session |
**Auto-detect Claims** and **YouTube Auto-Verify** are the two settings that change DeepVerify from something you invoke into something that runs on its own. Both are off until you turn them on — see [Automation](/guides/deepverify/automation).
## Support
Settings also links to bug reports, the help guide, and the Factagora web app.
# Understanding results
Source: https://docs.factagora.com/guides/deepverify/understanding-results
How to read a DeepVerify verdict card, the Trust Score, and the reliability tiers
DeepVerify reports at two levels: a **verdict** for each individual claim, and a **Trust Score** summarizing the page or video as a whole.
## The verdict card
Every claim returns a card with the same fields, whichever way it was found.
| Field | Meaning |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| **Verdict** | `TRUE`, `FALSE`, or `UNCERTAIN` |
| **Confidence score** | How sure DeepVerify is in the verdict |
| **Reasoning** | A short explanation of why the verdict was reached |
| **Sources checked** | The documents actually used to reach the verdict |
| **Recheck** | Re-run the same claim any time, for example if new information may have come out |
| **Go deeper** | Send the claim to [factagora.ai](https://factagora.ai) for community debate when the verdict is unclear |
| **Verify** | Shown on claims that were not checked automatically. Click it to check that one claim |
| **Timestamp** | On YouTube and Live claims, the timestamp is clickable and jumps to where the claim was said |
| **Original** | The excerpt as it appears in the source, shown when it differs from the sentence that was checked |
### Claims that were not checked automatically
Each plan checks a set number of claims per document automatically. Everything else is still detected and listed, just without a verdict, and each of those cards carries a **Verify** link so you can spend a check on the ones you care about. See [Pricing](/guides/deepverify/pricing) for the per-plan limits.
### Why the card sometimes shows a different sentence
A sentence like "he said it would double by then" cannot be checked on its own. Before verifying, DeepVerify rewrites the claim into a self-contained version using the surrounding text, and checks that instead. When the two differ, the card shows the rewritten sentence as the claim and the untouched excerpt under **Original**, so you can always trace it back to the page.
### Verdicts
* `TRUE` — the claim is supported by the sources checked
* `FALSE` — the claim is contradicted by the sources checked
* `UNCERTAIN` — the sources checked do not clearly support or contradict the claim
`UNCERTAIN` is not a failure. It most often means the claim cannot stand on its own — for example a sentence referring to "that presentation" cannot be resolved without the surrounding context. If a check fails outright (network error, service unavailable), the claim is left **unchecked** rather than being reported as `UNCERTAIN`, so a failure never quietly lowers your Trust Score.
## Trust Score
A single 0–100 number for the page or video, computed from the verdicts of every claim on it.
```
Trust Score = TRUE / (TRUE + FALSE + UNCERTAIN × 0.5) × 100
```
`UNCERTAIN` claims never count toward the numerator — they are not treated as true — but they add half weight to the denominator. So a page full of unverifiable claims scores lower than one whose claims all check out, without being punished as hard as one that is actively wrong.
If no claim could be decided either way, there is no score to show.
### Reliability tiers
The score maps to one of five tiers, shown with the score on the result card.
| Score | Tier |
| ------ | ------------------------ |
| 90–100 | Highly Reliable |
| 70–89 | Mostly Reliable |
| 50–69 | Mixed Reliability |
| 30–49 | Low Reliability |
| 0–29 | High Misinformation Risk |
The 50 boundary also drives YouTube playback alerts — videos scoring below it pause on false claims, so what you are warned about lines up with the tier you were shown. See [YouTube](/guides/deepverify/modes/youtube#playback-alerts).
## Next
Revisit and re-run earlier checks
Page, selection, YouTube, and live audio
# Embed & Detect
Source: https://docs.factagora.com/guides/factagora/fingerprint/embed-and-detect
Step-by-step guide to embedding and detecting DeepStamp watermarks
## 1. Embed a watermark
Send your content to `/fingerprint/embed` to extract the TKG and embed the watermark.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/fingerprint/embed" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "The European Central Bank raised interest rates by 25 basis points on Thursday, citing persistent core inflation in the eurozone. Analysts at Goldman Sachs expect one more hike before a pause in Q4.",
"content_type": "news",
"metadata": {
"author_id": "editor_jane",
"published_at": "2024-06-15T08:00:00Z",
"source_id": "article_12345"
}
}'
```
```python Python theme={null}
import requests
resp = requests.post(
"https://api.factagora.com/api/v1/fingerprint/embed",
headers={"Authorization": "Bearer fa_your_api_key"},
json={
"content": "The European Central Bank raised interest rates by 25 basis points on Thursday, citing persistent core inflation in the eurozone. Analysts at Goldman Sachs expect one more hike before a pause in Q4.",
"content_type": "news",
"metadata": {
"author_id": "editor_jane",
"published_at": "2024-06-15T08:00:00Z",
"source_id": "article_12345",
},
},
)
data = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/fingerprint/embed", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
content:
"The European Central Bank raised interest rates by 25 basis points on Thursday, citing persistent core inflation in the eurozone. Analysts at Goldman Sachs expect one more hike before a pause in Q4.",
content_type: "news",
metadata: {
author_id: "editor_jane",
published_at: "2024-06-15T08:00:00Z",
source_id: "article_12345",
},
}),
});
const data = await resp.json();
```
### Response
```json theme={null}
{
"watermarked_content": "The European Central Bank raised interest rates by 25 basis points...",
"fingerprint_id": "fp_l1p8OPCwGhvu",
"tkg_snapshot": {
"entities": ["European Central Bank", "Interest rate", "Goldman Sachs"],
"timeseries": ["2024-06-15"],
"relations": [
{ "from": "European Central Bank", "rel": "raises", "to": "Interest rate" }
],
"argument_map": [
{
"premise": "Persistent core inflation in the eurozone",
"evidence": "ECB policy meeting decision",
"conclusion": "Interest rates raised by 25 basis points"
}
]
},
"embed_timestamp": "2024-06-15T08:01:23.456Z",
"meta": { "executionTimeMs": 1234 }
}
```
**Distribute `watermarked_content`, not the original.** The watermarked version looks identical to the original but contains invisible zero-width characters that enable watermark-based detection.
**Store `fingerprint_id`** alongside your internal article ID. You'll need it for re-scoring and reporting.
## 2. Detect content reuse
When you encounter content that looks like it might originate from your article, even if it's been rewritten, send it to `/fingerprint/detect`.
```bash cURL theme={null}
curl -X POST "https://api.factagora.com/api/v1/fingerprint/detect" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "ECB hiked rates 25bp Thursday due to stubborn inflation. Goldman analysts predict one final increase before year-end pause."
}'
```
```python Python theme={null}
resp = requests.post(
"https://api.factagora.com/api/v1/fingerprint/detect",
headers={"Authorization": "Bearer fa_your_api_key"},
json={
"content": "ECB hiked rates 25bp Thursday due to stubborn inflation. Goldman analysts predict one final increase before year-end pause."
},
)
result = resp.json()
```
```typescript TypeScript theme={null}
const resp = await fetch("https://api.factagora.com/api/v1/fingerprint/detect", {
method: "POST",
headers: {
Authorization: "Bearer fa_your_api_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
content:
"ECB hiked rates 25bp Thursday due to stubborn inflation. Goldman analysts predict one final increase before year-end pause.",
}),
});
const result = await resp.json();
```
### Response
```json theme={null}
{
"match_found": true,
"confidence_score": 0.87,
"query_fingerprint_id": "fp_tmpQueryId01",
"matches": [
{
"fingerprint_id": "fp_l1p8OPCwGhvu",
"content_type": "news",
"metadata": { "author_id": "editor_jane", "source_id": "article_12345" },
"embed_timestamp": "2024-06-15T08:01:23.456Z",
"score": 0.87,
"similarity_breakdown": {
"entity_match": 0.92,
"timeseries_match": 1.0,
"causal_pattern_match": 0.78
},
"overlap": {
"entities": ["european central bank", "interest rate", "goldman sachs"],
"timeseries": ["2024-06-15"],
"relations": ["european central bank|raises|interest rate"]
},
"watermark_match": false,
"watermark_correlation": null
}
],
"meta": {
"scanned": 156,
"executionTimeMs": 342,
"weights": { "entity": 0.5, "time": 0.2, "causal": 0.3 },
"watermark_detected": false
}
}
```
Notice that the query text is completely rewritten, "ECB hiked rates 25bp" vs "European Central Bank raised interest rates by 25 basis points", yet the API matched it with 87% confidence by comparing the underlying causal structure.
## 3. Detect with watermark (highest confidence)
If the watermarked version of your content was copied with the invisible characters intact, the watermark layer fires for near-certain provenance:
```json theme={null}
{
"matches": [
{
"fingerprint_id": "fp_l1p8OPCwGhvu",
"score": 0.87,
"watermark_match": true,
"watermark_correlation": 0.98,
...
}
],
"meta": {
"watermark_detected": true
}
}
```
When `watermark_match: true`, the match is cryptographically verified, the exact watermarked content (or a portion of it) was used.
## 4. Tune detection with custom weights
Different content types benefit from different scoring emphasis. Override the defaults when needed:
```json Legal document (emphasize causal structure) theme={null}
{
"content": "...",
"weights": { "entity": 0.3, "time": 0.1, "causal": 0.6 }
}
```
```json Time-sensitive report (emphasize timeline) theme={null}
{
"content": "...",
"weights": { "entity": 0.3, "time": 0.5, "causal": 0.2 }
}
```
The weights used are always echoed back in `meta.weights` so you can verify what was applied.
## 5. Re-score an existing fingerprint
To periodically check if new content matches a fingerprint you already embedded, pass the `fingerprint_id` directly:
```bash theme={null}
curl -X POST "https://api.factagora.com/api/v1/fingerprint/detect" \
-H "Authorization: Bearer fa_your_api_key" \
-H "Content-Type: application/json" \
-d '{"fingerprint_id": "fp_l1p8OPCwGhvu"}'
```
This reuses the stored TKG snapshot without re-extracting, making it faster and ideal for scheduled monitoring.
## Summary
| Step | Endpoint | What it does |
| -------- | -------------------------------------------------- | --------------------------------------------------------- |
| Embed | `POST /fingerprint/embed` | Extracts TKG, embeds watermark, stores fingerprint |
| Detect | `POST /fingerprint/detect` | Runs watermark + TKG matching against stored fingerprints |
| Re-score | `POST /fingerprint/detect` (with `fingerprint_id`) | Re-scores existing fingerprint against new candidates |
# Overview
Source: https://docs.factagora.com/guides/factagora/fingerprint/overview
How DeepStamp protects your content with invisible, structure-based watermarking
**DeepStamp is the product name; the API paths still say `fingerprint`.** Endpoints are `/api/v1/fingerprint/embed` and `/api/v1/fingerprint/detect`, and responses return `fingerprint_id`. There is no `/api/v1/deepstamp/*` endpoint.
## What is DeepStamp?
DeepStamp is Factagora's content provenance API. It solves a fundamental problem: **how do you prove that a piece of content originated from you, even after it's been rewritten, paraphrased, or translated?**
Traditional text-matching tools fail when content is rephrased. DeepStamp works differently, it analyzes the *causal structure* of your content (who did what, when, and why) and embeds an invisible watermark based on that structure. Even if every word is changed, the underlying structure remains detectable.
## How it works
You send your content to `/fingerprint/embed`. The API extracts a **Temporal Knowledge Graph (TKG)**: entities, timelines, causal relations, and argument chains, then embeds an invisible zero-width Unicode watermark seeded by that structure. You get back the watermarked content to distribute.
When you encounter suspicious content, send it to `/fingerprint/detect`. The API runs two independent checks:
1. **Watermark check**: extracts hidden bits and correlates against stored fingerprints (near-certain match)
2. **TKG matching**: compares the causal structure using fuzzy word-level matching (catches paraphrases)
Each match comes with a full breakdown: which entities, time anchors, and causal patterns were shared. This is your evidence trail, auditable and explainable.
## Key capabilities
Word-level fuzzy matching means "EU enacts AI Act" matches "European Union passed AI Act regulation", no exact string match required.
Watermark correlation (cryptographic) + TKG Jaccard (semantic) run independently. Both firing simultaneously makes coincidental overlap statistically implausible.
Scoring weights are automatically tuned: legal documents emphasize causal structure (0.6), news emphasizes entities (0.5), reports balance all three signals.
Every match includes the exact overlap lists, shared entities, timelines, and causal triples, so you can explain *why* two articles matched.
## What's in a TKG snapshot?
The Temporal Knowledge Graph extracted from your content contains four layers:
| Layer | Example | Purpose |
| ---------------- | ---------------------------------------- | --------------------------------------- |
| **Entities** | `Bank of Korea`, `Interest rate` | Who and what are involved |
| **Timeseries** | `2024-03-15` | When events occurred |
| **Relations** | `Bank of Korea → raises → Interest rate` | What happened (cause and effect) |
| **Argument map** | Premise → Evidence → Conclusion chains | Why it happened (macro-level reasoning) |
The argument map is what makes DeepStamp uniquely robust. Two articles about the same event will share entities and dates, but the argument structure, *why* the rate was raised, *what evidence* supports the claim, is the hardest to change in a paraphrase.
## Use cases
* **News agencies**: Detect when your articles are republished without attribution
* **Legal teams**: Prove content provenance in licensing disputes
* **Research organizations**: Track how your findings are cited and reused
* **Content platforms**: Automatically flag potential content reuse at scale
## Next steps
Step-by-step guide with code examples.
Production tips for scoring, filtering, and auditing.
# Overview
Source: https://docs.factagora.com/guides/factagora/search-api/overview
Which Factagora API to use for what, and what each call costs.
The Factagora API is one HTTP interface over the Temporal Knowledge Graph. Every endpoint takes the same `fa_...` key and returns JSON. For what FactBlocks and the TKG are, see [What is Factagora?](/index).
This page is about picking the right endpoint. For request and response details, follow the links into the [API Reference](/api-reference/introduction).
## Choosing an API
| What you want to do | API | Credits |
| --------------------------------------------------- | ------------------------------------------------- | ------------------ |
| Search recent news by meaning, not keywords | [Fact Search](/api-reference/fact-search) | 1 |
| Pull the checkable claims out of a block of text | [Claim Detection](/api-reference/claims-detect) | 1 |
| Verify one specific claim and get a verdict | [Fact Checker](/api-reference/fact-checker) | 2 |
| Gather the evidence for and against a claim | [Evidence Finder](/api-reference/evidence-finder) | 2 |
| Research a topic across many sources at once | [Deep Research](/api-reference/deep-research) | 2 |
| Extract a timeline from a document or URL | [Timeseries](/api-reference/timeseries) | 3 |
| Extract cause-and-effect structure | [Causality Graph](/api-reference/causality-graph) | 3 |
| Fetch a page and get clean Markdown back | [Crawl](/api-reference/crawl) | 1 |
| Put your own content into a private knowledge graph | [Ingest](/api-reference/ingest) | 2 |
| Watermark your content and detect reuse of it | [DeepStamp](/api-reference/fingerprint-embed) | 2 embed / 1 detect |
See [Credits & Pricing](/credits-pricing) for how usage is measured and what happens on failed requests.
## Detect, then verify
Claim Detection and Fact Checker are meant to be used together. Detection takes a page of text and returns the sentences worth checking, each with a `normalized_claim` that resolves pronouns and references. Feed that into Fact Checker rather than the raw sentence, and the verdict has the context it needs.
This is the same pipeline the DeepVerify extension runs.
## Public data or your own
By default the APIs search Factagora's public corpus. If you want answers grounded only in your own material, [Ingest](/api-reference/ingest) puts your URLs, text, or files into a private graph, and [Fact Search](/api-reference/fact-search) reads it back with `source=ingest`.
## Next steps
Get an API key and make your first request.
Parameters, response fields, and language examples for every endpoint.
How usage is measured and what each call costs.
Per-key limits and the headers on every response.
# What is Factagora?
Source: https://docs.factagora.com/index
A verifiable knowledge platform for the AI era
## What Factagora does
AI is advancing at an incredible pace, but the 'Hallucination' problem persists. It's difficult to verify whether AI-generated information is accurate, and once misinformation spreads, it's hard to undo. News, social media, AI chatbots, how can we ensure the reliability of the information we encounter?
Factagora is a verifiable knowledge layer for AI. It turns unstructured text into structured, time-stamped, source-linked facts connected in a Temporal Knowledge Graph, so your AI can answer not just *what* is true, but *when* it was true and *why* it happened.
Keep your LLM, your vector database, and your RAG pipeline. Factagora is the grounding and verification layer you add on top, not a replacement for what you already run. Embeddings find what's *similar*; Factagora verifies what's *true right now* and *why*.
Point-in-time facts mean your AI sees what was true at the moment that matters, with no stale data and no hindsight bias.
Causal links explain *why* something happened, not just *that* it did, so AI can reason, not just retrieve.
Every fact carries its source and a confidence score, so each answer is backed by evidence you can follow.
A verifiable, traceable trail for the work that can't be wrong: finance, legal, healthcare, and compliance.
## Core Components
**FactBlock** is the smallest unit of trusted knowledge. It extracts key facts from unstructured text and structures them with metadata and sources.
**TKG (Temporal Knowledge Graph)** stores each fact as a time-stamped, causally linked proposition. It tracks not just *what* is true, but *when* it was true and *why* it happened, returning only the facts valid at the moment you ask, and linking causes to their effects. This is what lets Factagora answer "when" and "why" questions accurately, without later information leaking into earlier answers.
**DeepVerify** is Factagora's Chrome extension. It pulls the checkable claims out of the page you're reading and verifies each one against trusted sources, right there in the tab.
**DeepStamp** embeds an invisible, cryptographic watermark into your content based on its causal structure, entities, timelines, and argument chains. When that content reappears (even rewritten or paraphrased), DeepStamp detects the original source with high confidence and produces an auditable evidence trail.
**Factagora API** is an AI trust infrastructure that reduces hallucinations by structuring information as Factblocks, each linked to a confidence score, source, and temporal context, powered by the Temporal Knowledge Graph (TKG).
## Where to go
Chrome extension that fact-checks any page, video, or live audio as you browse. No code involved.
Source-backed retrieval, fact-checking, and evidence for your own stack.
Invisible, structure-based watermarking that survives rewriting and paraphrasing.
Connect Factagora to an AI agent.
# Quickstart
Source: https://docs.factagora.com/quickstart
Make your first Factagora API request in minutes
**Get your free API key**: You get 100 welcome API Credits for free. No credit card required. [Get started](https://factagora.com/en/playground)
## Step 1: Login
Sign in or create a free account at [Login](https://factagora.com/login). No credit card required, you get **100 welcome credits** automatically.
## Step 2: Get your API key
Navigate to [Settings → API Keys](https://factagora.com/en/playground/tokens) and generate a new API key.
Your API key will look like this:
```
fa_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
Keep your API key secret. Do not expose it in client-side code or public repositories.
## Step 3: Try it without writing code
If you want to see what an endpoint returns before wiring it into anything, run it in the [Playground](https://factagora.com/en/playground). Pick one of your API keys, fill in the parameters, and press Run. The response comes back in the browser.
The same area also holds **Collections**, where you can build a private knowledge graph from your own documents and ask questions grounded only in it.
Playground calls are real API calls. They deduct credits at the same rate as calls from your own code.
## Step 4: Make your first request
Use the Fact Search API to search for recent news articles.
```bash cURL theme={null}
curl -X GET "https://api.factagora.com/api/v1/fact-search?q=artificial+intelligence" \
-H "Authorization: Bearer fa_your_api_key"
```
```python Python theme={null}
import requests
response = requests.get(
"https://api.factagora.com/api/v1/fact-search",
params={"q": "artificial intelligence"},
headers={"Authorization": "Bearer fa_your_api_key"}
)
print(response.json())
```
```typescript TypeScript theme={null}
const response = await fetch(
"https://api.factagora.com/api/v1/fact-search?q=artificial+intelligence",
{
headers: { Authorization: "Bearer fa_your_api_key" },
}
);
const data = await response.json();
console.log(data);
```
## Step 5: Understand the response
A successful response returns a list of news articles with metadata:
```json theme={null}
{
"query": "artificial intelligence",
"articles": [
{
"title": "OpenAI releases new model",
"url": "https://techcrunch.com/...",
"domain": "techcrunch.com",
"publishedAt": "2025-03-30T12:00:00Z",
"language": "english",
"sourceCountry": "US",
"snippet": "OpenAI has announced...",
"source": "gnews"
}
],
"meta": {
"total": 42,
"executionTimeMs": 312,
"source": "gnews",
"cached": false
}
}
```
## Next steps
You now have a key and a working call. From here:
What each endpoint is for and what it costs.
Parameters, response fields, and language examples for every endpoint.
Watermark your content and detect reuse, even after rewriting.
How usage is measured and what each call costs.
# Rate Limits
Source: https://docs.factagora.com/rate-limits
Rate limits and usage guidelines for the Factagora API
## Overview
The Factagora API enforces rate limits to ensure fair usage and service stability. Limits vary by endpoint type.
| Endpoint type | Limit |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| Light endpoints (`/fact-search`, `/claims/detect`, `/crawl`, `/fingerprint/detect`) | **600 req/min** per API key |
| Heavy endpoints (`/fact-checker`, `/evidence-finder`, `/deep-research`, `/timeseries`, `/causality-graph`, `/ingest`, `/fingerprint/embed`) | **60 req/min** per API key |
## Response Headers
Every API response includes the following headers:
| Header | Description |
| ----------------------- | ------------------------------------------------------- |
| `X-RateLimit-Limit` | Maximum requests allowed per minute |
| `X-RateLimit-Remaining` | Remaining requests in the current window |
| `X-RateLimit-Reset` | Unix timestamp when the current window resets |
| `Retry-After` | Seconds to wait before retrying (only on 429 responses) |
## Rate Limit Exceeded
When you exceed the rate limit, the API returns a `429 Too Many Requests` response:
```json theme={null}
{
"error": "Too Many Requests",
"message": "Rate limit exceeded. Try again in 30s",
"statusCode": 429
}
```
## Handling Rate Limits
Use the `Retry-After` header to wait the appropriate amount of time before retrying:
```python Python theme={null}
import requests
import time
def request_with_retry(url, headers, params):
response = requests.get(url, headers=headers, params=params)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after)
return request_with_retry(url, headers, params)
return response
```
```typescript TypeScript theme={null}
async function requestWithRetry(url: string, headers: Record) {
const response = await fetch(url, { headers });
if (response.status === 429) {
const retryAfter = Number(response.headers.get("Retry-After") ?? 60);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
return requestWithRetry(url, headers);
}
return response;
}
```
If you consistently hit rate limits, consider batching requests or upgrading your plan. See [Credits & Pricing](/credits-pricing) for details.