REST APIAPI Reference
Complete reference for the Rasepi REST API. Manage hubs, entries, translations, expiry workflows, permissions, and more.
Authentication
The Rasepi API uses Bearer token authentication. All requests (except public endpoints) require an Authorization header.
Authorization: Bearer <your-token>
Dev Tokens (Development)
For local development, use dev tokens that encode both tenant and user IDs:
Authorization: Bearer dev-token-{tenantId}:{userId}OAuth (Production)
In production, authenticate via the OAuth flow at GET /auth/login. This returns a JWT with sub and tenant_id claims.
Key Concepts
Multi-Tenant
All data is isolated per tenant. The tenant is resolved from the JWT tenant_id claim. EF global query filters enforce isolation automatically.
Block-Level Translation
Entries are broken into blocks (paragraphs, headings). Translations track each block independently via SHA256 content hashing — only stale blocks need retranslation.
Forced Expiry
Every entry has an expiration date. Expired entries are flagged for review. Reviews can renew, archive, or update content.
Soft Delete
When entries have translations, blocks are soft-deleted (marked IsDeleted) rather than physically removed to preserve translation alignment.
Hubs
Hubs are collaborative workspaces that contain entries. Every entry belongs to exactly one hub.
Returns all hubs the authenticated user has access to within the current tenant.
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Engineering",
"slug": "engineering",
"description": "Engineering documentation hub",
"createdAt": "2026-01-15T10:30:00Z",
"ownerId": "...",
"entryCount": 42
}
]Returns a single hub with its full details including settings and member count.
{
"id": "3fa85f64-...",
"name": "Engineering",
"slug": "engineering",
"description": "...",
"settings": { "defaultLanguage": "en", "expiryDays": 90 },
"memberCount": 15,
"entryCount": 42
}Creates a new hub. The authenticated user becomes the owner. Requires Global Admin role.
{
"name": "Engineering",
"description": "Engineering documentation hub",
"settings": {
"defaultLanguage": "en",
"expiryDays": 90
}
}{
"id": "3fa85f64-...",
"name": "Engineering",
"slug": "engineering",
"ownerId": "current-user-id"
}Updates hub name, description, and settings. Requires Hub Admin role.
{
"name": "Updated Name",
"description": "Updated description"
}{
"id": "3fa85f64-...",
"name": "Updated Name",
"updatedAt": "2026-04-05T14:00:00Z"
}Permanently deletes a hub and all its entries. Only the hub owner or global admin can perform this action.
Transfers ownership of the hub to another user. The new owner must be a member of the hub.
{
"newOwnerId": "target-user-guid"
}{
"id": "...",
"ownerId": "target-user-guid",
"updatedAt": "2026-04-05T14:00:00Z"
}Reorders entries within the hub. Provide an array of entry IDs in the desired display order.
{
"entryIds": [
"entry-guid-1",
"entry-guid-2",
"entry-guid-3"
]
}Returns the current user's effective role in the given hub (Viewer, Editor, Admin, or Owner).
{
"hubId": "...",
"role": "Editor",
"isOwner": false
}Entries
Entries are documentation pages within a hub. They support block-based content, translations, expiry tracking, and version history.
Returns all entries in the specified hub, with pagination and optional filtering.
[
{
"id": "...",
"title": "Getting Started",
"slug": "getting-started",
"status": "Published",
"expiresAt": "2026-07-15T00:00:00Z",
"createdAt": "2026-01-10T09:00:00Z"
}
]Returns full entry with content blocks (TipTap JSON), metadata, and translation status.
{
"id": "...",
"title": "Getting Started",
"content": { "type": "doc", "content": [...] },
"blocks": [...],
"translations": { "de": "UpToDate", "fr": "Stale" }
}Creates a new entry in the hub. Content is provided as TipTap JSON. Block IDs are auto-generated.
{
"title": "My New Entry",
"hubId": "hub-guid",
"content": {
"type": "doc",
"content": [
{ "type": "paragraph", "content": [{ "type": "text", "text": "Hello world" }] }
]
},
"expiresAt": "2026-10-01T00:00:00Z"
}{
"id": "new-entry-id",
"title": "My New Entry",
"status": "Draft",
"blockCount": 1
}Updates entry content and metadata. Changed blocks trigger content hash recalculation and translation staleness detection.
{
"title": "Updated Title",
"content": { "type": "doc", "content": [...] }
}{
"id": "...",
"title": "Updated Title",
"updatedAt": "2026-04-05T14:00:00Z",
"staleTranslations": ["de"]
}Deletes an entry. If translations exist, blocks are soft-deleted to preserve translation alignment.
Changes entry status from Draft to Published. Plugin action guards may intercept this (e.g., approval workflows).
{
"id": "...",
"status": "Published",
"publishedAt": "2026-04-05T14:00:00Z"
}Searches entries by title across all accessible hubs.
[
{
"id": "...",
"title": "Getting Started",
"excerpt": "...matching text highlighted...",
"score": 0.95
}
]Renews the entry by resetting its expiry clock based on the configured expiry template.
{
"id": "...",
"expiresAt": "2026-10-05T00:00:00Z",
"renewedAt": "2026-04-05T14:00:00Z"
}Creates a copy of the entry with new block IDs. The duplicate starts as a Draft.
{
"id": "new-entry-id",
"title": "Getting Started (Copy)",
"status": "Draft"
}Moves an entry from its current hub to a different hub.
{
"targetHubId": "destination-hub-guid"
}{
"id": "...",
"hubId": "destination-hub-guid"
}Stars an entry for the current user. Use DELETE to unstar. Use GET to check star status.
Subscribes to change notifications for the entry. Use DELETE to unwatch.
Returns the version history for an entry, including who made each change and when.
[
{
"version": 3,
"editedBy": "user-name",
"editedAt": "2026-04-05T14:00:00Z",
"summary": "Updated introduction"
}
]Returns the most viewed/engaged entries across accessible hubs.
[
{
"id": "...",
"title": "Getting Started",
"viewCount": 1250,
"hubName": "Engineering"
}
]Returns entries recently viewed by the current user.
[
{
"id": "...",
"title": "API Design Guide",
"lastViewedAt": "2026-04-05T12:30:00Z"
}
]Returns entries that will expire within the configured warning window.
[
{
"id": "...",
"title": "Onboarding Checklist",
"expiresAt": "2026-04-15T00:00:00Z",
"daysLeft": 10
}
]Returns entries pinned by admins for high visibility.
[
{
"id": "...",
"title": "Company Handbook",
"pinnedAt": "2026-03-01T10:00:00Z"
}
]Translations
Block-level translation system. Translations track source content via SHA256 hashes — when a block changes, its translations are marked stale. Only stale blocks need retranslation (94% cost savings on partial edits).
Translations are block-level, not entry-level. Each paragraph/heading gets its own translation that tracks staleness independently.
Templates
Entry templates provide reusable document structures. Templates can be created, rated, imported/exported, and applied to new entries.
See the Template Gallery for an interactive browser, or the Template Builder to create your own.
Lists templates visible to the current tenant with pagination. Supports category and search filtering.
[
{
"id": "...",
"name": "Meeting Notes",
"category": "General",
"rating": 4.2,
"usageCount": 156
}
]Returns full template detail including block content and metadata.
{
"id": "...",
"name": "Meeting Notes",
"description": "Standard meeting notes format",
"blocks": [...],
"category": "General",
"tags": ["meetings", "notes"]
}Creates a new template. Any authenticated user can create templates.
{
"name": "Meeting Notes",
"description": "Standard meeting notes format",
"category": "General",
"blocks": [
{ "type": "heading", "content": "Meeting Notes" },
{ "type": "paragraph", "content": "Date: ..." }
]
}{
"id": "new-template-id",
"name": "Meeting Notes",
"createdAt": "2026-04-05T14:00:00Z"
}Updates template metadata and content. Only the owner or admins can edit.
{
"name": "Updated Name",
"description": "Updated description",
"blocks": [...]
}{
"id": "...",
"name": "Updated Name",
"updatedAt": "2026-04-05T14:00:00Z"
}Deletes a template. Built-in system templates cannot be deleted.
Returns the raw block node array for the template and records a usage event.
[
{ "type": "heading", "attrs": { "level": 1 }, "content": [...] },
{ "type": "paragraph", "content": [...] }
]Submits or updates a star rating (1–5) for a template.
{
"averageRating": 4.2,
"ratingCount": 28
}Imports a template from portable JSON format.
{
"name": "Imported Template",
"blocks": [...],
"metadata": { ... }
}{
"id": "imported-template-id",
"name": "Imported Template"
}Exports a template as portable JSON for sharing between tenants.
{
"name": "Meeting Notes",
"version": 1,
"blocks": [...],
"metadata": { ... }
}Expiry & Reviews
Rasepi enforces content freshness through expiry dates and review workflows. Entries must be periodically reviewed, renewed, or archived. Expiry templates define the rules; reviews record the decisions.
Returns the resolved expiry configuration for an entry, including template fallback chain.
{
"expiryDays": 90,
"warningDays": 14,
"templateId": "...",
"source": "hub-template"
}Returns current expiry status including days remaining, warning state, and renewal eligibility.
{
"daysRemaining": 23,
"state": "Warning",
"expiresAt": "2026-04-28T00:00:00Z",
"renewalEligible": true
}Records a review action against the entry (Approved, NeedsUpdate, Archived). Can include checklist completion.
{
"decision": "Approved",
"notes": "Content verified and up to date",
"checklistItems": [
{ "id": "...", "completed": true }
]
}{
"id": "review-id",
"decision": "Approved",
"reviewedAt": "2026-04-05T14:00:00Z",
"reviewedBy": "user-name"
}Returns the full review history for an entry.
[
{
"id": "...",
"decision": "Approved",
"reviewedBy": "user-name",
"reviewedAt": "2026-04-01T10:00:00Z",
"notes": "All good"
}
]Renews the entry, resetting its expiry clock. Checks renewal eligibility first.
{
"id": "...",
"expiresAt": "2026-07-05T00:00:00Z",
"renewedAt": "2026-04-05T14:00:00Z"
}Returns the personal expiry dashboard showing entries owned by or assigned to the current user that need attention.
{
"expiredCount": 3,
"warningCount": 7,
"healthyCount": 42,
"entries": [...]
}Expiry Templates
Expiry templates define review cadence, warning thresholds, and renewal rules. Assign templates to entries or set a tenant-wide default.
Lists all active expiry templates for the current tenant.
[
{
"id": "...",
"name": "Standard 90-Day",
"expiryDays": 90,
"warningDays": 14,
"isDefault": true
}
]Returns a single expiry template with full configuration.
{
"id": "...",
"name": "Standard 90-Day",
"expiryDays": 90,
"warningDays": 14,
"requiresReview": true,
"checklistId": "..."
}Creates a new expiry template with review cadence and warning rules.
{
"name": "Quarterly Review",
"expiryDays": 90,
"warningDays": 14,
"requiresReview": true
}{
"id": "new-template-id",
"name": "Quarterly Review",
"createdAt": "2026-04-05T14:00:00Z"
}Updates an existing expiry template configuration.
{
"name": "Updated Name",
"expiryDays": 120,
"warningDays": 21
}{
"id": "...",
"name": "Updated Name",
"updatedAt": "2026-04-05T14:00:00Z"
}Deletes an expiry template. Fails if entries still reference it.
Sets this expiry template as the tenant-wide default for new entries.
{
"id": "...",
"isDefault": true
}Freshness Scores
Freshness trust scores rate how up-to-date an entry is based on multiple signals: last edit, review history, expiry proximity, translation staleness, and more.
Returns the cached freshness trust score (0–100) for an entry.
{
"score": 82,
"grade": "B",
"calculatedAt": "2026-04-05T12:00:00Z"
}Returns individual freshness signals: last edit age, review recency, expiry proximity, translation staleness, etc.
[
{ "signal": "lastEditAge", "score": 90, "weight": 0.3, "detail": "Edited 5 days ago" },
{ "signal": "reviewRecency", "score": 75, "weight": 0.25, "detail": "Reviewed 30 days ago" },
{ "signal": "translationStaleness", "score": 60, "weight": 0.2, "detail": "1 of 3 translations stale" }
]Triggers an on-demand freshness score recalculation for the entry.
{
"score": 85,
"grade": "B+",
"calculatedAt": "2026-04-05T14:00:00Z"
}Returns tenant-wide freshness summary including average score, distribution, and worst entries.
{
"averageScore": 76,
"distribution": { "A": 12, "B": 25, "C": 8, "D": 3, "F": 1 },
"worstEntries": [...]
}Analytics
Track entry views, time spent, and engagement. Identify inactive content and measure documentation impact.
Returns aggregated analytics for an entry: view count, unique viewers, avg time spent, trending direction.
{
"viewCount": 1250,
"uniqueViewers": 89,
"avgTimeSpent": 145,
"trending": "up",
"period": "30d"
}Returns paginated raw activity events for an entry (views, edits, shares).
{
"events": [
{ "type": "view", "userId": "...", "timestamp": "2026-04-05T12:30:00Z" },
{ "type": "edit", "userId": "...", "timestamp": "2026-04-04T09:15:00Z" }
],
"totalCount": 342,
"page": 1
}Records time the user spent viewing an entry (in seconds). Called by the frontend on page leave.
Returns entries not viewed within N days (default 90). Useful for identifying stale content.
[
{
"id": "...",
"title": "Old Process Guide",
"lastViewedAt": "2025-12-01T00:00:00Z",
"daysSinceView": 125
}
]Access Control
Manage hub memberships, entry-level permissions, and user groups. Roles cascade: Hub roles apply to all entries within, but entry-level overrides are supported.
Returns all memberships (users and groups) for a hub with their roles.
[
{
"id": "membership-id",
"type": "user",
"userId": "...",
"displayName": "Jane Doe",
"role": "Editor"
},
{
"id": "membership-id",
"type": "group",
"groupId": "...",
"groupName": "Engineering",
"role": "Viewer"
}
]Adds a user to the hub with the specified role.
{
"userId": "user-guid",
"role": "Editor"
}{
"id": "membership-id",
"userId": "user-guid",
"role": "Editor"
}Adds a group to the hub. All group members inherit the specified role.
{
"groupId": "group-guid",
"role": "Viewer"
}{
"id": "membership-id",
"groupId": "group-guid",
"role": "Viewer"
}Removes a user or group membership from the hub.
Returns entry-level permission overrides (users and groups with specific roles on this entry).
[
{
"id": "permission-id",
"type": "user",
"userId": "...",
"displayName": "Jane Doe",
"role": "Editor"
}
]Adds an entry-level permission override for a specific user.
{
"userId": "user-guid",
"role": "Editor"
}{
"id": "permission-id",
"userId": "user-guid",
"role": "Editor"
}Returns all user groups in the tenant.
[
{
"id": "...",
"name": "Engineering",
"memberCount": 12
}
]Creates a new user group.
{
"name": "Engineering"
}{
"id": "new-group-id",
"name": "Engineering",
"memberCount": 0
}AI & Search
Conversational AI agent and hybrid search across your documentation. Supports keyword, semantic, and combined search modes.
Searches documentation using keyword, semantic, or hybrid search. Returns ranked results with excerpts.
{
"query": "how to set up SSO",
"mode": "hybrid",
"limit": 10
}{
"results": [
{
"entryId": "...",
"title": "SSO Configuration Guide",
"excerpt": "...configure single sign-on...",
"score": 0.92
}
]
}Creates a new AI agent conversation.
{
"title": "Help with API integration"
}{
"id": "conversation-id",
"title": "Help with API integration",
"createdAt": "2026-04-05T14:00:00Z"
}Lists all AI conversations for the current user.
[
{
"id": "...",
"title": "Help with API integration",
"lastMessageAt": "2026-04-05T14:05:00Z",
"messageCount": 6
}
]Returns a conversation with all its messages.
{
"id": "...",
"title": "Help with API integration",
"messages": [
{ "role": "user", "content": "How do I authenticate?", "timestamp": "..." },
{ "role": "assistant", "content": "Use Bearer token auth...", "timestamp": "..." }
]
}Sends a message without streaming. For streaming responses, use the AgentHub SignalR connection.
{
"content": "How do I create an entry via the API?"
}{
"role": "assistant",
"content": "To create an entry, send a POST request to...",
"sources": [
{ "entryId": "...", "title": "API Quick Start" }
]
}Returns AI usage statistics for the current tenant (messages sent, tokens used).
{
"messagesSent": 245,
"tokensUsed": 128500,
"monthlyLimit": 500000,
"period": "2026-04"
}Notifications
Expiry warnings, notification channels, and bulk actions. Configure Slack, email, or webhook channels for automated expiry alerts.
Returns unacknowledged expiry warnings for the current user.
[
{
"id": "...",
"entryId": "...",
"entryTitle": "Onboarding Guide",
"daysLeft": 7,
"severity": "warning"
}
]Acknowledges a notification, removing it from the pending list.
Renews multiple entries at once from the notification view.
{
"entryIds": ["entry-1", "entry-2", "entry-3"]
}{
"renewed": 3,
"failed": 0
}Returns all configured notification channels (Slack, email, webhook).
[
{
"id": "...",
"type": "slack",
"name": "#docs-alerts",
"enabled": true
}
]Creates a new notification channel for expiry alerts.
{
"type": "slack",
"name": "#docs-alerts",
"config": {
"webhookUrl": "https://hooks.slack.com/..."
}
}{
"id": "channel-id",
"type": "slack",
"name": "#docs-alerts"
}Sends a test payload to verify the notification channel is reachable.
{
"success": true,
"message": "Test notification delivered"
}Authentication Endpoints
OAuth login flow, tenant selection, and session management.
Initiates the OAuth flow for the specified provider (google, github, microsoft). Redirects to provider login page.
302 Redirect → provider login page
Lists all tenants the authenticated user belongs to. Used after login to select a workspace.
[
{
"id": "...",
"name": "Acme Corp",
"slug": "acme",
"role": "Admin"
}
]Selects a tenant and returns a new JWT with the tenant_id claim included.
{
"tenantId": "tenant-guid"
}{
"token": "eyJhbGci...",
"tenantId": "...",
"tenantName": "Acme Corp"
}Logs the user out by revoking all active tokens.
Admin
Tenant administration: language configuration, glossaries, categories, tags, plugins, and style rules. All admin endpoints require Global Admin role.
Returns all language configurations for the current tenant. Use /enabled for only active languages.
[
{
"code": "en",
"name": "English",
"enabled": true,
"isDefault": true
},
{
"code": "de",
"name": "German",
"enabled": true,
"isDefault": false
}
]Returns all translation glossaries. Glossaries ensure consistent terminology across translations.
[
{
"id": "...",
"name": "Technical Terms",
"entryCount": 156,
"languages": ["en", "de", "fr"]
}
]Returns all categories for organizing entries.
[
{
"id": "...",
"name": "Engineering",
"color": "#2563EB"
}
]Returns available plugins and their installation status for the current tenant.
[
{
"id": "...",
"name": "DeepL Translation",
"type": "TranslationProvider",
"enabled": true,
"version": "1.2.0"
}
]Returns style rule lists that define writing style guidelines enforced by AI during editing.
[
{
"id": "...",
"name": "Technical Writing",
"ruleCount": 12,
"assignedHubs": 3
}
]Returns the current subscription details for the tenant, including plan, usage, and billing cycle.
{
"plan": "Pro",
"status": "active",
"currentPeriodEnd": "2026-05-01T00:00:00Z",
"seats": { "used": 12, "limit": 25 }
}