Daily recap
GET /v1/recap
The daily recap email for a day, in full: every story, X post, video and investor letter it listed, by section. Without day, the newest recap, ordinarily yesterday's. Any other parameter is refused.
Parameters
| Parameter | Type | Description |
|---|---|---|
day | string | The recap for this day, as YYYY-MM-DD in New York time. Leave it out for the newest recap, ordinarily yesterday's. It must be a real date, and not after today. |
section | string, 1 to 100 characters | Only this section of the recap, by its name. Spaces at either end don't count, and it can't contain a null character. |
curl "https://api.bullpen.news/v1/recap?day=2026-10-30§ion=Materials" \
-H "Authorization: Bearer $BULLPEN_KEY"import os, requests
r = requests.get(
"https://api.bullpen.news/v1/recap",
params={"day": "2026-10-30", "section": "Materials"},
headers={"Authorization": f"Bearer {os.environ['BULLPEN_KEY']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch('https://api.bullpen.news/v1/recap?day=2026-10-30§ion=Materials', {
headers: { Authorization: `Bearer ${process.env.BULLPEN_KEY}` }
});
if (!r.ok) throw new Error((await r.json()).detail);
console.log(await r.json());What comes back
| Field | Type | Description |
|---|---|---|
day | string (date) | The day the recap covers, YYYY-MM-DD in New York time. Without a day in the call, the newest recap. |
subject | string | The email's subject line. |
headline | string | The email's preview line, shown under the subject in an inbox. |
bullpenUrl | string | The recap on bullpen.news. |
sections | array of object | The email's sections in its order, or only the one asked for. Anything taken off bullpen.news since it was sent is left out. |
sections[].name | string | The section as the email headed it, such as Technology and AI. |
sections[].results | array of Story, XPost, Video or Letter | Its stories, X posts, videos and investor letters, in the order the email listed them. |
tickers | map of TickerEntry | Each company the results name, by ticker. |
| Header | Sent with | Description |
|---|---|---|
Request-Id | every answer | This request's id, such as req_ followed by 24 letters and digits. Quote it to support. |
RateLimit-Policy | 200, 400, 404, 429, 500, 503 | Your plan's quotas, per minute and per day (IETF draft-11). It may change to match the RFC. |
RateLimit | 200, 400, 404, 429, 500, 503 | What each window has left, and the seconds until it resets (IETF draft-11). |
WWW-Authenticate | 401 | Bearer realm="bullpen.news" |
Retry-After | 429, 503 | How many seconds to wait. |
GET /v1/recap?day=2026-10-30§ion=Materials
{
"day": "2026-10-30",
"subject": "Bullpen.News, Friday October 30th: 92 stock ideas",
"headline": "92 stock ideas from 20 stories, 33 X posts and 8 investor letters.",
"bullpenUrl": "https://bullpen.news/recap/2026-10-30",
"sections": [
{
"name": "Materials",
"results": [
{
"id": "x:5274458",
"kind": "x_post",
"postId": "2116317834792034350",
"url": "https://x.com/i/web/status/2116317834792034350",
"published": "2026-10-30T23:54:25Z",
"wentLive": "2026-10-30T23:56:13Z",
"companies": [
"ELMT"
]
}
]
}
],
"tickers": {
"ELMT": {
"name": "Elmet Group Co.",
"sector": "Materials",
"marketCapUsd": 688080000,
"bullpenUrl": "https://bullpen.news/ticker/ELMT"
}
}
}Status codes
| Status | Meaning | Codes |
|---|---|---|
200 | The answer. | |
400 | A parameter is invalid or unknown (invalid_request), a key is in the URL (key_in_url), or a cursor is not this call's (invalid_cursor). | key_in_url, invalid_request, invalid_cursor |
401 | No valid key (unauthorized), or a revoked one (revoked). | unauthorized, revoked |
403 | Your account can't use this endpoint now: invite, disabled, terms, no_plan, ended, unpaid or tool. | no_plan, ended, unpaid, terms, disabled, invite, tool |
404 | Nothing by that ticker, firm, id or day (not_found). | not_found |
429 | Your plan's minute or day limit is reached (minute, day). | minute, day |
500 | Something went wrong on bullpen.news (internal). | internal |
503 | The API is paused (off), busy (ceiling) or having trouble (unavailable). Retry-After comes with all but off. | ceiling, off, unavailable |
Fresh: The newest recap goes out each morning. A past day never changes.
History: Every day from 7 September 2026.
Cost: One call, for the whole issue.