TrendNews API

REST API for reading digest posts and news trends across 110 countries. Format: JSON, UTF-8, all times in UTC.

Quick start

Base URL: https://trendnews.uk.app/api/v1. Sign up, create an API key in your account and send your first request:

curl -H "X-API-Key: YOUR_KEY" "https://trendnews.uk.app/api/v1/posts?country=UA&limit=5"

Countries are given as ISO-2 codes (UA, US, DE, PL…). The full list with feed languages is returned by /api/v1/countries. New posts appear every hour.

Authentication

Every request except /v1/health, must include the API key in a header:

X-API-Key: tn_live_…

Also accepted: Authorization: Bearer tn_live_…. Passing the key in URL parameters is not allowed: it would end up in logs and browser history.

Keep the key on your server. If you embed it in page JavaScript, any visitor can copy it. Route frontend requests through your backend.

Plans and limits

Limits depend on the account's plan. The daily quota is shared by all keys of the account and resets at 00:00 UTC. The per-minute limit applies to each key separately. All plans and prices

OffreRequests per dayRequests per minuteAPI keys
Free1 000601
Pro50 0003005
Business500 0001 20020

The current state is returned in the headers of every response:

HeaderMeaning
X-Planthe account's plan: free, pro ou business
X-Quota-Limitdaily quota of the account
X-Quota-Remainingrequests left for today
X-Quota-Resetseconds until the quota resets (00:00 UTC)
X-RateLimit-Limitper-minute request limit of the key
X-RateLimit-Remainingrequests left in the current minute
Retry-Afteronly with a 429 response: seconds until you can retry

Responses may be cached for up to 60 seconds (Cache-Control: private, max-age=60): data is updated once an hour. Caching also saves your quota.

Response format and errors

A successful response always has the data; lists also have meta with pagination. An error has the error field with a machine-readable code and a message.

// success{ "data": [ … ], "meta": { "total": 856, "limit": 20, "offset": 0, "has_more": true } }

// error{
  "error": {
    "code": "invalid_country",
    "message": "Unknown country code. The list of supported ISO-2 codes: /api/v1/countries"
  }
}
HTTPcodeWhen
400missing_parama required parameter is missing
400invalid_param, invalid_country, invalid_datea parameter has an invalid value or format
401missing_api_keyrequest without a key
401invalid_api_keythe key is invalid or revoked
403account_blockedthe key owner's account is blocked
404not_foundunknown endpoint or the post does not exist
405method_not_alloweda method other than GET
429rate_limitedper-minute request limit exceeded
429quota_exceededthe plan's daily quota is used up (resets at 00:00 UTC)
500server_errorinternal server error

Pagination

Lists return at most limit records (up to 100). To get the next page, increase offset by limit, as long as meta.has_more is true.

Endpoints

GET /api/v1/health no key

Service status

Checks that the API is up and returns the time of the latest post. No key needed — handy for monitoring.

Example response
{
  "data": {
    "status": "ok",
    "last_post_at": "2026-10-24T14:05:09Z",
    "countries": 6,
    "time": "2026-10-24T14:31:38Z"
  }
}
GET /api/v1/countries key required

Countries and languages

All countries we collect news for: ISO-2 code, name, flag, feed language, number of posts and the date of the latest one.

Example response
{
  "data": [
    { "code": "UA", "name": "Україна", "flag": "🇺🇦", "lang": "uk", "post_count": 856, "last_post_date": "2026-10-24" },
    { "code": "SI", "name": "Словенія", "flag": "🇸🇮", "lang": "sl", "post_count": 150, "last_post_date": "2026-10-24" },
    { "code": "GB", "name": "Велика Британія", "flag": "🇬🇧", "lang": "en", "post_count": 284, "last_post_date": "2026-10-24" }
  ]
}
GET /api/v1/categories key required

Country categories

Post categories of a country with the number of posts in each. Category names are in the country's language.

ParameterRequiredDescription
countryyesISO-2 country code (full list: /v1/countries)
Example response
{
  "data": [
    { "slug": "politics", "label": "Politics", "posts": 61 },
    { "slug": "sport", "label": "Sport", "posts": 54 },
    { "slug": "other", "label": "Other", "posts": 48 }
  ],
  "meta": { "country": "GB" }
}
GET /api/v1/posts key required

List posts

Digest posts, newest first. All filters are optional and can be combined.

