IntraVox API Reference¶
This document describes the IntraVox REST API for developers who want to integrate with IntraVox programmatically.
Table of Contents¶
- Base URLs
- Authentication
- Response Format
- Pages API
- Media API
- Versioning API
- Comments API
- Reactions API
- Analytics API
- Bulk Operations API
- Navigation & Footer API
- Settings API
- Page Metadata API
- News API
- Resources API
- Permissions API
- MetaVox Integration API
- Setup & Demo Data API
- Search API
- Export/Import API
- Error Codes
- Security
- Rate Limiting
- Migration Tool Integration
- Privacy
Quick Reference: OCS API Endpoints (External Access)¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/pages |
List all pages |
| POST | /api/v1/pages |
Create a new page |
| GET | /api/v1/pages/{id} |
Get single page |
| PUT | /api/v1/pages/{id} |
Update page |
| DELETE | /api/v1/pages/{id} |
Delete page |
| GET | /api/v1/pages/{pageId}/media |
List media files |
| POST | /api/v1/pages/{pageId}/media |
Upload media |
| GET | /api/v1/pages/{pageId}/media/{filename} |
Get media file |
All OCS endpoints are prefixed with /ocs/v2.php/apps/intravox
Base URLs¶
IntraVox provides two API interfaces:
OCS API (Recommended for external tools)¶
Use the OCS API when accessing IntraVox from external tools, scripts, or applications using Basic Auth or app passwords:
The OCS API properly handles HTTP methods (GET, POST, PUT, DELETE) and is the recommended interface for programmatic access.
Standard API (Internal use)¶
The standard API is used internally by the IntraVox frontend with session authentication:
Authentication¶
The API uses Nextcloud's standard authentication:
- App Password + Basic Auth (recommended for external tools)
- Create an app password in Nextcloud: Settings → Security → Devices & sessions → Create new app password
-
Include
OCS-APIREQUEST: trueheader for OCS endpoints -
Session cookies (for browser-based applications)
-
Bearer token with Nextcloud OAuth tokens
Example with curl (OCS API):¶
curl -u "username:app-password" \
-H "OCS-APIREQUEST: true" \
https://your-nextcloud.com/ocs/v2.php/apps/intravox/api/v1/pages
Example: Create a page¶
curl -X POST \
-u "username:app-password" \
-H "Content-Type: application/json" \
-H "OCS-APIREQUEST: true" \
-d '{"id": "my-page", "title": "My Page", "uniqueId": "page-12345"}' \
https://your-nextcloud.com/ocs/v2.php/apps/intravox/api/v1/pages
Response Format¶
All endpoints return JSON responses with a consistent structure.
Success Response¶
Error Response¶
Errors return appropriate HTTP status codes (400, 403, 404, 500) with a consistent format:
The errorId field is included for server errors (5xx) and can be used by support to correlate with server logs. Client errors (4xx) may not include this field.
Important: Error messages are intentionally generic for security reasons. Sensitive details (stack traces, file paths, SQL errors) are logged server-side but never exposed to API consumers.
Pages API¶
List All Pages¶
Returns a flat list of all pages the user has read access to.
Response:
[
{
"id": "page-abc123",
"uniqueId": "page-abc123",
"title": "Welcome Page",
"path": "/IntraVox/en/Welcome Page",
"parentId": null,
"permissions": {
"canRead": true,
"canWrite": true,
"canDelete": true
},
"createdAt": "2025-01-15T10:30:00Z",
"updatedAt": "2025-01-16T14:22:00Z"
}
]
Get Page Tree¶
Returns pages organized in a hierarchical tree structure.
Get Single Page¶
Returns full page details including content.
Parameters:
- id (string): The unique page ID
Response:
{
"id": "page-abc123",
"uniqueId": "page-abc123",
"title": "Welcome Page",
"content": "<p>Page HTML content...</p>",
"metadata": {
"author": "admin",
"category": "general"
},
"permissions": {
"canRead": true,
"canWrite": true,
"canDelete": true
},
"breadcrumb": [
{"id": "page-root", "title": "Home"},
{"id": "page-abc123", "title": "Welcome Page"}
]
}
Create Page¶
Creates a new page.
Request Body:
{
"title": "New Page Title",
"content": "<p>Initial content</p>",
"parentId": "page-parent123",
"metadata": {
"category": "news"
}
}
Response: Returns the created page object with HTTP 201.
Update Page¶
Updates an existing page.
Request Body:
{
"title": "Updated Title",
"content": "<p>Updated content</p>",
"metadata": {
"category": "updated"
}
}
Delete Page¶
Deletes a page. Returns {"success": true} on success.
Page Layout & Widgets¶
IntraVox pages use a structured JSON layout instead of raw HTML. The layout consists of rows containing widgets.
Layout Structure¶
{
"title": "My Page",
"layout": {
"columns": 1,
"rows": [
{
"columns": 1,
"backgroundColor": "",
"widgets": [...]
}
],
"sideColumns": {
"left": { "enabled": false, "widgets": [] },
"right": { "enabled": false, "widgets": [] }
}
}
}
Row Properties¶
| Property | Type | Description |
|---|---|---|
columns |
int | Number of columns (1-4) |
backgroundColor |
string | CSS color or variable (e.g., var(--color-primary-element)) |
collapsible |
bool | Make row collapsible (SharePoint-style) |
sectionTitle |
string | Title shown in collapsible header |
defaultCollapsed |
bool | Start collapsed (default: false) |
widgets |
array | Array of widget objects |
Widget Types¶
All widgets have these common properties:
- type (string): Widget type identifier
- column (int): Which column (1-based)
- order (int): Sort order within column
Text Widget¶
Heading Widget¶
-level: 1-6 (h1-h6)
Image Widget¶
{
"type": "image",
"column": 1,
"order": 1,
"src": "photo.jpg",
"alt": "Description",
"caption": "Optional caption"
}
src: Filename (relative to page media folder) or full URL
Video Widget¶
{
"type": "video",
"column": 1,
"order": 1,
"url": "https://youtube.com/watch?v=...",
"caption": ""
}
Divider Widget¶
-style: "solid", "dashed", "dotted"
Links Widget (Card Grid)¶
{
"type": "links",
"column": 1,
"order": 1,
"columns": 3,
"items": [
{
"title": "Link Title",
"text": "Description",
"url": "https://example.com",
"icon": "home",
"target": "_blank"
}
]
}
icon: Material Design Icon name (without mdi- prefix)
News Widget¶
{
"type": "news",
"column": 1,
"order": 1,
"title": "Latest News",
"sourcePath": "news",
"layout": "carousel",
"columns": 3,
"limit": 5,
"sortBy": "modified",
"sortOrder": "desc",
"showImage": true,
"showDate": true,
"showExcerpt": true,
"excerptLength": 100,
"autoplayInterval": 5
}
layout: "grid", "carousel", "list"
- sortBy: "modified", "created", "title"
Calendar Widget¶
{
"type": "calendar",
"column": 1,
"order": 1,
"title": "Upcoming Events",
"calendarIds": [1, 106],
"dateRange": "upcoming",
"limit": 5,
"showTime": true,
"showLocation": false,
"backgroundColor": null
}
calendarIds: Array of Nextcloud calendar IDs
- dateRange: "upcoming", "this_week", "next_two_weeks", "this_month", "next_three_months", "next_six_months", "next_year", "past_week", "past_month", "past_three_months"
Complete Page Example¶
curl -X POST \
-u "username:app-password" \
-H "Content-Type: application/json" \
-d '{
"title": "Department Page",
"parentId": "page-parent-123",
"layout": {
"columns": 1,
"rows": [
{
"columns": 1,
"backgroundColor": "var(--color-primary-element)",
"widgets": [
{
"type": "heading",
"column": 1,
"order": 1,
"content": "Welcome to IT Department",
"level": 1
}
]
},
{
"columns": 2,
"backgroundColor": "",
"widgets": [
{
"type": "text",
"column": 1,
"order": 1,
"content": "Welcome to the IT department page. Here you will find all relevant information."
},
{
"type": "links",
"column": 2,
"order": 1,
"columns": 1,
"items": [
{"title": "Helpdesk", "url": "/p/helpdesk", "icon": "help-circle"},
{"title": "Systems", "url": "/p/systems", "icon": "server"}
]
}
]
}
]
}
}' \
https://your-nextcloud.com/apps/intravox/api/pages
Media API¶
Each IntraVox page has a _media folder for storing images and videos. Media can be uploaded via the internal API (session auth) or via WebDAV for external tools.
Upload Media (Internal API)¶
Uploads a file to a page's media folder. Used by the IntraVox frontend.
Content-Type: multipart/form-data
Form Fields:
- media: The file to upload (or image/video for backward compatibility)
Response:
Upload Media with Custom Name¶
Uploads a file with a specified filename (instead of auto-generated).
Content-Type: multipart/form-data
Form Fields:
- file: The file to upload
- filename: Desired filename
Response:
Check for Duplicate Media¶
Checks if a file with the same name already exists before uploading.
Request Body:
Response:
List Media (Internal API)¶
Returns all media files for a page (internal route).
Upload Media via WebDAV (External Tools)¶
For external tools using Basic Auth, use Nextcloud's WebDAV API to upload media files:
# First, get the page path
curl -u "user:app-password" \
-H "OCS-APIREQUEST: true" \
"https://your-nextcloud.com/ocs/v2.php/apps/intravox/api/v1/pages/{uniqueId}?format=json"
# Response includes: "path": "en/page-folder"
# Upload the file via WebDAV
curl -X PUT \
-u "user:app-password" \
--data-binary @/path/to/image.jpg \
-H "Content-Type: image/jpeg" \
"https://your-nextcloud.com/remote.php/dav/files/user/IntraVox/{path}/_media/image.jpg"
Example:
# Upload banner.svg to page "page-media-test-001"
curl -X PUT \
-u "admin:app-password" \
--data-binary @banner.svg \
-H "Content-Type: image/svg+xml" \
"https://your-nextcloud.com/remote.php/dav/files/admin/IntraVox/en/api-media-test/_media/banner.svg"
List Media (OCS API)¶
Returns all media files attached to a page.
Headers:
- OCS-APIREQUEST: true
Response:
{
"media": [
{
"name": "img_60f1e5b2.jpg",
"size": 125432,
"mimeType": "image/jpeg",
"modified": 1705412520
}
]
}
Get Media File (OCS API)¶
Returns the media file content.
Versioning API¶
Get Page Versions¶
Returns version history for a page.
Response:
[
{
"timestamp": 1705412520,
"date": "2025-01-16T14:22:00Z",
"author": "admin",
"label": "Published version"
},
{
"timestamp": 1705326120,
"date": "2025-01-15T14:22:00Z",
"author": "editor",
"label": null
}
]
Restore Version¶
Restores a page to a previous version.
Get Version Content¶
Returns the content of a specific version.
Update Version Label¶
Updates the label/name of a version (for named snapshots).
Request Body:
Response:
Comments API¶
Get Comments¶
Query Parameters:
- limit (int, optional): Maximum comments to return (default: 50)
- offset (int, optional): Pagination offset
Response:
{
"comments": [
{
"id": 123,
"message": "Great page!",
"authorId": "user1",
"authorName": "John Doe",
"createdAt": "2025-01-16T10:00:00Z",
"parentId": null,
"replies": []
}
],
"total": 15
}
Create Comment¶
Request Body:
Set parentId to another comment ID to create a reply.
Update Comment¶
Request Body:
Only the comment author can update their comments.
Delete Comment¶
Comment authors and admins can delete comments.
Reactions API¶
Page Reactions¶
GET /api/pages/{pageId}/reactions
POST /api/pages/{pageId}/reactions/{emoji}
DELETE /api/pages/{pageId}/reactions/{emoji}
GET Response:
Comment Reactions¶
GET /api/comments/{commentId}/reactions
POST /api/comments/{commentId}/reactions/{emoji}
DELETE /api/comments/{commentId}/reactions/{emoji}
Analytics API¶
Track Page View¶
Tracks a page view. Called automatically by the frontend. Requires read access to the page.
Response:
Get Page Statistics¶
Query Parameters:
- days (int, optional): Number of days to include (default: 30, max: 365)
Response:
{
"success": true,
"pageId": "page-abc123",
"period": 30,
"totalViews": 150,
"totalUniqueUsers": 42,
"dailyStats": [
{
"date": "2025-01-15",
"views": 25,
"uniqueUsers": 12
}
]
}
Get Top Pages¶
Query Parameters:
- limit (int, optional): Maximum pages to return (default: 10, max: 50)
- days (int, optional): Period to consider (default: 30, max: 365)
Response:
{
"success": true,
"period": 30,
"pages": [
{
"pageId": "page-abc123",
"title": "Popular Page",
"path": "/news/popular",
"totalViews": 500,
"totalUniqueUsers": 150
}
]
}
Get Dashboard Statistics¶
Returns aggregated statistics for the analytics dashboard. Admin only.
Query Parameters:
- days (int, optional): Period to include (default: 30, max: 365)
Response:
{
"success": true,
"period": 30,
"totalViews": 5000,
"totalPagesViewed": 45,
"dailyStats": [...],
"topPages": [...]
}
Analytics Settings (Admin Only)¶
GET Response:
POST Request Body:
POST Response:
Bulk Operations API¶
All bulk operations require admin privileges. Non-admin users receive HTTP 403.
Operation Limits: Maximum 100 pages per bulk operation to prevent server overload.
Validate Operation¶
Validates a bulk operation without executing it (dry-run).
Request Body:
Response:
{
"success": true,
"operation": "delete",
"total": 3,
"canProceed": 2,
"willFail": 1,
"valid": [
{"pageId": "page-1", "title": "Page 1"},
{"pageId": "page-2", "title": "Page 2"}
],
"invalid": [
{"pageId": "page-3", "reason": "Permission denied"}
]
}
Bulk Delete¶
Request Body:
Response:
{
"success": true,
"operation": "delete",
"total": 2,
"deleted": 2,
"failed": 0,
"results": [
{"pageId": "page-1", "title": "Page 1", "status": "deleted"},
{"pageId": "page-2", "title": "Page 2", "status": "deleted"}
],
"errors": []
}
Bulk Move¶
Request Body:
Bulk Update¶
Request Body:
{
"pageIds": ["page-1", "page-2"],
"updates": {
"metadata": {
"category": "archived"
}
},
"dryRun": false
}
Navigation & Footer API¶
Get Navigation¶
Returns the custom navigation configuration.
Save Navigation¶
Updates the navigation configuration (requires write permission).
Get Footer¶
Save Footer¶
Settings API¶
Video Domains¶
Get or set allowed video embed domains.
GET Response:
POST Request Body:
Upload Limit¶
Returns the maximum file upload size.
Response:
Engagement Settings¶
Configure page engagement features (comments, reactions).
Response:
Publication Settings¶
Configure publication workflow settings.
Response:
Page Metadata API¶
Get Page Metadata¶
Returns metadata for a page without the full content.
Response:
{
"id": "page-abc123",
"title": "Page Title",
"author": "admin",
"createdAt": "2025-01-15T10:00:00Z",
"updatedAt": "2025-01-16T14:00:00Z",
"category": "news",
"tags": ["important", "announcement"]
}
Update Page Metadata¶
Updates only the metadata of a page.
Request Body:
Get Page Content¶
Returns only the content/layout of a page (without metadata).
Get Breadcrumb¶
Returns the breadcrumb path for a page.
Response:
[
{"id": "page-root", "title": "Home", "path": "/"},
{"id": "page-parent", "title": "Parent Page", "path": "/parent"},
{"id": "page-current", "title": "Current Page", "path": "/parent/current"}
]
Check Cache Status¶
Returns cache status information for a page.
Response:
News API¶
Get News Items¶
Returns news items from pages marked as news.
Query Parameters:
- limit (int, optional): Maximum items to return (default: 10)
- sourcePath (string, optional): Filter by source path
Response:
[
{
"id": "page-news-1",
"title": "Latest Announcement",
"excerpt": "This is an important...",
"image": "banner.jpg",
"date": "2025-01-16T10:00:00Z",
"path": "/news/announcement"
}
]
Resources API¶
Get Resource Media¶
Returns shared resource files (backgrounds, icons, etc.).
Examples:
Permissions API¶
Get User Permissions¶
Returns the current user's permissions in IntraVox.
Response:
{
"isAdmin": true,
"canCreatePages": true,
"canEditNavigation": true,
"canImport": true,
"canExport": true,
"canManageSettings": true
}
MetaVox Integration API¶
Get MetaVox Status¶
Checks if MetaVox is installed and enabled.
Response:
Get MetaVox Fields¶
Returns available MetaVox metadata fields for IntraVox pages.
Response:
{
"fields": [
{"name": "department", "type": "select", "options": ["IT", "HR", "Finance"]},
{"name": "owner", "type": "user"},
{"name": "expiryDate", "type": "date"}
]
}
Setup & Demo Data API¶
Run Setup¶
Initializes IntraVox (creates folder structure, default pages). Admin only.
Response:
Get Demo Data Status¶
Checks if demo data is installed.
Response:
Get Available Languages¶
Returns languages available for demo data import.
Import Demo Data¶
Imports demo data for a specific language.
Request Body:
Clean Start¶
Removes all IntraVox content and starts fresh. Admin only.
Calendar API¶
Requires authentication (session). Private and confidential events (CLASS:PRIVATE, CLASS:CONFIDENTIAL) are automatically filtered out. Date range is capped at 1 year maximum.
List Calendars¶
Returns all calendars available to the current user (personal + shared).
Responses: 200 OK, 401 Authentication required, 500 Server error
Response:
{
"calendars": [
{
"id": 106,
"uri": "org-events",
"displayName": "Org events",
"color": "#D6B461",
"isReadOnly": false
}
]
}
Get Calendar Events¶
Returns events from one or more calendars within a time range. Recurring events (RRULE) are expanded into individual occurrences.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
calendarIds |
string | Yes | Comma-separated calendar IDs (e.g., 1,106) |
rangeStart |
string | No | ISO 8601 start date. Defaults to now |
rangeEnd |
string | No | ISO 8601 end date. Defaults to 30 days from now |
limit |
integer | No | Maximum events (1-20, default: 5) |
Responses: 200 OK, 400 Invalid date format, 401 Authentication required, 500 Server error
Response:
{
"events": [
{
"uid": "f602fd5a-a355-4c98-87c4-c6ea30d8e405-2026-03-26T07:00:00+01:00",
"summary": "Team meeting A",
"location": "Utrecht office",
"start": "2026-03-26T07:00:00+01:00",
"end": "2026-03-26T09:30:00+01:00",
"isAllDay": false,
"calendarColor": "#D6B461",
"calendarName": "Org events"
}
]
}
Get Calendar Events (Public Share)¶
Same parameters and response as above, but uses the share owner's calendar context. No authentication required — only a valid share token.
Responses: 200 OK, 400 Invalid date format, 403 Invalid or expired share token, 500 Server error
Search API¶
Search Pages¶
Query Parameters:
- q (string): Search query
Response:
[
{
"id": "page-abc123",
"title": "Matching Page",
"excerpt": "...text containing the <mark>search</mark> term..."
}
]
Export/Import API¶
Get Exportable Languages¶
Returns a list of languages that can be exported.
Response:
Export Language¶
Exports all pages for a language as JSON or ZIP.
Export Single Page¶
Import ZIP¶
Imports pages from a ZIP file (requires admin).
Import from Confluence¶
Imports pages from a Confluence HTML export ZIP file.
Content-Type: multipart/form-data
Form Fields:
- file: The Confluence HTML export ZIP file
- language (string, optional): Target language (default: "nl")
- parentPageId (string, optional): Parent page ID for imported pages
Error Codes¶
| Code | Meaning | Example |
|---|---|---|
| 200 | Success | Request completed |
| 201 | Created | Page/comment created |
| 207 | Multi-Status | Partial success in bulk operations |
| 400 | Bad Request | Invalid parameters, validation error |
| 403 | Forbidden | No permission, admin required |
| 404 | Not Found | Page/resource doesn't exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server-side error (check errorId in response) |
Security¶
Admin-Only Endpoints¶
The following endpoints require system administrator privileges:
| Endpoint | Purpose |
|---|---|
POST /api/bulk/* |
Bulk operations (delete, move, update) |
POST /api/import/* |
ZIP and Confluence imports |
POST /api/setup |
Initial setup |
POST /api/settings/* |
Video domains, engagement, publication settings |
GET /api/analytics/dashboard |
Analytics dashboard |
POST /api/analytics/settings |
Analytics configuration |
POST /api/demo-data/* |
Demo data management |
File Upload Security¶
- Extension whitelist: Only allowed extensions: jpg, jpeg, png, gif, webp, svg, mp4, webm, ogg
- MIME type validation: Files are validated using both
finfoandgetimagesize()for images - SVG sanitization: SVG files are sanitized to remove scripts, iframes, and other dangerous content
- Size limits: Respects PHP and Nextcloud upload limits
Path Traversal Protection¶
All path parameters are validated against: - Null byte injection - URL-encoded traversal patterns (../) - Double-encoding attacks - Unicode normalization attacks
Rate Limiting¶
The API uses Nextcloud's built-in brute force protection. For heavy integrations, consider implementing client-side throttling to avoid triggering rate limits.
Migration Tool Integration¶
For migration tools (SharePoint, Confluence, custom CMS) that need to bulk-import pages with media, we recommend the following Nextcloud-supported approach:
Recommended Workflow¶
┌─────────────────────────────────────────────────────────────────┐
│ Migration Tool │
├─────────────────────────────────────────────────────────────────┤
│ 1. Create page via OCS API │
│ POST /ocs/v2.php/apps/intravox/api/v1/pages │
│ → Returns pageId and path │
│ │
│ 2. Upload media via WebDAV (Nextcloud native) │
│ PUT /remote.php/dav/files/{user}/{path}/_media/{filename} │
│ → Standard Nextcloud file upload │
│ │
│ 3. Update page content with media references │
│ - Edit page.json via WebDAV, or │
│ - Use OCS PUT endpoint (when supported) │
└─────────────────────────────────────────────────────────────────┘
Why WebDAV for Media Uploads?¶
| Aspect | WebDAV |
|---|---|
| Stability | Core Nextcloud feature since version 1 |
| Documentation | Officially documented at docs.nextcloud.com |
| Large files | Chunked upload support built-in |
| Authentication | App passwords (secure, revocable) |
| Reliability | Used by all official Nextcloud clients |
Complete Migration Example¶
#!/bin/bash
# Example: Migrate a SharePoint page with images to IntraVox
SERVER="https://your-nextcloud.com"
USER="admin"
APP_PASSWORD="your-app-password"
AUTH="$USER:$APP_PASSWORD"
# Step 1: Create the page via OCS API
PAGE_RESPONSE=$(curl -s -X POST \
-u "$AUTH" \
-H "Content-Type: application/json" \
-H "OCS-APIREQUEST: true" \
-d '{
"id": "migrated-sharepoint-page",
"title": "Migrated from SharePoint",
"uniqueId": "page-sp-migration-001",
"layout": {
"columns": 1,
"rows": [
{
"columns": 1,
"widgets": [
{
"type": "heading",
"column": 1,
"order": 1,
"content": "Migrated Page",
"level": 1
},
{
"type": "image",
"column": 1,
"order": 2,
"src": "header-banner.jpg",
"alt": "Header image"
},
{
"type": "text",
"column": 1,
"order": 3,
"content": "Content migrated from SharePoint."
}
]
}
]
}
}' \
"$SERVER/ocs/v2.php/apps/intravox/api/v1/pages")
echo "Page created: $PAGE_RESPONSE"
# Step 2: Upload media via WebDAV
# The _media folder is auto-created when the page is created
curl -X PUT \
-u "$AUTH" \
--data-binary @/path/to/header-banner.jpg \
-H "Content-Type: image/jpeg" \
"$SERVER/remote.php/dav/files/$USER/IntraVox/en/migrated-sharepoint-page/_media/header-banner.jpg"
echo "Media uploaded successfully"
WebDAV Chunked Upload (Large Files)¶
For files larger than 10MB, use Nextcloud's chunked upload:
# Initialize chunked upload
UPLOAD_DIR=".upload-$(uuidgen)"
curl -X MKCOL \
-u "$AUTH" \
"$SERVER/remote.php/dav/uploads/$USER/$UPLOAD_DIR"
# Upload chunks (5MB each)
split -b 5242880 large-video.mp4 chunk_
for chunk in chunk_*; do
curl -X PUT \
-u "$AUTH" \
--data-binary @$chunk \
"$SERVER/remote.php/dav/uploads/$USER/$UPLOAD_DIR/$chunk"
done
# Assemble the file
curl -X MOVE \
-u "$AUTH" \
-H "Destination: $SERVER/remote.php/dav/files/$USER/IntraVox/en/page/_media/large-video.mp4" \
"$SERVER/remote.php/dav/uploads/$USER/$UPLOAD_DIR/.file"
Media Path Structure¶
IntraVox stores media in a predictable structure:
/IntraVox/
├── en/ # Language folder
│ └── page-folder/ # Page folder (same as page ID)
│ ├── page-folder.json # Page content
│ └── _media/ # Media folder
│ ├── .nomedia # Marker file (auto-created)
│ ├── header.jpg # Uploaded images
│ └── video.mp4 # Uploaded videos
Authentication Recommendations¶
- Create dedicated app password for migration tools:
- Settings → Security → Devices & sessions
-
Create app password with descriptive name ("SharePoint Migration Tool")
-
Use service account for automated migrations:
- Create dedicated Nextcloud user for migrations
-
Assign appropriate GroupFolder permissions
-
Revoke after completion:
- App passwords can be revoked without affecting user account
Privacy¶
Analytics data is privacy-conscious: - User IDs are hashed before storage - Only daily aggregates are stored, not individual page views - Data is automatically cleaned up based on retention settings (default: 90 days)