Skip to content

Sync API (REST)

The Sync API provides REST endpoints for data ingestion. The Trove desktop app and custom connectors use these to push data into your knowledge base.

All endpoints require an Authorization: Bearer <token> header.

Convention note: The Sync API uses snake_case for request fields (e.g., connector_id, external_id) and camelCase for response fields (e.g., documentsIndexed). This differs from the GraphQL API, which uses camelCase throughout.

Base URL: https://api.ontrove.sh


Batch ingest documents for a connector.

Terminal window
curl -X POST https://api.ontrove.sh/api/sync/documents \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"connector_id": "abc123",
"cursor": "optional-pagination-cursor",
"documents": [
{
"external_id": "post-12345",
"title": "Interesting Article",
"text": "Full text content of the article...",
"url": "https://example.com/blog/post-12345",
"author": "Jane Smith",
"date": "2026-03-25T12:00:00Z",
"content_type": "text",
"tags": ["tech", "ai"],
"metadata": { "likes": 42 }
}
]
}'
FieldTypeRequiredDescription
connector_idstringYesThe connector to ingest documents into.
cursorstringNoPagination cursor for the connector’s sync state.
documentsarrayYesArray of documents. Minimum 1, maximum 50.
FieldTypeRequiredDescription
external_idstringYesUnique identifier from the source system. Used for deduplication.
titlestringNoDocument title.
textstringConditionalFull text content. Required unless audio_url is provided.
audio_urlstringConditionalURL to an audio file for transcription. Required if text is not provided.
urlstringNoSource URL.
authorstringNoDocument author.
datestringNoISO 8601 timestamp for the original publication date.
content_typestringNoContent type label. One of: "text", "transcript", "highlight", "bookmark".
tagsstring[]NoArray of tags.
metadataobjectNoArbitrary key-value metadata.

Documents with the same (connector_id, external_id) pair are skipped. You can safely re-submit documents without creating duplicates.

{
"documentsIndexed": 8,
"documentsSkipped": 2,
"errors": [
{
"external_id": "id5",
"error": "Document has no text"
}
],
"cursor": "next-cursor"
}
FieldTypeDescription
documentsIndexednumberNumber of documents successfully indexed.
documentsSkippednumberNumber of documents skipped (already exist).
errorsarrayPer-document errors. Empty array if all documents succeed.
cursorstringUpdated cursor for the next batch.
StatusCause
400Missing connector_id, empty documents array, more than 50 documents, or missing external_id on a document.
401Missing or invalid authorization token.
404Connector not found.

Enqueue an audio file for transcription via Workers AI. The transcription is processed asynchronously. The resulting text is indexed as a document.

Terminal window
curl -X POST https://api.ontrove.sh/api/sync/audio \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"connector_id": "abc123",
"external_id": "episode-42",
"audio_url": "https://example.com/episode.mp3",
"title": "Episode 42: The Future of AI",
"author": "Podcast Host",
"date": "2026-03-25T12:00:00Z",
"metadata": { "duration": 3600 }
}'
FieldTypeRequiredDescription
connector_idstringYesThe connector this audio belongs to.
external_idstringYesUnique identifier from the source system.
audio_urlstringYesURL to the audio file (MP3, WAV, etc.).
titlestringNoTitle for the transcribed document.
authorstringNoAuthor or speaker.
datestringNoISO 8601 timestamp.
metadataobjectNoArbitrary metadata (e.g., duration, episode number).
{
"status": "queued",
"message": "Transcription workflow enqueued"
}

The audio is processed asynchronously by a Cloudflare Workflow. Once transcription completes, the resulting text is indexed as a document under the specified connector.


Connector health overview. Returns a summary of all connectors and total document count.

Terminal window
curl https://api.ontrove.sh/api/sync/status \
-H "Authorization: Bearer YOUR_TOKEN"
{
"connectors": [
{
"id": "abc123",
"connector_type": "rss",
"name": "Tech Blogs",
"status": "active",
"document_count": 342,
"last_synced_at": "2026-03-25T10:00:00Z"
},
{
"id": "def456",
"connector_type": "hacker-news",
"name": "Bookmarks",
"status": "active",
"document_count": 1158,
"last_synced_at": "2026-03-25T09:30:00Z"
}
],
"total_documents": 1500
}
FieldTypeDescription
connectorsarraySummary of each connector.
connectors[].idstringConnector ID.
connectors[].connector_typestringConnector type.
connectors[].namestringConnector display name.
connectors[].statusstringCurrent status ("active", "paused", "error", "setup").
connectors[].document_countnumberNumber of documents from this connector.
connectors[].last_synced_atstringISO 8601 timestamp of the last successful sync.
total_documentsnumberTotal documents across all connectors.

Delete a single document from all storage layers (D1, R2, Vectorize). This action is irreversible.

Terminal window
curl -X DELETE https://api.ontrove.sh/api/sync/documents/doc_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
{
"deleted": true,
"document_id": "doc_abc123"
}
{
"error": "Document not found: doc_abc123"
}