ParameterRequiredDescription
countrynoISO-2 country code
categorynoCategory slug: politics, economy, war, society, sport, culture, world, tech, other
datenoA specific day, YYYY-MM-DD
fromnoStart of the date range, YYYY-MM-DD (inclusive)
tonoEnd of the date range, YYYY-MM-DD (inclusive)
qnoSearch in title and topic, up to 100 characters
limitnoNumber of items, 1–100; default 20
offsetnoPagination offset; default 0
Example response
{
  "data": [
    {
      "id": 24239,
      "country": "SI",
      "lang": "sl",
      "category": { "slug": "other", "label": "Drugo" },
      "trend": "češka korak bližje ukinitvi prispevka",
      "date": "2026-10-24",
      "title": "Tema dneva: Češka korak bližje ukinitvi prispevka",
      "digest": "»češka korak bližje ukinitvi prispevka« se danes pojavlja v več medijih (2). …",
      "source_count": 2,
      "published_at": "2026-10-24T14:05:09Z",
      "url": "https://trendnews.uk.app/post.php?id=24239"
    }
  ],
  "meta": { "total": 150, "limit": 1, "offset": 0, "has_more": true }
}
GET /api/v1/posts/{id} key required

Single post

Full post data together with the list of original sources it was built from.

ParameterRequiredDescription
idyesPost ID (part of the path)
Example response
{
  "data": {
    "id": 24242,
    "country": "GB",
    "lang": "en",
    "category": { "slug": "sport", "label": "Sport" },
    "trend": "aston villa man city",
    "date": "2026-10-24",
    "title": "Story of the day: Aston villa man city",
    "digest": "One of the day's top stories is “aston villa man city”, reported by 3 sources. …",
    "source_count": 3,
    "published_at": "2026-10-24T14:05:10Z",
    "url": "https://trendnews.uk.app/post.php?id=24242",
    "sources": [
      { "title": "…", "url": "https://www.standard.co.uk/…", "host": "www.standard.co.uk", "sitename": "Evening Standard" }
    ]
  }
}
GET /api/v1/events key required

Events

Events are groups of articles from different outlets about the same thing, with a stable event_id. Reprints, articles from one site and from one wire agency count as one independent source. The trend metric is transparent: mentions over 1/6/24 h, independent sources, velocity; the formula is in meta.trend_formula.

ParameterRequiredDescription
countrynoFeed country, ISO-2
regionnoEvent region: GeoNames code (IN.35) or name (Madhya Pradesh)
citynoEvent city: name (Satna) or GeoNames ID
categorynoCategory slug
langnoLanguage, ISO 639-1
sincenoEvents updated after this moment (UTC); default: the last 48 h
include_routineno1 — renvoyer aussi les contenus de routine (horoscopes, loteries, fêtes du jour, programmes TV, cours quotidiens) ; masqués par défaut, champ routine
min_independentnoMinimum independent sources; default 2
qnoSearch in the event title
sortnotrend (default), recent or sources
limitnoNumber of items, 1–100; default 20
offsetnoPagination offset; default 0
Example response
{
  "data": [
    {
      "id": "ev_k3v9q2m7x1a4d",
      "title": "Satna: Two killed as truck rams bike near Maihar",
      "country": "IN",
      "lang": "en",
      "category": { "slug": "society", "confidence": 0.67 },
      "first_seen": "2026-10-25T09:12:40Z",
      "original_published_at": "2026-10-25T08:41:00Z",
      "last_updated": "2026-10-25T13:05:12Z",
      "articles": 7,
      "sources_total": 6,
      "independent_sources": 4,
      "geo": {
        "source_country": "IN",
        "event": { "country": "IN", "region": "Madhya Pradesh", "region_code": "IN.35", "city": "Satna",
                   "city_geonames_id": 1257806, "lat": 24.6, "lon": 80.83, "confidence": 0.86 }
      },
      "trend": { "mentions_1h": 1, "mentions_6h": 5, "mentions_24h": 7, "independent_sources_24h": 4, "velocity": 2.5, "score": 18.6 },
      "evidence": { "available": true, "version": 2, "computed_at": "2026-10-25T13:20:03Z", "url": "https://trendnews.uk.app/api/v1/events/ev_k3v9q2m7x1a4d/evidence" }
    }
  ],
  "meta": { "total": 1, "limit": 20, "offset": 0, "has_more": false, "sort": "trend",
            "trend_formula": "score = independent_sources_24h × log2(1 + mentions_6h) × (1 + min(velocity, 3) / 3); …" }
}
GET /api/v1/events/{id} key required

Single event

