Skip to content

Fact Check ​

Check a factual claim against recent news with /v1/fact-check. Send a statement, an article's text or the id of an article in APITube.

For each claim, the response includes one of 8 verdicts, a confidence score, a short explanation and articles that support or challenge it.

Sign up at APITube to get your API key. Include it with every API request.

Fact Check is a paid feature — it is not available on the Free plan. Each request costs 5 points.

Endpoint ​

GET  /v1/fact-check
POST /v1/fact-check

GET and POST return the same results. Send parameters in the URL with GET or as JSON in the request body with POST. Provide one of id, text, or claim (priority: id > text > claim).

Request Parameters ​

ParameterTypeRequiredDescription
idintegerOne of*An APITube article id. The article is loaded from the archive, and its claims are extracted and verified.
textstringOne of*Raw article text (title + body), 100–10000 characters. Claims are extracted automatically.
claimstringOne of*A single factual statement to verify directly (5–500 characters).
max_claimsintegerNoMaximum number of claims to extract and verify. Values below 1 are raised to 1; values above 5 are reduced to 5. Default: 5.
evidence_per_claimintegerNoMaximum number of evidence articles to retrieve per claim. Values below 1 are raised to 1; values above 20 are reduced to 20. Default: 5.
api_keystringYes**Your API key. Can also be provided via headers.

* Provide exactly one of id, text, or claim. ** Required if not provided in headers.

Each request costs 5 points and requires a paid plan. This endpoint allows 10 requests per minute, in addition to your account's overall rate limit.

How it works ​

  1. Claims — for text/id the claims are extracted automatically; for claim your statement is used directly.
  2. Evidence — for each claim, matching articles are retrieved from the news archive.
  3. Verdict — each claim is assessed strictly against its evidence and assigned one of the verdicts below.

Verdict scale ​

true · mostly_true · mixed · misleading · mostly_false · false · unverified · outdated

  • unverified — not enough evidence in the archive to confirm or refute.
  • outdated — the claim was once true but is contradicted by more recent evidence.

Response Format ​

json
{
  "status": "ok",
  "request_id": "string",
  "input": { "type": "claim", "language": "en" },
  "summary": {
    "overall_verdict": "false",
    "overall_confidence": 0.91,
    "claims_total": 1,
    "claims_checked": 1,
    "verdict_breakdown": { "false": 1 }
  },
  "claims": [
    {
      "claim": "string",
      "normalized_claim": "string",
      "checkworthy": true,
      "verdict": "false",
      "confidence": 0.91,
      "as_of": "2026-06-15",
      "explanation": "string",
      "evidence": [
        {
          "article_id": 0,
          "title": "string",
          "url": "string",
          "source": "string",
          "source_authority": 0,
          "published_at": "string",
          "snippet": "string",
          "stance": "refutes",
          "relevance": 0.88
        }
      ]
    }
  ]
}

Response Fields ​

FieldTypeDescription
statusstringAlways ok on success.
request_idstringUnique identifier for the request.
input.typestringWhich input was used: id, text, or claim.
input.languagestringDetected language of the input.
summary.overall_verdictstringAggregated verdict across all checked claims.
summary.overall_confidencenumberAverage confidence across checked claims (0..1).
summary.claims_totalintegerTotal number of claims returned.
summary.claims_checkedintegerNumber of factual, verifiable claims that were checked.
summary.verdict_breakdownobjectCount of claims per verdict.
claims[].verdictstringOne of the 8 verdicts (see scale above).
claims[].confidencenumberConfidence score for the verdict, from 0 to 1.
claims[].explanationstringWhy this verdict was assigned.
claims[].as_ofstringDate the verdict is valid as of (YYYY-MM-DD).
claims[].checkworthybooleanWhether the claim is an objective, verifiable statement.
claims[].evidence[]arraySupporting/refuting articles with stance (supports/refutes/neutral), relevance (0..1) and source_authority (higher = more authoritative).

Request Examples ​

GET — verify a single claim ​

bash
curl "https://api.apitube.io/v1/fact-check?claim=OpenAI released GPT-5 in 2024&api_key=YOUR_API_KEY"
python
import requests

resp = requests.get(
    "https://api.apitube.io/v1/fact-check",
    params={"claim": "OpenAI released GPT-5 in 2024", "api_key": "YOUR_API_KEY"},
)
print(resp.json())
javascript
const params = new URLSearchParams({
  claim: "OpenAI released GPT-5 in 2024",
  api_key: "YOUR_API_KEY",
});
const resp = await fetch(`https://api.apitube.io/v1/fact-check?${params}`);
console.log(await resp.json());
php
$query = http_build_query([
    "claim" => "OpenAI released GPT-5 in 2024",
    "api_key" => "YOUR_API_KEY",
]);
$data = json_decode(file_get_contents("https://api.apitube.io/v1/fact-check?$query"), true);
print_r($data);
go
package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
)

func main() {
	u, _ := url.Parse("https://api.apitube.io/v1/fact-check")
	q := u.Query()
	q.Set("claim", "OpenAI released GPT-5 in 2024")
	q.Set("api_key", "YOUR_API_KEY")
	u.RawQuery = q.Encode()

	resp, _ := http.Get(u.String())
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var data map[string]any
	json.Unmarshal(body, &data)
	fmt.Println(data)
}
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.apitube.io/v1/fact-check?claim=OpenAI+released+GPT-5+in+2024&api_key=YOUR_API_KEY"))
            .GET()
            .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
