Articles

Access indexed Discover publications with their metadata, entities and impression observations over time.

The Articles endpoints let you search, retrieve, and trace the appearance history of individual Discover articles. They are read-only GET requests backed by the urls table, and every one requires an API key — send it as an X-API-Key header (or Authorization: Bearer). Keys can be country-restricted; where that changes behaviour it is called out per endpoint.

#List articles

GET/v1/articlesAPI key

Search and page through articles with filters on region, language, domain, category, content type, dates, and enrichment status. The list is region-scoped: pass an explicit region, or omit it and a key locked to exactly one country applies that country implicitly.

Query parameters
regionstringoptional
ISO alpha-2 country code. Validated against the key whitelist; applied implicitly when the key is single-country. Filters country_code.
langstringoptional
Article language code; exact match on article_language.
domainstringoptional
Case-insensitive substring match (ilike %domain%).
categorystringoptional
Exact match on gnl_category (Google News-style category).
content_typestringoptional
Exact match on ai_content_type.
searchstringoptional
Case-insensitive substring; matches url OR title_last.
date_fromstringoptional
Lower bound on first_seen_at (>=). ISO-8601.
date_tostringoptional
Upper bound on first_seen_at (<=). ISO-8601.
has_entitiesbooleanoptional
true keeps only rows with entity_merge_status = SUCCESS; false the complement.
has_summarybooleanoptional
true keeps rows whose summary is not null; false keeps null summaries.
sort_bystringoptionaldefault last_seen_at
One of last_seen_at, first_seen_at, published_at.
sort_orderstringoptionaldefault desc
One of asc, desc.
limitintegeroptionaldefault 50
Page size, 1200.
offsetintegeroptionaldefault 0
Rows to skip, >= 0.
curl
curl "https://d2tr.com/api/v1/articles?region=US&category=Sports&has_summary=true&sort_by=first_seen_at&sort_order=desc&limit=2" \
  -H "X-API-Key: $D2TR_API_KEY"
Response
{
  "articles": [
    {
      "id": "b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d",
      "url": "https://example-sports.com/finals-recap",
      "domain": "example-sports.com",
      "title": "Finals recap: an instant classic",
      "title_en": "Finals recap: an instant classic",
      "publisher": "Example Sports",
      "language": "en",
      "country_code": "US",
      "published_at": "2026-06-28T22:10:00+00:00",
      "first_seen_at": "2026-06-28T22:35:12+00:00",
      "last_seen_at": "2026-06-29T09:02:44+00:00",
      "summary": "A last-second shot decided the championship...",
      "summary_en": "A last-second shot decided the championship...",
      "category": "Sports",
      "content_type": "news_article",
      "author": "Jane Doe",
      "image_url": "https://cdn.example-sports.com/img/finals.jpg",
      "entities_count": 0,
      "observations_count": 0
    }
  ],
  "total": 137,
  "limit": 2,
  "offset": 0
}

#Get an article

GET/v1/articles/{article_id}API key

Full detail for one article, optionally including the markdown body, extracted entities, images, and the assigned trend. A restricted key fetching an article outside its country whitelist gets a 404 (not 403) so existence isn't leaked.

Path & query parameters
article_idstringrequired
Path. Article UUID (urls.id).
include_markdownbooleanoptionaldefault false
When true, populate markdown_content; otherwise null.
include_entitiesbooleanoptionaldefault true
When true, entities is the merged entity array; when false, null.
include_imagesbooleanoptionaldefault true
When true, images is populated; when false, null.
curl
curl "https://d2tr.com/api/v1/articles/b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d?include_markdown=true&include_entities=true" \
  -H "X-API-Key: $D2TR_API_KEY"