The event with all its articles: publisher, publication date and its quality (from the feed, timezone-corrected, or from the page metadata), when we first saw the article, wire agency and independence group.

ParameterRequiredDescription
idyesEvent ID (part of the path)
Example response
{
  "data": {
    "id": "ev_k3v9q2m7x1a4d",
    "title": "Satna: Two killed as truck rams bike near Maihar",
    "independent_sources": 4,
    "…": "усі поля з /v1/events",
    "sources": [
      { "url": "https://…", "publisher": "Dainik Bhaskar", "title": "…", "lang": "hi",
        "published_at": "2026-10-25T08:41:00Z", "published_at_quality": "page_metadata",
        "first_seen": "2026-10-25T09:12:40Z", "agency": null, "independence_group": 1 },
      { "url": "https://…", "publisher": "…", "agency": "PTI", "independence_group": 2 },
      { "url": "https://…", "publisher": "…", "agency": "PTI", "independence_group": 2 }
    ]
  }
}
GET /api/v1/events/{id}/evidence key required

Event evidence

Faits avec liens vers les sources, citations, contradictions, inconnues, changements depuis la version précédente et longueur de texte conseillée. Deux couches : extractive (tous les forfaits) et affinée par Claude (forfait Business) — voir la section « Événements et preuves » ci-dessous. La première requête met l'événement en file d'attente (202, réessayez dans ~30 s).

ParameterRequiredDescription
idyesEvent ID (part of the path)
sincenoReturn in what_changed every change after this moment (UTC)
layernoCouche de preuves : auto (par défaut), refined (Business uniquement) ou extractive
Example response
{
  "data": {
    "event_id": "ev_k3v9q2m7x1a4d",
    "version": 2,
    "computed_at": "2026-10-25T13:20:03Z",
    "independent_sources": 4,
    "sources_read": 6,
    "full_text_read": 5,
    "layer": "refined",
    "summary": "A speeding truck hit a motorcycle near Maihar in Satna district on Saturday morning, killing two people; police say the driver fled.",
    "facts": [
      { "claim": "Two people were killed when a speeding truck hit a motorcycle near Maihar in Satna district on Saturday morning.",
        "kind": "number", "status": "confirmed", "independent_sources": 3,
        "sources": [ { "url": "https://…", "publisher": "…", "published_at": "2026-10-25T08:41:00Z", "snippet": "…" } ] },
      { "claim": "Police said the truck driver fled the spot.", "kind": "statement", "status": "single_source", "independent_sources": 1, "sources": [ … ] }
    ],
    "quotes": [ { "text": "The driver fled after the accident, a search is under way", "speaker": "SP Ashutosh Gupta", "source": { "url": "https://…", "publisher": "…" } } ],
    "contradictions": [ { "topic": "Three people were injured…", "versions": [ { "claim": "Three people were injured…", "source": "https://…" }, { "claim": "Four people were injured…", "source": "https://…" } ] } ],
    "unknowns": [ { "statement": "The cause of the accident is not yet known.", "source": "https://…" } ],
    "what_changed": { "since_version": 1, "since": "2026-10-25T10:02:11Z",
                      "items": [ { "type": "new_fact", "claim": "Police said the truck driver fled the spot.", "status": "single_source" } ] },
    "suggested_length_words": 250,
    "method": "extractive + LLM: … confirmed = cited in >= 2 independent sources (computed, not by the model)",
    "llm": { "model": "claude-haiku-5-5", "input_tokens": 6050, "output_tokens": 1800 },
    "stale": false
  }
}

Événements et preuves : comment ça marche

La couche des événements regroupe les articles de tous les flux en événements : une information reprise par des dizaines de médias est un seul événement avec un seul event_id. Voici comment chaque champ est calculé, pour que vous puissiez expliquer les données à vos lecteurs.

Événement et event_id

Les articles sont regroupés par sens (embeddings multilingues multilingual-e5) dans une fenêtre de 72 heures au sein du pays du flux. Les mots-clés communs et la géographie sont aussi vérifiés pour ne pas fusionner des événements différents sur un sujet proche. L'event_id (format ev_ + 13 caractères) ne change pas tant que l'événement est mis à jour : les nouveaux articles rejoignent l'événement existant au lieu d'en créer un nouveau.

Indépendance des sources

Les articles partagent un independence_group lorsqu'ils viennent du même site, citent la même agence (Reuters, AP, AFP, PTI, ANI, Ukrinform, etc.) ou sont des copies quasi identiques. sources_total compte tous les médias, independent_sources les groupes indépendants. Une dépêche reprise par vingt sites compte comme une seule source. Par défaut, /v1/events renvoie les événements ayant au moins 2 sources indépendantes (paramètre min_independent).

