Rasepi Developer Documentation
Build integrations with the Rasepi multilingual documentation platform. This reference covers every API endpoint for managing hubs, entries, translations, expiry workflows, and more.
Authentication
Bearer tokens, dev mode login, and tenant scoping
Content Management
Create, edit, publish, and search entries
Translations
Block-level translation with stale detection
Content Freshness
Expiry tracking, reviews, and renewal workflows
Analytics
Read counts, engagement, and inactive content
Access Control
Permissions, groups, and memberships
🔒 Authentication
All API requests require a Bearer token in the Authorization header. Tokens are scoped to a specific tenant and user.
Authorization: Bearer <your-token>
// Every request is scoped to a tenant.
// The tenant_id claim in the JWT determines data isolation.
Multi-tenant isolation: All data is automatically scoped to your tenant via EF global query filters. Cross-tenant access is impossible by design.
Development Tokens
In development mode, use the dev auth endpoints to get test tokens:
// 1. Get available dev tenants
GET /auth/dev-tenants
// 2. Login with a dev persona
POST /auth/dev-login
{
"persona": "alice",
"tenantId": "<tenant-guid>"
}
// 3. Use the returned token
// Format: Bearer dev-token-{tenantId}:{userId}
Key Concepts
Before diving into endpoints, understand the core ideas that make Rasepi unique.
🧩 Block-Level Translation
Entries are composed of blocks (paragraphs, headings, etc.). Translations happen at the block level, not the whole entry. When a single paragraph changes, only that block's translations are marked stale, saving up to 94% in translation costs.
🔓 Content Hashing
Each block has a SHA256 content hash. When the original block changes, its hash is recalculated. Translation blocks compare their SourceContentHash to the current hash. Mismatches trigger a Stale status.
⏰ Forced Expiry
Every entry has an expiration date. When it expires, owners are notified and content is flagged. Expiry templates define the rules: warning periods, grace periods, review requirements, and auto-renewal conditions.
🗑️ Soft Delete
Blocks are never truly deleted when translations exist. Instead, an IsDeleted flag preserves the block structure so translated entries maintain correct alignment. The UI shows a "[Content removed]" placeholder.
🏠 Hubs & Entries
Hubs are collaborative workspaces (like Confluence spaces). Each hub contains entries (documents). Hubs have a root entry (home page) and can define default expiry rules, member roles, and language settings.
🛠️ TipTap JSON
Content is stored as TipTap JSON. Each top-level node carries a blockId UUID for tracking. The API accepts and returns this format, making it easy to integrate with TipTap-based editors.
Authentication
OAuth login flow and development-mode authentication helpers.
Redirects the user to the specified OAuth provider for authentication.
| Name | Type | Description |
|---|---|---|
| providerrequired | string | OAuth provider name (e.g., google, github) |
Exchanges an OAuth authorization code for a user session and bearer token.
| Name | Type | Description |
|---|---|---|
| coderequired | string | Authorization code from the OAuth provider |
{
"user": { "id": "guid", "displayName": "Alice", ... },
"token": "eyJhbGci..."
}
Logs the user out and invalidates the session.
Hubs
Hubs are collaborative workspaces that contain entries. Each hub has a unique key, default expiry settings, and membership-based access control.
Returns all hubs the authenticated user has access to.
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"key": "engineering",
"name": "Engineering",
"defaultExpiryDays": 90,
"ownerId": "...",
"createdAt": "2026-01-15T10:30:00Z"
}
]
Retrieves a single hub by its unique key.
| Name | Type | Description |
|---|---|---|
| keyrequired | string | Unique hub key (slug) |
Returns the current user's role in the specified hub and whether they are a global admin.
{
"role": "Editor",
"isGlobalAdmin": false
}
Creates a new hub. The creator automatically becomes the hub owner.
| Name | Type | Description |
|---|---|---|
| keyrequired | string | Unique hub slug (URL-safe) |
| namerequired | string | Display name for the hub |
| defaultExpiryDaysrequired | integer | Default expiry days for entries in this hub |
| categoryIdoptional | guid | Category to assign |
| tagIdsoptional | guid[] | Tags to assign |
| previewImageoptional | string | URL for hub preview image |
Updates hub properties such as name, expiry defaults, and preview image.
| Name | Type | Description |
|---|---|---|
| namerequired | string | New display name |
| defaultExpiryDaysrequired | integer | New default expiry |
| previewImageoptional | string | Preview image URL |
| defaultOrgRoleoptional | string | Default role for org members |
| defaultExpiryTemplateIdoptional | guid | Default expiry template |
Permanently deletes a hub and all its entries. Only the hub owner or a global admin can perform this action.
Transfers ownership of the hub to another user.
| Name | Type | Description |
|---|---|---|
| newOwnerIdrequired | guid | User ID of the new owner |
Entries
Entries are the core content units: multilingual documents with block-level structure, expiry tracking, and TipTap JSON content.
Returns all entries in the specified hub.
| Name | Type | Description |
|---|---|---|
| hubKeyrequired | string | Hub key (slug) |
Returns the root (home) entry for the hub.
Retrieves an entry in the specified language. If the requested language has a translation, it returns translated content. May trigger a first-visit auto-translation.
| Name | Type | Description |
|---|---|---|
| idrequired | guid | Entry ID |
| languageoptional | string | Language code (default: en) |
{
"id": "...",
"title": "Onboarding Guide",
"key": "onboarding-guide",
"content": "{\"type\":\"doc\",\"content\":[...]}",
"originalLanguage": "en",
"status": "Published",
"expiryDate": "2026-06-15T00:00:00Z",
"hubId": "...",
"ownerId": "..."
}
Creates a new entry with TipTap JSON content. Blocks are automatically extracted and assigned UUIDs.
| Name | Type | Description |
|---|---|---|
| hubKeyrequired | string | Hub to create the entry in |
| keyrequired | string | Unique entry slug |
| originalLanguagerequired | string | Language code of the content (e.g., en) |
| titlerequired | string | Entry title |
| contentrequired | string (JSON) | TipTap document JSON |
| expiryDaysoptional | integer | Custom expiry (overrides hub default) |
| previewImageoptional | string | Preview image URL |
Updates an entry's title and/or content. Triggers block hash recalculation and marks affected translations as stale.
| Name | Type | Description |
|---|---|---|
| titlerequired | string | Updated title |
| contentrequired | string (JSON) | Updated TipTap JSON |
| previewImageoptional | string | Preview image URL |
| statusoptional | string | Entry status override |
Permanently deletes an entry. Cannot delete the root entry of a hub.
Searches entries by title. Minimum 2 characters required.
| Name | Type | Description |
|---|---|---|
| qrequired | string | Search query (min 2 chars) |
| hubKeyoptional | string | Filter to specific hub |
| takeoptional | integer | Max results (default: 15) |
Publishes a draft entry. Runs plugin action guards before publishing; if any guard blocks, the action fails.
Resets the expiry clock on an entry using its configured expiry duration.
Returns all entries that have passed their expiration date.
| Name | Type | Description |
|---|---|---|
| newOwnerIdrequired | guid | User ID of the new owner |
Changes the original (source) language of an entry. Use with caution as this affects all translation relationships.
| Name | Type | Description |
|---|---|---|
| languageCoderequired | string | New language code (e.g., de) |
Designates this entry as the hub's root (home) page. Replaces any previous root entry.
Translations
Block-level translation management. Translations track individual blocks via content hashing, enabling efficient stale detection and partial retranslation.
Returns all available translations for an entry, including their status (Draft, UpToDate, Stale).
[
{
"language": "de",
"title": "Einführungsleitfaden",
"status": "UpToDate",
"staleBlockCount": 0,
"totalBlockCount": 12
},
{
"language": "fr",
"title": "Guide d'intégration",
"status": "Stale",
"staleBlockCount": 2,
"totalBlockCount": 12
}
]
Retrieves the full translation for a specific language.
Creates a new translation for the entry. Can optionally use automatic translation via a configured provider.
| Name | Type | Description |
|---|---|---|
| titlerequired | string | Translated title |
| contentrequired | string (JSON) | Translated TipTap JSON content |
| useAutoTranslationoptional | boolean | Auto-translate via provider |
| provideroptional | string | Translation provider name |
Returns the current status of a translation: Draft, UpToDate, or Stale.
{ "status": "Stale" }
Manually marks a translation as up-to-date, resetting all stale flags on its blocks.
Returns blocks whose source content has changed since they were last translated. These blocks need retranslation.
Removes a translation and all its blocks for the specified language.
Expiry & Reviews
Content freshness workflows: expiry tracking, review submissions, renewal eligibility, and configurable expiry templates.
Returns the current expiry state of an entry including days until expiry and warning status.
{
"expiryDate": "2026-06-15T00:00:00Z",
"daysUntilExpiry": 78,
"isInWarningPeriod": false,
"isPaused": false
}
Returns the resolved expiry template applied to this entry (may be inherited from hub or tenant).
Returns the effective template with full fallback resolution: entry custom → hub default → tenant default.
| Name | Type | Description |
|---|---|---|
| templateIdrequired | guid | Expiry template ID |
| reasonoptional | string | Reason for change |
Records a content review. May be a quick review, full review, or attestation. After review, expiry may be renewed.
| Name | Type | Description |
|---|---|---|
| reviewTyperequired | string | QuickReview, FullReview, or Attestation |
| timeSpentSecondsrequired | integer | Time spent reviewing |
| notesoptional | string | Reviewer notes |
| blocksChangedoptional | integer | Number of blocks updated |
| contentWasUpdatedoptional | boolean | Whether content changed |
| checklistJsonoptional | string | Completed checklist state |
Returns the complete review history for an entry.
Checks whether the entry can be renewed and returns any blockers.
{
"canRenew": false,
"blockers": ["Review required before renewal"]
}
Renews an entry, resetting its expiry clock. May require a review first depending on the expiry template.
| Name | Type | Description |
|---|---|---|
| customExpiryDaysoptional | integer | Override expiry duration |
| notesoptional | string | Reason for renewal |
Expiry Dashboard
Multi-level expiry analytics: personal dashboard, tenant-wide summaries, and per-hub breakdowns.
Returns expiry counts and upcoming deadlines for entries owned by the current user.
Returns per-hub expiry counts across the tenant.
Returns detailed expiry status for every entry in the specified hub.
Entry Templates
Reusable block structures that can be applied to new entries. Templates have categories, ratings, and import/export support.
Returns paginated templates with filtering. Response includes X-Total-Count header.
| Name | Type | Description |
|---|---|---|
| searchoptional | string | Search by name |
| categoryoptional | string | Filter by category |
| filteroptional | string | all | mine | official | community |
| pageoptional | integer | Page number (default: 1) |
| pageSizeoptional | integer | Results per page (default: 30) |
Returns full template details including blocks.
Returns the fully assembled TipTap JSON document for preview rendering.
Returns blocks ready to inject into the TipTap editor. Records a usage event.
Creates a new entry template from a block structure.
| Name | Type | Description |
|---|---|---|
| starsrequired | integer | Rating from 1 to 5 |
Returns distinct category strings used across templates.
Imports a template from portable JSON format.
Exports a template as portable JSON for sharing between tenants.
Analytics
Activity tracking, engagement metrics, and inactive content detection.
Aggregated KPIs: total reads, unique editors, last read time, average and total time spent.
{
"totalReads": 142,
"uniqueEditors": 5,
"lastReadAt": "2026-03-28T14:22:00Z",
"averageTimeSpentSeconds": 185,
"totalTimeSpentSeconds": 26270
}
Returns raw activity events with pagination. Filter by event type.
| Name | Type | Description |
|---|---|---|
| eventTypeoptional | string | DocumentRead, DocumentEdited, or TimeSpent |
| skipoptional | integer | Offset (default: 0) |
| takeoptional | integer | Limit 1-200 (default: 50) |
Client reports time spent reading. Minimum 5 seconds to filter out drive-by visits.
| Name | Type | Description |
|---|---|---|
| secondsrequired | integer | Time spent in seconds (min: 5) |
| languageoptional | string | Language being read |
Returns entries not read within the specified number of days. Useful for identifying stale content.
| Name | Type | Description |
|---|---|---|
| daysoptional | integer | Days threshold, 1-3650 (default: 90) |
Hub Memberships
Manage hub members and their roles. Members can be users or groups.
| Name | Type | Description |
|---|---|---|
| targetUserIdrequired | guid | User ID to add |
| rolerequired | string | Viewer, Editor, or Admin |
| Name | Type | Description |
|---|---|---|
| groupIdrequired | guid | Group ID |
| rolerequired | string | Role for all group members |
Entry Permissions
Entry-level sharing for user and group access control.
| Name | Type | Description |
|---|---|---|
| targetUserIdrequired | guid | User to grant access |
| rolerequired | string | Viewer or Editor |
Groups
User group management. Groups can be assigned to hubs and entries for bulk permission management.
| Name | Type | Description |
|---|---|---|
| namerequired | string | Group name |
| descriptionoptional | string | Group description |
Users
User profile and preferences.
Returns the authenticated user's profile.
Returns all users in the current tenant. Used for share dialogs and user pickers.
| Name | Type | Description |
|---|---|---|
| languageCoderequired | string | Preferred language code |
Tenant Languages
Configure which languages are available in your tenant, set defaults, and configure translation triggers.
[
{
"code": "en",
"displayName": "English",
"isEnabled": true,
"isDefault": true,
"trigger": "AlwaysTranslate",
"provider": "deepl"
}
]
| Name | Type | Description |
|---|---|---|
| coderequired | string | ISO language code (e.g., de) |
| displayNamerequired | string | Display name (e.g., "German") |
| triggeroptional | string | AlwaysTranslate, OnDemand, or Never |
| provideroptional | string | Translation provider name |
| sortOrderoptional | integer | Display order |
Expiry Templates
Reusable expiry configurations that define warning periods, grace periods, review requirements, and auto-renewal rules.
Returns the number of entries using this template.
Cannot delete a template that is in use by entries.
Categories
Hub taxonomy for organizing workspaces.
Tags
Content tags for cross-hub organization and discoverability.
Expiry Notifications
Manage expiry warning notifications and bulk renewals.
Returns unacknowledged expiry warnings for the current user.
| Name | Type | Description |
|---|---|---|
| entryIdsrequired | guid[] | Array of entry IDs to renew |
Notification Channels
Webhook channels for delivering expiry and activity notifications to external systems (Slack, Teams, etc.).
Sends a test payload to verify channel configuration.
{
"successCount": 142,
"failureCount": 3,
"lastUsedAt": "2026-03-28T10:00:00Z"
}
Content Rules
Hub-level and tenant-level content rules (e.g., mandatory fields, naming conventions).
| Name | Type | Description |
|---|---|---|
| isEnabledrequired | boolean | Enable/disable rules |
| rulesJsonrequired | string | Rules configuration JSON |
Tenant Setup
Onboarding endpoints for creating new tenants. These are public (no auth required).
Returns all languages the platform supports.
Returns registered plugin manifests with metadata.
Creates a new tenant (workspace) during onboarding.
| Name | Type | Description |
|---|---|---|
| namerequired | string | Tenant display name |
| slugrequired | string | URL-safe identifier |
| domainoptional | string | Custom domain |
| allowAllUsersoptional | boolean | Open registration |
| enabledLanguagesoptional | string[] | Initial language codes |
| enabledPluginsoptional | string[] | Plugin IDs to enable |
Review Checklists
Configurable checklists that reviewers must complete during content reviews.
Block Type Heuristics
Semantic block classification rules for automatic content categorization.
Data Models & Enums
Key types used across the API. All responses use string-serialized enums.
EntryStatus
Lifecycle status of an entry.
TranslationStatus
Freshness status for block-level translations.
PermissionLevel
Access levels for hub memberships and entry permissions.
ReviewType
Types of content review for expiry workflow.
ActivityEventType
Types of analytics events.
TranslationTrigger
When auto-translation should fire for a language.
TenantRole
User roles at the tenant level.