Filter News by Reading Level
Every article is scored for reading difficulty during enrichment, and those scores are filterable. Use them to build a feed for language learners, a children's news app, or the opposite — a feed of dense, expert-level analysis. The full parameter set lives in Readability Filters.
Step 1: Pick a difficulty band
The quickest way in is readability.difficulty — four named bands mapped to school grade ranges: beginner (below grade 6), intermediate (6–10), advanced (10–14), expert (14+). readability.audience says the same thing in terms of who the text is for: children, general, professional, academic.
curl "https://api.apitube.io/v1/news/everything?readability.difficulty=beginner&language.code=en&per_page=20&api_key=YOUR_API_KEY"import requests
response = requests.get(
"https://api.apitube.io/v1/news/everything",
params={
"readability.difficulty": "beginner",
"language.code": "en",
"per_page": "20",
"api_key": "YOUR_API_KEY",
},
)
print(response.json())const params = new URLSearchParams({ "readability.difficulty": "beginner", "language.code": "en", "per_page": "20", "api_key": "YOUR_API_KEY" });
const response = await fetch(`https://api.apitube.io/v1/news/everything?${params}`);
const data = await response.json();
console.log(data);$query = http_build_query(["readability.difficulty" => "beginner", "language.code" => "en", "per_page" => "20", "api_key" => "YOUR_API_KEY"]);
$response = file_get_contents("https://api.apitube.io/v1/news/everything?$query");
$data = json_decode($response, true);
print_r($data);package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
u, _ := url.Parse("https://api.apitube.io/v1/news/everything")
q := u.Query()
q.Set("readability.difficulty", "beginner")
q.Set("language.code", "en")
q.Set("per_page", "20")
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)
}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/news/everything?readability.difficulty=beginner&language.code=en&per_page=20&api_key=YOUR_API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Write a script in your preferred language that calls the APITube News API:
GET https://api.apitube.io/v1/news/everything?readability.difficulty=beginner&language.code=en&per_page=20
Read the API key from an environment variable (do not hardcode it), handle request
errors, and print the key fields of each result.
Docs: https://docs.apitube.io/platform/news-api/parametersEach article carries the scores it was matched on, so you can show them in the UI:
{
"readability": {
"flesch_kincaid_grade": 8,
"flesch_reading_ease": 100,
"automated_readability_index": 8.8,
"difficulty_level": "intermediate",
"target_audience": "general",
"reading_age": 13,
"avg_words_per_sentence": 60.5
}
}- Grade level —
readability.flesch_kincaid_grade, the US school grade needed to follow the text. - Ease score —
readability.flesch_reading_ease, 0–100, where higher is easier. - Reading age —
readability.reading_age, in years. - Band labels —
readability.difficulty_levelandreadability.target_audience, the same vocabulary you filtered with.
Step 2: Tune the band to an exact range
The named bands are wide. For a precise cut use the numeric filters, each with .min and .max variants: readability.fk_grade (0–30), readability.ease (0–100), readability.ari (0–30), readability.age (6–22).
curl "https://api.apitube.io/v1/news/everything?readability.fk_grade.min=6&readability.fk_grade.max=10&readability.ease.min=60&language.code=en&per_page=20&api_key=YOUR_API_KEY"import requests
response = requests.get(
"https://api.apitube.io/v1/news/everything",
params={
"readability.fk_grade.min": "6",
"readability.fk_grade.max": "10",
"readability.ease.min": "60",
"language.code": "en",
"per_page": "20",
"api_key": "YOUR_API_KEY",
},
)
print(response.json())const params = new URLSearchParams({ "readability.fk_grade.min": "6", "readability.fk_grade.max": "10", "readability.ease.min": "60", "language.code": "en", "per_page": "20", "api_key": "YOUR_API_KEY" });
const response = await fetch(`https://api.apitube.io/v1/news/everything?${params}`);
const data = await response.json();
console.log(data);$query = http_build_query(["readability.fk_grade.min" => "6", "readability.fk_grade.max" => "10", "readability.ease.min" => "60", "language.code" => "en", "per_page" => "20", "api_key" => "YOUR_API_KEY"]);
$response = file_get_contents("https://api.apitube.io/v1/news/everything?$query");
$data = json_decode($response, true);
print_r($data);package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
u, _ := url.Parse("https://api.apitube.io/v1/news/everything")
q := u.Query()
q.Set("readability.fk_grade.min", "6")
q.Set("readability.fk_grade.max", "10")
q.Set("readability.ease.min", "60")
q.Set("language.code", "en")
q.Set("per_page", "20")
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)
}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/news/everything?readability.fk_grade.min=6&readability.fk_grade.max=10&readability.ease.min=60&language.code=en&per_page=20&api_key=YOUR_API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Write a script in your preferred language that calls the APITube News API:
GET https://api.apitube.io/v1/news/everything?readability.fk_grade.min=6&readability.fk_grade.max=10&readability.ease.min=60&language.code=en&per_page=20
Read the API key from an environment variable (do not hardcode it), handle request
errors, and print the key fields of each result.
Docs: https://docs.apitube.io/platform/news-api/parametersTwo shortcuts cover the common cases without any numbers: is_easy_read=1 keeps articles with a Flesch Reading Ease of 60 or above, and is_difficult_read=1 keeps everything below 40.
Step 3: Cap the reading time and stack the rest of your filters
Reading level answers "can they understand it"; read_time answers "will they finish it". Combine both, then add whatever topical filters your product needs.
curl "https://api.apitube.io/v1/news/everything?readability.difficulty=beginner&read_time.max=3&language.code=en&category.id=medtop:15000000&per_page=20&api_key=YOUR_API_KEY"import requests
response = requests.get(
"https://api.apitube.io/v1/news/everything",
params={
"readability.difficulty": "beginner",
"read_time.max": "3",
"language.code": "en",
"category.id": "medtop:15000000",
"per_page": "20",
"api_key": "YOUR_API_KEY",
},
)
print(response.json())const params = new URLSearchParams({ "readability.difficulty": "beginner", "read_time.max": "3", "language.code": "en", "category.id": "medtop:15000000", "per_page": "20", "api_key": "YOUR_API_KEY" });
const response = await fetch(`https://api.apitube.io/v1/news/everything?${params}`);
const data = await response.json();
console.log(data);$query = http_build_query(["readability.difficulty" => "beginner", "read_time.max" => "3", "language.code" => "en", "category.id" => "medtop:15000000", "per_page" => "20", "api_key" => "YOUR_API_KEY"]);
$response = file_get_contents("https://api.apitube.io/v1/news/everything?$query");
$data = json_decode($response, true);
print_r($data);package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
u, _ := url.Parse("https://api.apitube.io/v1/news/everything")
q := u.Query()
q.Set("readability.difficulty", "beginner")
q.Set("read_time.max", "3")
q.Set("language.code", "en")
q.Set("category.id", "medtop:15000000")
q.Set("per_page", "20")
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)
}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/news/everything?readability.difficulty=beginner&read_time.max=3&language.code=en&category.id=medtop:15000000&per_page=20&api_key=YOUR_API_KEY"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}Write a script in your preferred language that calls the APITube News API:
GET https://api.apitube.io/v1/news/everything?readability.difficulty=beginner&read_time.max=3&language.code=en&category.id=medtop:15000000&per_page=20
Read the API key from an environment variable (do not hardcode it), handle request
errors, and print the key fields of each result.
Docs: https://docs.apitube.io/platform/news-api/parametersA learner app usually wants a ladder rather than a single band, so users can move up as they improve:
import requests
LEVELS = {
"A2": {"readability.fk_grade.max": 5},
"B1": {"readability.fk_grade.min": 5, "readability.fk_grade.max": 8},
"B2": {"readability.fk_grade.min": 8, "readability.fk_grade.max": 11},
"C1": {"readability.fk_grade.min": 11},
}
def feed(level, api_key, language="en", limit=20):
params = {"language.code": language, "per_page": limit, "api_key": api_key, **LEVELS[level]}
return requests.get("https://api.apitube.io/v1/news/everything", params=params).json()["results"]Tip: readability is computed per article, not per source, so an outlet that usually writes for a general audience will still surface the occasional dense piece. Filter on the score, not on the publisher.