All pages

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

ParameterTypeDescription
tickerstringOnly letters that discuss this company, by its ticker.
firmstring, 1 to 100 charactersOnly letters by this firm, by its name. Spaces at either end don't count, and it can't contain a null character.
limitinteger, 1 to 100, default 10How many results to return, from 1 to 100.
cursorstringThe 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

FieldTypeDescription
lettersarray of LetterNewest first.
tickersmap of TickerEntryEach company the results name, by ticker.
nextCursorstringPass it as cursor for the next page. Left out on the last page.
HeaderSent withDescription
Request-Idevery answerThis request's id, such as req_ followed by 24 letters and digits. Quote it to support.
RateLimit-Policy200, 400, 404, 429, 500, 503Your plan's quotas, per minute and per day (IETF draft-11). It may change to match the RFC.
RateLimit200, 400, 404, 429, 500, 503What each window has left, and the seconds until it resets (IETF draft-11).
WWW-Authenticate401Bearer realm="bullpen.news"
Retry-After429, 503How 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

StatusMeaningCodes
200The answer.
400A 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
401No valid key (unauthorized), or a revoked one (revoked).unauthorized, revoked
403Your account can't use this endpoint now: invite, disabled, terms, no_plan, ended, unpaid or tool.no_plan, ended, unpaid, terms, disabled, invite, tool
404Nothing by that ticker, firm, id or day (not_found).not_found
429Your plan's minute or day limit is reached (minute, day).minute, day
500Something went wrong on bullpen.news (internal).internal
503The 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.