Response
{
  "id": "b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d",
  "url": "https://example-sports.com/finals-recap",
  "url_normalized": "example-sports.com/finals-recap",
  "domain": "example-sports.com",
  "title": "Finals recap: an instant classic",
  "publisher": "Example Sports",
  "language": "en",
  "country_code": "US",
  "published_at": "2026-06-28T22:10:00+00:00",
  "author": "Jane Doe",
  "first_seen_at": "2026-06-28T22:35:12+00:00",
  "last_seen_at": "2026-06-29T09:02:44+00:00",
  "summary": "A last-second shot decided the championship...",
  "summary_en": "A last-second shot decided the championship...",
  "title_en": "Finals recap: an instant classic",
  "category": "Sports",
  "category_confidence": 0.94,
  "content_type": "news_article",
  "article_meta": {
    "headline": "Finals recap: an instant classic",
    "description": "How the title was won in the final seconds.",
    "section": "Basketball",
    "date_published": "2026-06-28T22:10:00+00:00",
    "date_modified": "2026-06-28T23:40:00+00:00"
  },
  "markdown_content": "# Finals recap\n\nThe arena fell silent...",
  "entities": [
    {
      "name": "Example City Ballers",
      "normalized_name": "example city ballers",
      "unified_score": 0.87,
      "embedding_similarity": 0.79,
      "source": "razor",
      "entity_types": ["Organization", "SportsTeam"],
      "wikipedia_url": "https://en.wikipedia.org/wiki/Example_City_Ballers",
      "kg": {
        "id": "/g/11abc",
        "name": "Example City Ballers",
        "description": "Professional basketball team",
        "image_url": "https://kg.example.com/ballers.png"
      },
      "url_id": "b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d"
    }
  ],
  "images": [
    {
      "image_url": "https://cdn.example-sports.com/img/finals.jpg",
      "width": 1200,
      "height": 630,
      "content_type": "image/jpeg",
      "storage_urls": {
        "original": "https://<project>.supabase.co/storage/v1/object/public/images/orig/....jpg",
        "w512": "https://<project>.supabase.co/storage/v1/object/public/images/w512/....jpg",
        "w256": "https://<project>.supabase.co/storage/v1/object/public/images/w256/....jpg"
      }
    }
  ],
  "geo_sources": [],
  "trend": {
    "trend_id": "9c8b7a6d-...",
    "label": "Championship finals",
    "state": "active",
    "structural_type": "spike",
    "assignment_method": "embedding",
    "assignment_score": 0.83,
    "assigned_at": "2026-06-29T01:00:00+00:00",
    "trend_role": "core"
  }
}

#Article observations

GET/v1/articles/{article_id}/observationsAPI key

The appearance history for an article — every poll that saw the URL in a Discover feed, enriched with the profile's region, language, and city. Backed by url_observations and sorted newest-first.

Path & query parameters
article_idstringrequired
Path. Article UUID.
date_fromstringoptional
Lower bound on seen_at (>=).
date_tostringoptional
Upper bound on seen_at (<=).
limitintegeroptionaldefault 100
Page size, 1500.
offsetintegeroptionaldefault 0
Rows to skip, >= 0.
curl
curl "https://d2tr.com/api/v1/articles/b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d/observations?limit=3" \
  -H "X-API-Key: $D2TR_API_KEY"
Response
{
  "article_id": "b3f1c2a0-7d4e-4a11-9f0c-1e2d3a4b5c6d",
  "url": "https://example-sports.com/finals-recap",
  "observations": [
    {
      "seen_at": "2026-06-29T09:02:44+00:00",
      "region": "US",
      "lang": "en",
      "city": "New York",
      "position": null,
      "run_id": "run_7f3a..."
    },
    {
      "seen_at": "2026-06-29T06:15:03+00:00",
      "region": "US",
      "lang": "en",
      "city": "Chicago",
      "position": null,
      "run_id": "run_5b2c..."
    }
  ],
  "total": 42,
  "first_seen_at": "2026-06-28T22:35:12+00:00",
  "last_seen_at": "2026-06-29T09:02:44+00:00"
}