Date de publication

original_published_at est la date de publication fiable la plus ancienne parmi les sources, first_seen le moment où nous avons vu l'événement pour la première fois. Pour chaque article, published_at_quality indique l'origine de la date : feed — du flux ; feed_timezone_corrected — le flux donnait l'heure locale étiquetée UTC et nous l'avons corrigée selon le fuseau du pays ; page_metadata — des métadonnées de la page ; unknown_used_first_seen — pas de date, l'heure de première détection est utilisée.

Géographie

geo.source_country est le pays du flux où l'article a été publié. geo.event indique où l'événement a eu lieu : pays, région avec un code GeoNames (region_code, p. ex. IN.35 — Madhya Pradesh), ville avec city_geonames_id et coordonnées. Les lieux sont repérés dans les titres et descriptions grâce au référentiel GeoNames (villes de plus de 15 000 habitants et régions, y compris les formes locales). Filtres de /v1/events : region (code ou nom) et city (nom ou identifiant GeoNames). Si le lieu n'est pas déterminé avec assurance, geo.event vaut null.

Langue et catégorie

La langue de chaque article est détectée d'après son texte (fastText) et remplace celle du flux si la confiance est d'au moins 0,8. La langue de l'événement est celle de la majorité de ses articles. La catégorie résulte d'un vote des articles de l'événement ; category.confidence est la part des votes en sa faveur.

Indicateurs de tendance

Le champ trend est transparent : mentions_1h, mentions_6h, mentions_24h sont les nouveaux articles sur 1, 6 et 24 heures, independent_sources_24h les groupes indépendants sur une journée, velocity le rythme des 6 dernières heures par rapport aux 18 précédentes. La formule de score est aussi renvoyée dans meta.trend_formula :

score = independent_sources_24h × log2(1 + mentions_6h) × (1 + min(velocity, 3) / 3)
velocity = (mentions_6h / 6) / ((mentions_24h − mentions_6h) / 18)

Preuves : deux couches

/v1/events/{id}/evidence lit les textes complets de jusqu'à 10 sources (indépendantes d'abord, dans le respect de robots.txt) et renvoie des faits avec liens, citations, contradictions, inconnues, what_changed et suggested_length_words. Ce dernier est une longueur de texte conseillée : elle dépend du nombre de faits confirmés, pour ne pas délayer l'article.

Couche extractive (tous les forfaits) : un fait est une phrase citée mot pour mot d'une source, et les phrases de même sens sont regroupées. confirmed signifie que l'affirmation figure dans au moins deux sources indépendantes, single_source dans une seule, disputed que les sources donnent des chiffres différents.

Couche affinée (forfait Business) : Claude reformule les phrases des sources en faits atomiques et ajoute un court summary neutre. Le modèle ne peut rien ajouter de lui-même : chaque fait doit citer des phrases des sources, un fait sans citation est écarté, snippet est une citation mot pour mot, et le statut confirmed est calculé par le système selon l'indépendance des sources citées, pas par le modèle. Une contradiction n'est signalée que lorsque des sources donnent des valeurs qui s'excluent pour le même fait.

