← Back to docs

RSS Feed Analytics API

Language: EN | EN | SV

RSS Feed Analytics API

Use this feature to generate category-level AI summaries and save multiple named analysis variants per period.

Who Is This For

  • Editors using /feed-admin
  • Teams that want different analysis styles for the same category and time period
  • Authenticated users triggering analysis generation through the web UI

Access

  • Web UI: /feed-admin
  • Requires login + permission:rss
  • Replace-in-place is now visible directly on cached variants for daily, weekly, monthly, and yearly; after generation the page refreshes so the overwritten variant list is shown exactly as stored

Triggering Cron / Manual Runs

You can run analytics in three ways:

  1. Scheduler (cron-managed)
  • Laravel scheduler reads jobs from app/Console/Kernel.php.
  • Current default analytics schedule is rss:generate-analytics --period=daily at 20:00.
  • Typical host cron entry:
* * * * * cd /path/to/tools && php artisan schedule:run >> /dev/null 2>&1

If your environment intentionally runs schedule:run only once per day, run it at 20:00 to match the analytics schedule. Weekly/monthly/yearly can still be run manually when needed.

  1. Manual CLI run
php artisan rss:generate-analytics --period=daily
php artisan rss:generate-analytics --period=weekly
php artisan rss:generate-analytics --period=monthly
php artisan rss:generate-analytics --period=yearly
php artisan rss:generate-analytics --period=all
  1. API trigger (external cron/webhook)
  • Endpoint: POST /api/rss/analytics/run
  • Auth: Authorization: Bearer <ANALYTICS_CRON_SECRET>
curl -X POST "https://tools.tornevall.com/api/rss/analytics/run" \
  -H "Authorization: Bearer YOUR_ANALYTICS_CRON_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"period":"daily","categories":"all","sites":false}'

Accepted period values for CLI/API: daily, weekly, monthly, yearly, all.

Generate Analysis

POST /feed-admin/analytics/generate

Request Fields

  • category (required)
  • period (required): daily, weekly, monthly, yearly
  • model (optional): for example gpt-4o-mini, gpt-4o, gpt-4-turbo
  • language (optional): for example sv, en, de, fr, es
  • variant_title (optional): saved title for this analysis variant
  • tone (optional): for example neutral, critical, humorous, satirical, aggressive, analytical
  • variant_description (optional): what this saved analysis should focus on
  • watch_for (optional): analyst guidance text added to the prompt
  • category_watch_for (optional): category-specific focus text combined with watch_for
  • generate_all_languages (optional, default true): generate all supported languages in one run
  • set_as_default (optional): set this variant as the default public analysis for that period bucket

Example

curl -X POST "https://tools.tornevall.com/feed-admin/analytics/generate" \
  -H "Content-Type: application/json" \
  -H "X-CSRF-TOKEN: YOUR_TOKEN" \
  --cookie "LARAVEL_SESSION=YOUR_SESSION" \
  -d '{
    "category": "Right Wing",
    "period": "weekly",
    "model": "gpt-4o-mini",
    "language": "en",
    "variant_title": "Critical English Variant",
    "tone": "critical",
    "variant_description": "A critical English-language weekly analysis focused on active authors and heavy edits.",
    "watch_for": "Look for escalation language and repeated talking points",
    "set_as_default": false
  }'

Saved Variant Behavior

You can keep multiple saved analyses for the same category and period bucket.

Examples:

  • a default Swedish overview
  • an English critical variant
  • a humorous variant for the same week
  • a yearly long-form trend summary

Default Analysis

If you leave title/description empty, the generation behaves like a generic default analysis.

If a variant is marked as default:

  • it becomes the first selected option on /feed
  • it is preferred in summary views
  • other variants for the same category/period bucket remain available in the dropdown

Multilingual By Default

When generate_all_languages=true, one generation run creates/updates records for all supported languages in the same request cycle.

Current supported language set:

  • sv, en, de, fr, es, da, no

The response includes generated_languages so the UI can show exactly which languages were updated.

Category-Specific Analyst Focus

Each category has its own saved analyst-focus text in /feed-admin.

  • top focus box = global guidance
  • category focus box = category-specific guidance

Both are combined before prompt generation.

Period Bucket Behavior

Generation updates one record per:

  • category
  • period type
  • period bucket
  • analysis variant

Buckets:

  • Daily -> day bucket (example: 2026-03-22)
  • Weekly -> ISO week bucket (example: 2026-W11)
  • Monthly -> month bucket (example: 2026-03)
  • Yearly -> year bucket (example: 2026)

This means:

  • re-running the same weekly variant in the same week updates the same saved row
  • generating a different titled/language/tone variant creates a separate saved variant in that same bucket
  • same behavior applies to daily, monthly, and yearly (same variant + same bucket => replace/update existing row)

Site-Level Analytics Tool

In /feed-admin, you can also generate analyses per site/feed (not only per category).

Site generation endpoint:

POST /feed-admin/analytics/site/generate

Main fields:

  • site_urlid (required)
  • period, model, language, variant_title, tone, variant_description
  • watch_for (global analyst focus)
  • site_watch_for (site-specific focus)

watch_for and site_watch_for are combined in the prompt.

This makes it possible to keep separate site assessments for daily/weekly/monthly/yearly windows.

Public Analytics RSS Selectors

GET /api/rss/feed/{selector} now supports:

  • analytics-daily (alias daily-analytics)
  • analytics-weekly (alias weekly-analytics)
  • analytics-monthly (alias monthly-analytics)
  • analytics-yearly (alias yearly-analytics)
  • analytics-bulk (alias bulk-analytics) for combined daily/weekly/monthly/yearly output

Selector entries are also discoverable from GET /api/rss in urls[].

Public Feed Selection

On /feed, category analytics can expose multiple saved variants through a dropdown.

Each option can reflect:

  • title
  • language
  • tone
  • default status

The selected analysis is rendered directly in the browser, and long analyses can be expanded with Read more / Show less.

Prompt Enrichment

The analysis prompt can now include:

  • analyst guidance (watch_for)
  • requested language
  • requested tone
  • saved variant title and description
  • example entry links
  • source links and feed permalinks
  • activity signals such as active sources/authors and edit-heavy behavior

Output Rendering

Analytics content is stored as markdown and rendered as HTML in:

  • /feed-admin
  • /rss
  • /feed

User Notes

  • Use watch_for to steer the model toward specific concerns.
  • Use variant_title and variant_description when you want a reusable named analysis.
  • Use set_as_default if that variant should be the first public choice.
  • Use yearly mode for long trend snapshots.