> For a complete page index of the Captain API documentation, fetch https://docs.filesearch.dev/llms.txt?excludeSpec=true

# Get Publication Feed

GET https://api.filesearch.dev/v2/datasets/odyssey/publications/feed

Chronological, cursor-paginated stream of articles.

Always live: every read builds the feed at request time — articles are gathered from publisher sources, merged, de-duplicated, and sorted by recency. The aggregated listing itself is never cached; only per-article enrichment work is. `fields=ids` is the cheap title-only mode. `fields=full` returns entity-linked articles; articles not yet enriched come back with `enrichment_status="pending"` — the list never enriches a whole page inline. Hydrate individual articles via `GET /v2/datasets/odyssey/publications/articles/{article_id}`, which enriches on demand. `since`/`until` window by time; page via `next_cursor`.

Filters: `publications=` is a cheap publisher allowlist applied before enrichment. `sector=` and `has_entities=` depend on enrichment, so they hydrate the page on demand — the page size is clamped low and each request carries an enrichment budget and wall-clock deadline; when a bound is hit you receive a partial page plus a cursor to continue.

Reference: https://docs.filesearch.dev/reference/datasets/odyssey/feed/publication-feed

## Request

### Query parameters

- `since` (string, optional, nullable) — Start boundary: items at/after this ISO-8601 UTC timestamp
- `until` (string, optional, nullable) — End boundary: items strictly before this ISO-8601 UTC timestamp
- `cursor` (string, optional, nullable) — Opaque next_cursor from a prior page; supersedes until
- `page_size` (integer, optional, default: 100)
- `publications` (list of string, optional, nullable) — Pre-enrichment allowlist: only articles from these publishers (registrable domain, canonical slug, or catalog name)
- `publication` (list of string, optional, nullable) — Singular alias of `publications` (accepted for compatibility; merged with `publications`)
- `sector` (string, optional, nullable) — Filter to articles whose enriched sector matches (hydrates the page on demand; page is clamped + budgeted). Tolerant of case, separators, and shorthand (e.g. `fintech` matches `Financial Services`)
- `has_entities` (boolean, optional, nullable) — Filter to articles that did/didn't resolve any entity (hydrates the page on demand; page is clamped + budgeted)
- `fields` (string, optional, default: full) — 'ids' = titles and ids only (no entity-linking); 'full' = entity-linked articles
- `title_only` (boolean, optional, nullable) — Alias for `fields=ids`: titles + ids only, no entity-linking

## Response

### 200

Successful Response

- `articles` (list of AppApiRoutesV2OdysseyFeedFeedResponseArticlesItems, optional)
- `has_more` (boolean, optional, default: false)
- `next_cursor` (string, optional, nullable)
- `page_size` (integer, optional, nullable)

## Types

### AppApiRoutesV2OdysseyFeedFeedResponseArticlesItems

## Examples

**Response**

```json
{
  "articles": [
    {
      "id": "art_WyJBUlQjMjAyNi0wNy0wMyIsIjIwMjYtMDctMDNUMjE6Mjc6NDIuMzc4NTA2WiMzYjRlNzZiZDQzOGZjMzY0Il0",
      "article_id": "art_3b4e76bd438fc364377055e8ddfff48c",
      "title": "FDA device 510k: Dynamis Robotic Surgical System (LEM Surgical AG)",
      "subhead": null,
      "publication": "openFDA",
      "publisher_domain": "open.fda.gov",
      "publication_slug": "open-fda-gov",
      "label_source": "catalog",
      "author": null,
      "url": "https://www.accessdata.fda.gov/scripts/cdrh/cfdocs/cfpmn/pmn.cfm?ID=K260369",
      "published_at": "2026-07-03T21:27:42.378506Z",
      "topics": null,
      "has_entities": false,
      "enriched": false,
      "detail_url": "/v2/datasets/odyssey/publications/articles/art_WyJBUlQjMjAyNi0wNy0wMyIsIjIwMjYtMDctMDNUMjE6Mjc6NDIuMzc4NTA2WiMzYjRlNzZiZDQzOGZjMzY0Il0",
      "also_reported_by": [],
      "dup_count": 1
    }
  ],
  "has_more": true,
  "next_cursor": "eyJvZmZzZXQiOiAxfQ",
  "page_size": 1
}
```

**SDK Code**

```python Python REST
import requests

BASE_URL = "https://api.filesearch.dev"
API_KEY = "your_api_key"

headers = {"Authorization": f"Bearer {API_KEY}"}

response = requests.get(
    f"{BASE_URL}/v2/datasets/odyssey/publications/feed",
    headers=headers,
    params={"page_size": 1},
    timeout=60.0
)
print(response.json())
```

```typescript TypeScript REST
const BASE_URL = "https://api.filesearch.dev";
const API_KEY = "your_api_key";

const response = await fetch(`${BASE_URL}/v2/datasets/odyssey/publications/feed?page_size=1`, {
    method: "GET",
    headers: { "Authorization": `Bearer ${API_KEY}` }
});
console.log(await response.json());
```