---
title: "Cron Portfolio Email"
method: POST
path: "/cron/portfolio-email"
tags: ["cron"]
---

# Cron Portfolio Email

`POST /cron/portfolio-email`

## 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/portfolio-email`
- Auth: none declared

Build + send the owner's Daily Portfolio Update email.

Reads owner_portfolio holdings, joins fresh screener_cache signals, and emails
settings.digest_recipient. Owner-only; uses the compliant OVERWEIGHT / NEUTRAL /
UNDERWEIGHT labels (no BUY/SELL). Runs synchronously so a manual caller sees the
full result.

Schedule: Mon–Fri 07:00 UTC via APScheduler (after the 06:00 screener batch).
dry_run=true: render + return a preview WITHOUT sending or persisting last_signal.
Auth: X-Cron-Secret.

## Query parameters

- `dry_run` boolean

## Headers

- `X-Cron-Secret` string, nullable

## Response `200`

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)
