SDK & Export API

Filtering, Workspaces and Sync

Last updated June 4, 2026

Filtering, Workspaces and Sync

listArticles and listArticlesRaw accept a ListArticlesParams object. These are the only list options: there is no offset, tag, ordering, or page param. The server always sorts by publishedAt descending.

ParamTypeDefaultNotes
limitnumber50 (server-side)Max number of articles returned.
sincestringnoneISO date string. Returns only articles with publishedAt >= since.
workspaceIdstringnone (all workspaces)Restrict to one workspace by its id.
status'published' \'draft' \'scheduled''published'Which article state to return.
### Workspaces: all by default, scope with workspaceId

Your API key is account-scoped, so it can read every workspace you own. The behavior is:

  • Omit workspaceId and you get articles from all of your workspaces combined. This is the default.
  • Pass workspaceId and results are limited to that single workspace.
ts
// All workspaces (default)
const everything = await rh.listArticles();

// Just one workspace const oneWorkspace = await rh.listArticles({ workspaceId: '665abc123...', });

The value is the workspace's id (its _id). The SDK does not expose a method to list workspaces, and the article shape does not include a workspace field, so get the id from the Workspaces area of your dashboard. If you have a single workspace, or you want every workspace, just omit workspaceId.

status

Only published articles are returned unless you ask otherwise:

ts
const drafts = await rh.listArticles({ status: 'draft' });
const scheduled = await rh.listArticles({ status: 'scheduled' });

getArticleBySlug takes the same status option through its GetArticleParams:

ts
const draft = await rh.getArticleBySlug('work-in-progress', { status: 'draft' });

limit

ts
const latestFive = await rh.listArticles({ limit: 5 });

Incremental sync with since and syncedAt

For a content cache or a search index, fetch only what changed since your last run. Use listArticlesRaw so you can read the server's syncedAt cursor, store it, and pass it as since next time.

ts
let cursor = loadCursor(); // ISO string from your store, or undefined on first run

const { articles, syncedAt } = await rh.listArticlesRaw({ since: cursor, // omit on first run to backfill everything limit: 1000, });

for (const article of articles) { upsertIntoIndex(article); }

saveCursor(syncedAt); // use as since on the next sync

since filters on publishedAt >= since, and syncedAt is the server timestamp of the response, which makes a reliable cursor for the next call.

Was this article helpful?