Le paramètre layer : auto (par défaut : couche affinée pour Business, extractive pour les autres forfaits), refined (Business uniquement, sinon 403 plan_required), extractive. Le champ layer de la réponse indique la couche renvoyée. La première requête d'un client Business met l'affinage en file d'attente : pendant sa préparation (généralement moins de 30 s), la couche extractive est renvoyée avec refined_status: processing et l'en-tête Retry-After. Au forfait Pro, vous pouvez essayer la couche affinée : layer=refined pour 20 événements différents par mois (le reste dans l'en-tête X-Refined-Trial-Remaining). Pour les autres forfaits, la réponse contient refined_layer avec un lien vers les forfaits. Le champ llm indique le modèle et le nombre de tokens.

« Confirmé » signifie qu'au moins deux sources indépendantes l'ont rapporté, pas que l'affirmation est vraie. Pour les sujets sensibles, vérifiez les sources d'origine via les liens de sources.

Mise à jour et conservation

Les événements sont recalculés toutes les heures avec la collecte des actualités. Les preuves sont actualisées automatiquement pour les événements ayant 3 sources indépendantes ou plus et pour ceux dont un client Business a demandé l'affinage au cours des dernières 24 heures. stale: true signifie que de nouveaux articles sont arrivés depuis le dernier calcul et qu'une mise à jour est déjà en file d'attente. Articles, événements et preuves sont conservés 3 jours après leur dernière mise à jour ; les posts et tendances, plus longtemps.

Webhooks (Business)

Au lieu d'interroger l'API, recevez un POST avec du JSON à votre adresse https. Configuration dans l'espace client, onglet « Webhooks » : adresse, pays, minimum de sources indépendantes et types d'événements. event.created est envoyé une fois, lorsqu'un événement atteint votre nombre de sources indépendantes ; evidence.updated lorsque ses preuves changent (avec what_changed ; pour Business, la couche affinée si elle existe).

Chaque requête est signée : en-tête X-TrendNews-Signature: t=<heure unix>,v1=<hex>, où v1 = HMAC-SHA256 de <t>.<corps brut> avec votre secret. Vérifiez la signature et rejetez les requêtes de plus de 5 minutes. Répondez en 2xx sous 8 secondes ; sinon nous réessayons après 1, 5, 30, 120 et 360 minutes. X-TrendNews-Delivery est un identifiant unique de livraison contre les doublons.

Exemple de corps event.created :

{
  "type": "event.created",
  "created_at": "2026-10-25T18:04:11Z",
  "data": {
    "id": "ev_aacw4p3jhkye6", "title": "Storm Boelo brings 80mph gusts and travel disruption to Scotland",
    "country": "GB", "lang": "en", "category": "society",
    "first_seen": "2026-10-23T18:16:53Z", "original_published_at": "2026-10-23T18:16:53Z",
    "independent_sources": 17, "sources_total": 22,
    "geo": { "country": "GB", "region": "Scotland", "region_code": "GB.SCT", "city": null },
    "api_url": "https://trendnews.uk.app/api/v1/events/ev_aacw4p3jhkye6",
    "evidence_url": "https://trendnews.uk.app/api/v1/events/ev_aacw4p3jhkye6/evidence",
    "page_url": "https://trendnews.uk.app/event.php?id=ev_aacw4p3jhkye6"
  }
}

Vérification de la signature (PHP) :

$body = file_get_contents('php://input');
preg_match('/t=(\d+),v1=([0-9a-f]{64})/', $_SERVER['HTTP_X_TRENDNEWS_SIGNATURE'] ?? '', $m);
$ok = $m && abs(time() - (int)$m[1]) < 300
   && hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, getenv('TRENDNEWS_WEBHOOK_SECRET')), $m[2]);
if (!$ok) { http_response_code(401); exit; }
$event = json_decode($body, true);   // handle $event['type'] … then
http_response_code(204);

Recherches enregistrées

Une recherche enregistrée est une requête que nous relançons chaque heure sur les nouvelles actualités. Les résultats sont conservés 30 jours et disponibles dans votre RSS privé (rss_url), via l'API et — avec Business — dans un webhook de type watch.match. Limites : Free — 1 recherche, Pro — 10, Business — 100. Créez-les dans votre compte ou via l'API.

Syntaxe : les mots séparés par des espaces doivent tous apparaître (dans le titre ou le chapô) ; "phrase exacte" ; OR pour les alternatives ; -mot pour exclure. Le mode events envoie chaque événement avec une correspondance et au moins min_sources sources indépendantes (2 ou plus) ; le mode articles, chaque nouvel article correspondant.

# create
curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
  -d '{"query": "\"green hydrogen\" OR electrolyser", "countries": ["DE","NL"], "mode": "events", "min_sources": 2}' \
  https://trendnews.uk.app/api/v1/watches

# list, one, delete
curl -H "X-API-Key: $KEY" https://trendnews.uk.app/api/v1/watches
curl -H "X-API-Key: $KEY" https://trendnews.uk.app/api/v1/watches/12
curl -X DELETE -H "X-API-Key: $KEY" https://trendnews.uk.app/api/v1/watches/12

# new hits since the last one you have
curl -H "X-API-Key: $KEY" "https://trendnews.uk.app/api/v1/watches/12/hits?since_id=3051&limit=100"

Exemple de corps watch.match :