text
Write a script in your preferred language that calls the APITube News API:

GET https://api.apitube.io/v1/fact-check?claim=OpenAI released GPT-5 in 2024

Read the API key from an environment variable (do not hardcode it), handle request
errors, and print each claim's verdict, confidence and evidence.
Docs: https://docs.apitube.io/platform/news-api/fact-check

POST — fact-check article text or an article by id ​

bash
# Verify an article already in the corpus by its id
curl -X POST "https://api.apitube.io/v1/fact-check" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "id": 123456789, "max_claims": 5 }'

# Or fact-check raw article text
curl -X POST "https://api.apitube.io/v1/fact-check" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "text": "<article title and body, 100-10000 chars>" }'
python
import requests

resp = requests.post(
    "https://api.apitube.io/v1/fact-check",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"id": 123456789, "max_claims": 5},
)
print(resp.json())
javascript
const resp = await fetch("https://api.apitube.io/v1/fact-check", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ id: 123456789, max_claims: 5 }),
});
console.log(await resp.json());
php
$ch = curl_init("https://api.apitube.io/v1/fact-check");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["X-API-Key: YOUR_API_KEY", "Content-Type: application/json"],
    CURLOPT_POSTFIELDS => json_encode([
        "id" => 123456789,
        "max_claims" => 5,
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data);
go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	payload, _ := json.Marshal(map[string]any{
		"id": 123456789,
		"max_claims": 5,
	})

	req, _ := http.NewRequest("POST", "https://api.apitube.io/v1/fact-check", bytes.NewBuffer(payload))
	req.Header.Set("X-API-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	var data map[string]any
	json.Unmarshal(body, &data)
	fmt.Println(data)
}
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws Exception {
        String payload = "{\"id\": 123456789, \"max_claims\": 5}";
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.apitube.io/v1/fact-check"))
            .header("X-API-Key", "YOUR_API_KEY")
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(payload))
            .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}
text
Write a script in your preferred language that calls the APITube News API:

POST https://api.apitube.io/v1/fact-check
Body (JSON):
{
    "id": 123456789,
    "max_claims": 5
}

Read the API key from an environment variable (do not hardcode it), handle request
errors, and print each claim's verdict, confidence and evidence.
Docs: https://docs.apitube.io/platform/news-api/fact-check

Using Bearer token ​

shell
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.apitube.io/v1/fact-check?claim=The Eiffel Tower is in Paris"

Response Example ​

json
{
  "status": "ok",
  "request_id": "req_abc123def456",
  "input": { "type": "claim", "language": "en" },
  "summary": {
    "overall_verdict": "false",
    "overall_confidence": 0.91,
    "claims_total": 1,
    "claims_checked": 1,
    "verdict_breakdown": { "false": 1 }
  },
  "claims": [
    {
      "claim": "OpenAI released GPT-5 in 2024",
      "normalized_claim": "openai released gpt-5 in 2024",
      "checkworthy": true,
      "verdict": "false",
      "confidence": 0.91,
      "as_of": "2026-06-15",
      "explanation": "Sources report the release of GPT-4o in 2024; a model named GPT-5 was not released that year.",
      "evidence": [
        {
          "article_id": 884412201,
          "title": "OpenAI unveils GPT-4o, its new flagship model",
          "url": "https://example-news.com/openai-gpt4o",
          "source": "example-news.com",
          "source_authority": 92,
          "published_at": "2024-05-13T17:00:00Z",
          "snippet": "OpenAI on Monday announced GPT-4o...",
          "stance": "refutes",
          "relevance": 0.88
        }
      ]
    }
  ]
}

Error Responses ​

Free plan not allowed ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 403,
      "code": "ER0706",
      "message": "Fact-check is not available on the free plan. Please upgrade your subscription.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 403

Missing input ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 400,
      "code": "ER0700",
      "message": "Provide one of the parameters: id, text, or claim.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 400

Article not found (id) ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 404,
      "code": "ER0702",
      "message": "Article with the provided id was not found.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 404

Invalid id ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 400,
      "code": "ER0704",
      "message": "id must be a valid integer.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 400

Invalid text length ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 400,
      "code": "ER0701",
      "message": "text must be between 100 and 10000 characters.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 400

Invalid claim length ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 400,
      "code": "ER0705",
      "message": "claim must be between 5 and 500 characters.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 400

No Points on Account ​

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 402,
      "code": "ER0176",
      "message": "You have no points on your account.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 402

Rate Limit Exceeded ​

Fact Check allows 10 requests per minute.

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 429,
      "code": "ER0203",
      "message": "Rate limit exceeded. You can make 10 requests per minute. Try again in 60 seconds.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 429

Service Unavailable ​

The fact-check service did not respond. Wait a moment and retry.

json
{
  "status": "not_ok",
  "request_id": "req_abc123def456",
  "errors": [
    {
      "status": 502,
      "code": "ER0703",
      "message": "Fact-check service is temporarily unavailable. Please try again later.",
      "links": { "about": "https://docs.apitube.io/platform/news-api/http-response-codes" },
      "timestamp": "2026-06-15T14:30:00Z"
    }
  ]
}

Status Code: 502