Building a Client App
Build apps that search, browse, and manage your Trove knowledge base using the GraphQL API. Authenticate with Clerk, then query the API directly.
Architecture
Section titled “Architecture”Your App --> Clerk SDK (auth) --> Trove GraphQL API --> User's Knowledge BaseYour app uses Clerk’s SDK to authenticate users and obtain session tokens. Those tokens are passed as Bearer tokens to Trove’s GraphQL API, which scopes all queries to the authenticated user’s data.
Authentication
Section titled “Authentication”- Integrate Clerk into your app using their SDK for your platform (React, Swift, Kotlin, Next.js, etc.).
- Obtain a session token from Clerk after the user signs in.
- Pass the token in the
Authorizationheader on every request to Trove.
curl -X POST https://api.ontrove.sh/graphql \ -H "Authorization: Bearer YOUR_CLERK_TOKEN" \ -H "Content-Type: application/json" \ -d '{"query": "{ stats { totalDocuments } }"}'Core Patterns
Section titled “Core Patterns”Search and Display Results
Section titled “Search and Display Results”The most common operation. Returns documents ranked by semantic relevance with snippets.
query Search($query: String!, $limit: Int) { search(query: $query, limit: $limit) { results { document { id title author contentType indexedAt } snippet relevanceScore } totalMatches queryTimeMs }}Document Detail View
Section titled “Document Detail View”Request fullText only when the user navigates to a specific document. This field is lazy-loaded from object storage and is larger than previewText.
query GetDocument($id: ID!) { document(id: $id) { id title url author contentDate fullText wordCount contentType tags connector { name connectorType } }}Connector Management
Section titled “Connector Management”List all data sources and their status.
query MyConnectors { connectors { id name connectorType status documentCount lastSyncedAt }}Paginated Document Browsing
Section titled “Paginated Document Browsing”Browse all documents with offset-based pagination.
query BrowseDocuments($offset: Int, $limit: Int, $sortBy: DocumentSortField) { documents(offset: $offset, limit: $limit, sortBy: $sortBy) { nodes { id title author previewText contentType indexedAt } totalCount hasMore }}Account Stats
Section titled “Account Stats”Get an overview of the knowledge base.
query Stats { stats { totalDocuments totalConnectors activeConnectors documentsByConnectorType { connectorType documentCount } }}Recommended GraphQL Clients
Section titled “Recommended GraphQL Clients”| Platform | Client |
|---|---|
| TypeScript / JavaScript | urql, Apollo Client, or graphql-request |
| Swift | Apollo iOS |
| Kotlin | Apollo Kotlin |
Performance Tips
Section titled “Performance Tips”- Skip
fullTextin list views. UsepreviewTextinstead. Full text loads from R2 and can be large. - Paginate with
limitandoffset. Don’t fetch all documents at once. - Filter by connector or content type. Smaller result sets return faster with smaller payloads.
- Cache connector lists. Connector metadata changes infrequently. Cache it client-side and refresh on user action.
- Use
queryTimeMsfor diagnostics. Search responses include execution time so you can monitor performance.