{
  "type": "watch.match",
  "created_at": "2026-10-26T19:12:40Z",
  "data": {
    "watch": { "id": 12, "name": "Hydrogen", "query": "\"green hydrogen\" OR electrolyser" },
    "hit": { "kind": "event", "id": "ev_x8ox05csqqyae", "title": "…", "url": "https://trendnews.uk.app/event.php?id=ev_x8ox05csqqyae",
             "country": "DE", "lang": "de", "independent_sources": 3, "published_at": "2026-10-26T17:40:02Z",
             "api_url": "https://trendnews.uk.app/api/v1/events/ev_x8ox05csqqyae" }
  }
}

La première exécution d'une nouvelle recherche remplit le RSS avec les résultats de la dernière journée sans les envoyer au webhook ; ensuite seuls les nouveaux résultats y sont envoyés. Signature et nouvelles tentatives comme pour les autres webhooks.

Marchés

Cours du Bitcoin, d'Ethereum, de Solana, de XRP, de l'or, de l'argent, du pétrole Brent, du S&P 500, du Nasdaq, de l'EUR/USD et de l'USD/UAH avec l'actualité qui les fait bouger. Claude étiquette chaque événement ayant au moins deux sources indépendantes : de quel actif il s'agit, dans quel sens il pousse le cours (up, down, neutral) et son importance (impact 1–3). Cours issus de Binance et Yahoo Finance, actualisés toutes les 15 minutes.

RequêteRenvoie
GET /v1/marketsTous les actifs : cours, variation sur 1 h / 24 h / 7 jours, news_24h — combien d'actualités poussent à la hausse et à la baisse et le solde score de −1 à 1, le dernier mouvement brusque.
GET /v1/markets/{asset}Un actif, ses actualités des hours dernières heures (48 par défaut) et les 5 derniers mouvements brusques.
GET /v1/markets/{asset}/pricesBougies OHLC : res=1h (jusqu'à 120 jours) ou res=1d (jusqu'à 2 ans), paramètre limit.
GET /v1/markets/{asset}/movesMouvements brusques : une bougie horaire au-delà du seuil de l'actif (de 0,5 % pour EUR/USD à 3 % pour Solana et XRP). Claude rédige l'explication uniquement à partir des titres autour du mouvement ; lang — en, uk, es, pt, de, fr.
GET /v1/markets/{asset}/newsActualités sur l'actif avec direction et poids ; paramètres hours et limit.

Actifs : bitcoin, ethereum, solana, xrp, gold, silver, brent, sp500, nasdaq, eurusd, usduah. Les mêmes données sont sur la page https://trendnews.uk.app/markets/.

curl -H "X-API-Key: YOUR_KEY" "https://trendnews.uk.app/api/v1/markets/bitcoin/moves?lang=en&limit=5"

Le lien entre l'actualité et le cours est probable, non prouvé. Ceci n'est pas un conseil en investissement.

MCP pour les agents IA

TrendNews dispose d'un serveur MCP (Model Context Protocol) : un agent IA — Claude, Cursor ou le vôtre — recherche lui-même des événements, lit les preuves avec citations, consulte les tendances et gère les recherches enregistrées. Adresse : https://trendnews.uk.app/mcp (Streamable HTTP). L'autorisation se fait avec la même clé API dans l'en-tête X-API-Key ; chaque appel d'outil compte comme une requête API dans le quota de votre offre.

Outils : search_events, get_event, get_event_evidence, get_trends, list_digests, list_countries, get_markets, explain_price_moves, list_saved_searches, create_saved_search, get_saved_search_hits.

# Claude Code
claude mcp add --transport http trendnews https://trendnews.uk.app/mcp --header "X-API-Key: YOUR_KEY"

# Cursor, Windsurf, Claude Desktop… (mcp.json)
{
  "mcpServers": {
    "trendnews": {
      "url": "https://trendnews.uk.app/mcp",
      "headers": { "X-API-Key": "YOUR_KEY" }
    }
  }
}

Le serveur indique à l'agent que « confirmé » signifie « rapporté par au moins deux sources indépendantes », et non « vrai », et lui demande de citer les sources d'origine.

Code examples

Get the 10 latest economy posts for Ukraine:

curl -H "X-API-Key: $TN_KEY" \
  "https://trendnews.uk.app/api/v1/posts?country=UA&category=economy&limit=10"

Iterate over all result pages:

offset = 0
while True:
    page = requests.get(f"{BASE}/api/v1/posts", params={"country": "GB", "limit": 100, "offset": offset},
                        headers={"X-API-Key": KEY}, timeout=10).json()
    handle(page["data"])
    if not page["meta"]["has_more"]:
        break
    offset += 100

Try it

You can create a key in your account. The request goes straight from your browser. The key is not stored anywhere and is gone after a page reload.