---
title: "Cron News Sentiment Backfill"
method: POST
path: "/cron/news-sentiment-backfill"
tags: ["cron"]
---

# Cron News Sentiment Backfill

`POST /cron/news-sentiment-backfill`

## Request

- Base URL: `https://api.equity-rank.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.equity-rank.com/cron/news-sentiment-backfill`
- Auth: none declared

One bounded, resumable slice of the 365-day news-sentiment backfill (NEWS-02).
Auth: X-Cron-Secret.

Invoke repeatedly. Each call derives every symbol's resume point from
`news_sentiment_coverage` / `news_sentiment_daily` themselves — no cursor
table that could disagree with the data — skips the symbols already current,
and works the rest in ticker order until `chunk_size` symbols are done or
`max_minutes` elapses. Both bounds exist because the screener batch and the
overnight prefetch own the shared 26.67 req/s AlphaVantage bucket from ~02:00
to ~23:30 UTC; an unbounded run would not fail, it would make the 06:00 batch
late. The returned run reports `stopped_because` — `chunk_size`,
`max_minutes`, `universe_exhausted` or `universe_exhausted_with_errors`;
only `universe_exhausted`, with `symbols_remaining == 0`, means the backfill
is finished. The `_with_errors` form is terminal too (nothing is left to
claim) but it is NOT completion: `symbols_failed` symbols were claimed and
left without ground, so it is to be reported, not read as a clean stop.

Sizing (measured in plan 94-02): >=13 provider calls per symbol per year,
~3x that on a name whose every month saturates the 1,000-item cap, over
~3,300 tickers — so roughly 43k-129k calls across the whole campaign, not
one long run. Duplicate-safe: a second invocation while one is in flight
gets `cron_runs.status='skipped'` from _run_tracked's atomic claim.

## Headers

- `x-cron-secret` string, nullable

## Request body

- NewsSentimentBackfillRequest: Body for one bounded slice of the Phase 94 news-sentiment backfill. Every field is optional; omitting one takes the Railway-tunable default (NEWS_BACKFILL_CHUNK_SIZE / NEWS_BACKFILL_MAX_MINUTES / NEWS_INGEST_CONCURRENCY).
  - `chunk_size` integer, nullable
  - `max_minutes` number, nullable
  - `tickers` string[], nullable
  - `horizon_days` integer
  - `concurrency` integer, nullable

## Response `202`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/equity-rank/apis/equity-rank-api.md) · [All operations](https://skmtc.dev/equity-rank/apis/equity-rank-api/llms.txt) · [OpenAPI document](https://skmtc.dev/equity-rank/apis/equity-rank-api/revisions/c2f2463fee33?raw)
