Skip to content

GraphQL Queries

All queries require an Authorization: Bearer <token> header. Every query is scoped to the authenticated user’s data.

Semantic search across your knowledge base. Uses vector similarity to find documents matching the meaning of your query, not just keywords.

search(
query: String!
sourceId: ID
sourceType: String
author: String
after: DateTime
before: DateTime
contentType: ContentType
tags: [String!]
feedId: ID
limit: Int = 10
): SearchResults!
ParameterTypeDefaultDescription
queryString!requiredThe search query. Interpreted semantically, not as exact keyword match.
sourceIdIDnullFilter results to a specific source.
sourceTypeStringnullFilter by source type (e.g., "rss", "hacker-news").
authorStringnullFilter by document author.
afterDateTimenullOnly include documents dated after this timestamp.
beforeDateTimenullOnly include documents dated before this timestamp.
contentTypeContentTypenullFilter by content type — see the ContentType enum.
tags[String!]nullFilter to documents matching all specified tags.
feedIdIDnullFilter results to a specific feed within a source.
limitInt10Number of results to return. Maximum 50.

Returns SearchResults containing an array of ranked results, each with a document, snippet, and relevance score.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query Search($q: String!, $limit: Int) { search(query: $q, limit: $limit) { totalMatches queryTimeMs results { relevanceScore snippet document { id title url author contentDate } } } }",
"variables": { "q": "distributed systems consensus", "limit": 5 }
}'

Thematic exploration of your knowledge base. Similar to search but optimized for browsing a topic rather than answering a specific question.

discover(
topic: String!
sourceId: ID
sourceType: String
feedId: ID
limit: Int = 10
): SearchResults!
ParameterTypeDefaultDescription
topicString!requiredThe topic to explore.
sourceIdIDnullFilter results to a specific source.
sourceTypeStringnullFilter by source type.
feedIdIDnullFilter results to a specific feed within a source.
limitInt10Number of results to return. Maximum 50.

Returns SearchResults, the same structure as search.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query Discover($topic: String!) { discover(topic: $topic, limit: 10) { totalMatches results { relevanceScore snippet document { id title url author } } } }",
"variables": { "topic": "machine learning infrastructure" }
}'

Chronological listing of your most recently indexed documents, newest first.

recent(
sourceId: ID
sourceType: String
author: String
since: DateTime
feedId: ID
limit: Int = 15
): [Document!]!
ParameterTypeDefaultDescription
sourceIdIDnullFilter to a specific source.
sourceTypeStringnullFilter by source type.
authorStringnullFilter by document author.
sinceDateTimenullOnly include documents indexed after this timestamp.
feedIdIDnullFilter to a specific feed within a source.
limitInt15Number of documents to return. Maximum 50.

Returns an array of Document objects.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query Recent { recent(limit: 5) { id title author contentDate source { sourceType } } }"
}'

Retrieve a single document by its ID. This is the only query that returns the full document text.

document(id: ID!): Document
ParameterTypeDefaultDescription
idID!requiredThe document ID.

Returns a Document or null if not found.

The fullText field is lazy-loaded from blob storage on demand. Only request it when you need the complete document content. Use previewText for summaries and listings.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query GetDocument($id: ID!) { document(id: $id) { id title url author contentDate previewText fullText wordCount contentType tags metadata } }",
"variables": { "id": "doc_abc123" }
}'

Paginated document listing with filtering and sorting. Use this for building document browsers, filtered views, and data exports.

documents(
sourceId: ID
sourceType: String
author: String
contentType: ContentType
tags: [String!]
after: DateTime
before: DateTime
search: String
sortBy: DocumentSortField = INDEXED_AT
sortOrder: SortOrder = DESC
limit: Int = 25
offset: Int = 0
): DocumentConnection!
ParameterTypeDefaultDescription
sourceIdIDnullFilter to a specific source.
sourceTypeStringnullFilter by source type.
authorStringnullFilter by document author.
contentTypeContentTypenullFilter by content type — see the ContentType enum.
tags[String!]nullFilter to documents matching all specified tags.
afterDateTimenullOnly include documents dated after this timestamp.
beforeDateTimenullOnly include documents dated before this timestamp.
searchStringnullText search filter (keyword match, not semantic).
sortByDocumentSortFieldINDEXED_ATSort field. One of: INDEXED_AT, CONTENT_DATE, TITLE, AUTHOR.
sortOrderSortOrderDESCSort direction. ASC or DESC.
limitInt25Page size. Maximum 100.
offsetInt0Number of documents to skip (offset-based pagination).

