Investor letters
GET /v1/letters
Investor letters (fund and partnership letters) bullpen.news has read, newest first: all of them, only those that discuss a ticker, or only one firm's. Any other parameter is refused.
Parameters
| Parameter | Type | Description |
|---|---|---|
ticker | string | Only letters that discuss this company, by its ticker. |
firm | string, 1 to 100 characters | Only letters by this firm, by its name. Spaces at either end don't count, and it can't contain a null character. |
limit | integer, 1 to 100, default 10 | How many results to return, from 1 to 100. |
cursor | string | The nextCursor a previous call returned, for the next page. Keep the other arguments the same. |
curl "https://api.bullpen.news/v1/letters?limit=2" \
-H "Authorization: Bearer $BULLPEN_KEY"import os, requests
r = requests.get(
"https://api.bullpen.news/v1/letters",
params={"limit": 2},
headers={"Authorization": f"Bearer {os.environ['BULLPEN_KEY']}"},
)
r.raise_for_status()
print(r.json())const r = await fetch('https://api.bullpen.news/v1/letters?limit=2', {
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 |
|---|---|---|
letters | array of Letter | Newest first. |
tickers | map of TickerEntry | Each company the results name, by ticker. |
nextCursor | string | Pass it as cursor for the next page. Left out on the last page. |
| 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/letters?limit=2
{
"letters": [
{
"id": "letter:1249",
"kind": "letter",
"title": "Aristotle Core Bond Fund Commentary",
"firm": "Aristotle Funds",
"period": "3Q26",
"published": "2026-09-30T12:00:00Z",
"wentLive": "2026-10-31T16:30:21Z",
"summary": "Aristotle Core Bond Fund increased investment-grade corporate and agency and non-agency mortgage-backed securities exposure while reducing government and agency holdings. The portfolio favored BBB issuers, securitized credit, higher-quality hyperscalers, global systemically important banks, utilities and select office REITs, while remaining cautious on consumer cyclicals, healthcare and retail.",
"url": "https://cdn.prod.website-files.com/642414d0e893bb832996f598/6ae514b69037df5e7f874c4a_Aristotle%20Core%20Bond%20Fund%20Commentary.pdf",
"companies": []
},
{
"id": "letter:1248",
"kind": "letter",
"title": "Aristotle Short Duration Income Fund Commentary",
"firm": "Aristotle Funds",
"period": "third quarter 2026",
"published": "2026-09-30T12:00:00Z",
"wentLive": "2026-10-31T16:30:26Z",
"summary": "Aristotle Short Duration Income Fund reduced Treasury and bank-loan exposure while adding investment-grade corporates and non-agency mortgages to improve risk-adjusted yield. The portfolio favored BBB corporates, investment-grade CLO debt, senior ABS, banks, utilities, select office REITs and higher-quality hyperscalers, while remaining cautious on consumer cyclical, healthcare and retail-related credits.",
"url": "https://cdn.prod.website-files.com/642414d0e893bb832996f598/6ae5140065ede339eeb64fa7_Aristotle%20Short%20Duration%20Income%20Fund%20Commentary.pdf",
"companies": []
}
],
"tickers": {},
"nextCursor": "WyJsZXR0ZXJzIiwibGV0dGVycyIsIlJCTnZvMVd6WjRvUlJxMFciLDJd"
}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: Letters arrive 3 to 4 weeks after their quarter ends. Up to a minute old.
History: Periods back to 2015 for some firms.
Cost: One call.