Returns DocumentConnection with nodes, totalCount, and hasMore.

Note: Avoid requesting fullText in paginated queries. Each fullText field triggers a read from object storage. Use previewText for listings and fetch full text via the document query for individual documents.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ListDocs($type: String, $limit: Int, $offset: Int) { documents(sourceType: $type, sortBy: CONTENT_DATE, sortOrder: DESC, limit: $limit, offset: $offset) { totalCount hasMore nodes { id title author contentDate contentType tags } } }",
"variables": { "type": "rss", "limit": 20, "offset": 0 }
}'

Retrieve a single source by ID, including its nested statistics and recent activity.

source(id: ID!): Source
ParameterTypeDefaultDescription
idID!requiredThe source ID.

Returns a Source or null if not found. The source type includes nested fields queryable in the same request:

  • feeds: The source’s feeds, each with its own cursor and status.
  • recentDocuments(limit: 5): Latest documents from this source.
  • topAuthors(limit: 20): Most prolific authors in this source.
  • dateRange: Earliest and latest document dates.
  • syncRuns(limit: 5): Recent sync history.
Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query GetSource($id: ID!) { source(id: $id) { id sourceType name status documentCount lastSyncedAt recentDocuments(limit: 3) { id title contentDate } topAuthors(limit: 3) { author documentCount } dateRange { earliest latest } syncRuns(limit: 3) { id status startedAt documentsSynced } } }",
"variables": { "id": "src_abc123" }
}'

List all sources with optional filters by type or status.

sources(
sourceType: String
status: SourceStatus
): [Source!]!
ParameterTypeDefaultDescription
sourceTypeStringnullFilter by source type (e.g., "rss", "hacker-news").
statusSourceStatusnullFilter by status: ACTIVE, PAUSED, ERROR, or SETUP.

Returns an array of Source objects.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ListSources($status: SourceStatus) { sources(status: $status) { id sourceType name status documentCount lastSyncedAt } }",
"variables": { "status": "ACTIVE" }
}'

Retrieve a single feed (a publication/stream within a source) by ID.

feed(id: ID!): Feed
ParameterTypeDefaultDescription
idID!requiredThe feed ID.

Returns a Feed or null if not found — including its watermark (parsed sync position) and recentDocuments.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query GetFeed($id: ID!) { feed(id: $id) { id name status documentCount lastSyncedAt watermark { strategy syncedThrough trackedCount } } }",
"variables": { "id": "feed_def456" }
}'

List feeds, optionally filtered by source or status.

feeds(sourceId: ID, status: FeedStatus): [Feed!]!
ParameterTypeDefaultDescription
sourceIdIDnullOnly include feeds within this source.
statusFeedStatusnullOnly include feeds with this status (ACTIVE, PAUSED, ERROR).

Returns an array of Feed.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query($sourceId: ID) { feeds(sourceId: $sourceId) { id name status documentCount watermark { strategy syncedThrough } } }",
"variables": { "sourceId": "src_abc123" }
}'

Query sync run history across all sources or for a specific source.

syncRuns(
sourceId: ID
status: SyncRunStatus
limit: Int = 20
offset: Int = 0
): [SyncRun!]!
ParameterTypeDefaultDescription
sourceIdIDnullFilter to a specific source.
statusSyncRunStatusnullFilter by status: RUNNING, SUCCESS, ERROR, or CANCELLED.
limitInt20Number of results.
offsetInt0Offset for pagination.

Returns an array of SyncRun objects.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query SyncHistory($sourceId: ID) { syncRuns(sourceId: $sourceId, limit: 10) { id status feedId documentsSynced startedAt completedAt durationMs errorMessage source { id name } } }",
"variables": { "sourceId": "src_abc123" }
}'

Account-level aggregates: total documents, total sources, breakdowns by type, and recent sync activity.

stats: UserStats!

None.

Returns UserStats.

Terminal window
curl -X POST https://api.ontrove.sh/graphql \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "{ stats { totalDocuments totalSources activeSources documentsBySourceType { sourceType documentCount } documentsByContentType { contentType documentCount } recentSyncRuns(limit: 3) { id status startedAt source { name } } } }"
}'