eLibrary API
The eLibrary API manages a document library: documents (metadata), collections, categories and tags, with archive function and batch creation. The actual files go through the central attachment system (entity type ELIBRARY_DOCUMENT) — incl. ClamAV scan.
Endpoints Overview
Documents
| Method | Endpoint | Description |
|---|---|---|
GET | /api/elibrary/documents | List all documents (with filtering) |
GET | /api/elibrary/documents/grouped | Grouped view (collections + standalone) |
GET | /api/elibrary/documents/:id | Get single document |
POST | /api/elibrary/documents | Create document (metadata ONLY, JSON) — upload file separately |
POST | /api/elibrary/documents/batch | Batch create (metadata + optional collection), returns document IDs |
PUT | /api/elibrary/documents/:id | Update document metadata (uploader or editAll) |
PATCH | /api/elibrary/documents/:id/archive | Archive/unarchive |
DELETE | /api/elibrary/documents/:id | Delete document (the associated file is marked as deleted) |
Files: A document's file is managed by the central attachment system — upload via POST /api/attachments/ELIBRARY_DOCUMENT/:documentId, download via GET /api/attachments/:attachmentId/download (incl. ClamAV scan, scanStatus, quarantine). Flow: first create the document metadata → then upload the file to the returned documentId. Attachments API →
Collections
| Method | Endpoint | Description |
|---|---|---|
GET | /api/elibrary/collections | List all collections |
GET | /api/elibrary/collections/:id | Get single collection (with documents) |
POST | /api/elibrary/collections | Create collection |
PUT | /api/elibrary/collections/:id | Update collection |
PATCH | /api/elibrary/collections/:id/archive | Archive/unarchive collection |
DELETE | /api/elibrary/collections/:id | Delete collection |
POST | /api/elibrary/collections/:id/documents | Add documents to collection |
POST | /api/elibrary/collections/:id/documents/remove | Remove documents from collection |
Categories & Tags
| Method | Endpoint | Description |
|---|---|---|
GET | /api/elibrary/categories | List all categories |
GET | /api/elibrary/categories/:id | Get single category |
POST | /api/elibrary/categories | Create category |
PUT | /api/elibrary/categories/:id | Update category |
DELETE | /api/elibrary/categories/:id | Delete category |
GET | /api/elibrary/tags | List all tags |
Document Types
| Type | Description |
|---|---|
PDF | PDF documents |
EBOOK | E-books |
WHITEPAPER | Whitepapers |
PRESENTATION | Presentations (PPT/slides) |
VIDEO | Video files |
AUDIO | Audio files |
SPREADSHEET | Spreadsheets (Excel/CSV) |
DATASHEET | Datasheets |
API Examples
Upload Document (Single File)
Step 1 — create document metadata (JSON, NO file):
POST /api/elibrary/documents
Content-Type: application/json
{
"title": "ITSM Whitepaper 2026",
"type": "WHITEPAPER",
"publisher": "Eviworx",
"categoryId": "clx-cat-whitepapers",
"collectionId": null,
"tags": ["itsm", "whitepaper"]
}
Response (201 Created)
{
"id": "clx-doc-id",
"title": "ITSM Whitepaper 2026",
"type": "WHITEPAPER",
"publisher": "Eviworx",
"category": { "id": "clx...", "name": "Whitepapers", "color": "#8b5cf6" },
"collectionId": null,
"tags": [
{ "id": "clx...", "name": "itsm" },
{ "id": "clx...", "name": "whitepaper" }
],
"uploadedBy": { "id": "clx...", "name": "Legal Manager" },
"createdAt": "2026-01-28T10:00:00Z",
"isArchived": false
}
Step 2 — upload the file to the returned documentId (central attachment system, multipart):
POST /api/attachments/ELIBRARY_DOCUMENT/clx-doc-id
Content-Type: multipart/form-data # field: file
# Download afterwards: GET /api/attachments/:attachmentId/download
Batch Creation with Collection
Batch creates metadata ONLY (1–20 documents, optionally as a collection) and returns the document IDs. Files are then uploaded individually per documentId (see above).
POST /api/elibrary/documents/batch
Content-Type: application/json
{
"collectionName": "ISO 27001 Package 2026",
"collectionDescription": "Audit documentation set",
"categoryId": "clx-cat-compliance",
"documents": [
{ "title": "ISMS Policy", "type": "PDF", "publisher": "Security", "tags": ["iso27001"] },
{ "title": "Risk Assessment", "type": "SPREADSHEET", "publisher": "Security", "tags": ["iso27001", "risk"] },
{ "title": "Audit Presentation", "type": "PRESENTATION", "publisher": "Security", "tags": ["iso27001"] }
]
}
Response (201 Created)
{
"collection": {
"id": "clx...",
"name": "ISO 27001 Package 2026",
"description": "Audit documentation set",
"category": {
"name": "Compliance",
"color": "#8b5cf6"
},
"documentCount": 3,
"createdBy": {
"name": "Legal Manager"
},
"createdAt": "2026-01-28T10:00:00Z",
"isArchived": false
},
"data": [
{ "id": "clx-1", "title": "ISMS Policy", "type": "PDF", "isArchived": false },
{ "id": "clx-2", "title": "Risk Assessment", "type": "SPREADSHEET", "isArchived": false },
{ "id": "clx-3", "title": "Audit Presentation", "type": "PRESENTATION", "isArchived": false }
]
}
Download File
Download goes through the central attachment system. The attachmentId comes from the document's attachment list:
# List the document's attachments → attachmentId
GET /api/attachments/ELIBRARY_DOCUMENT/:documentId
# Download the file
GET /api/attachments/:attachmentId/download
Archive Document
PATCH /api/elibrary/documents/:id/archive
{
"isArchived": true
}
Response
{
"id": "clx...",
"title": "GDPR Privacy Policy 2025",
"isArchived": true,
"archivedAt": "2026-01-28T10:30:00Z"
}
Collections
Collections group related documents (e.g., all documents on a topic):
Create Collection
POST /api/elibrary/collections
{
"name": "ISO 27001 Certification Documents",
"description": "All documents required for ISO 27001 audit",
"categoryId": "clx-cat-compliance"
}
Response
{
"id": "clx...",
"name": "ISO 27001 Certification Documents",
"description": "All documents required for ISO 27001 audit",
"category": {
"id": "clx...",
"name": "Policies & Compliance",
"color": "#8b5cf6"
},
"documentCount": 0,
"createdBy": {
"name": "Compliance Manager"
},
"createdAt": "2026-01-28T11:00:00Z",
"isArchived": false
}
Add Documents to Collection
// On create (metadata):
POST /api/elibrary/documents
{ "title": "...", "type": "PDF", "publisher": "...", "categoryId": "...", "collectionId": "clx-collection-id" }
// Existing documents without a collection:
POST /api/elibrary/collections/clx-collection-id/documents
{
"documentIds": ["clx-doc-1", "clx-doc-2"]
}
Filtering & Search
Filter Parameters
| Parameter | Description |
|---|---|
f.type | PDF, EBOOK, WHITEPAPER, PRESENTATION, VIDEO, AUDIO, SPREADSHEET, DATASHEET |
f.categoryId | Filter by category |
f.isArchived | Filter by archive status (requires viewArchived, else 403) |
q | Full-text (title / publisher) |
standalone | true = only documents without a collection (/documents only) |
archived / includeArchived | flags: only archived resp. active + archived (require viewArchived) |
page / per / sort | Pagination + sort (per is capped). Collection grouping via /documents/grouped. |
All three lists (documents / collections / grouped) use the filter syntax above. search, limit, sortBy, sortOrder, type and categoryId as plain parameters are rejected with 400 LEGACY_QUERY_PARAM_REMOVED; an unknown f.<field> yields 400 FILTER_FIELD_NOT_SUPPORTED. Batch creation succeeds completely or not at all (201 { collection|null, data }).
Contradicting parameters are rejected: archived or includeArchived together with f.isArchived, and standalone together with f.collectionId, yield 400 QUERY_SCOPE_CONFLICT. The grouped view pages up to a depth of 2000 (page × per), beyond that 400 MERGE_DEPTH_EXCEEDED, because it merges collections and standalone documents. /documents has no such limit.
Example Queries
# All whitepapers
GET /api/elibrary/documents?f.type=WHITEPAPER
# By category
GET /api/elibrary/documents?f.categoryId=clx-cat-id
# Full-text search (title/publisher)
GET /api/elibrary/documents?q=itsm
# Standalone documents only (without a collection)
GET /api/elibrary/documents?standalone=true
# Grouped view (collections + standalone)
GET /api/elibrary/documents/grouped
# Archived documents (requires viewArchived)
GET /api/elibrary/documents?archived=true
Permissions
| Permission | Description |
|---|---|
elibrary.view | View documents & collections |
elibrary.viewArchived | View archived documents — also covers their files and changes to archived entries |
elibrary.upload | Upload documents |
elibrary.editOwn | Edit own documents (uploader) |
elibrary.editAll | Edit all documents |
elibrary.archive | Archive/unarchive documents |
elibrary.delete | Delete documents (critical action, logged) |
viewArchived governs all access to archived entries: Whoever may not see an archived row may not modify, unarchive or delete it either — editing, toggling the archive flag and deleting an ALREADY archived row additionally require elibrary.viewArchived (documents as well as collections). Archiving a visible row is allowed without viewArchived: only the current state counts. This also covers the files — listing, metadata and download of attachments of archived documents.
Visibility is always decided by the document: A collection never opens up documents — the collection detail only returns documents the reader may see anyway. Adding documents to a collection or removing them therefore requires the edit right on the DOCUMENT (editAll resp. editOwn as uploader), not ownership of the collection; an unknown or foreign-assigned document ID is 404, and a document belonging to another collection is not silently moved (400 DOCUMENT_ALREADY_IN_COLLECTION). The creator may additionally delete their OWN, EMPTY collection without elibrary.delete — otherwise a failed multi-upload would leave behind an empty collection they could not remove. Once it contains documents, elibrary.delete is required.
Use Cases
Use Case 1: Policies & Compliance Docs
// Create collection
POST /api/elibrary/collections
{
"name": "Company Policies 2026",
"categoryId": "clx-cat-policies"
}
// Batch CREATE documents (metadata, atomic) → { collection, data: [documents] }
POST /api/elibrary/documents/batch
{ "collectionName": "Company Policies 2026", "categoryId": "clx-cat-policies",
"documents": [ { "title": "IT Security Policy", "type": "PDF", "publisher": "IT" } ] }
// Upload files afterwards per documentId: POST /api/attachments/ELIBRARY_DOCUMENT/:id
// Uses:
// - Onboarding: new employees get a link to the collection
// - Compliance audit: all policies in one place
// - Versioning: archive old version, upload new one
Use Case 2: IT Runbooks & Procedures
// Upload runbooks as PDF documents
{
"title": "Incident Escalation Process",
"type": "PDF",
"publisher": "IT Operations",
"categoryId": "clx-cat-procedures",
"tags": ["incident", "escalation", "process"]
}
// Uses:
// - Agents have access via eLibrary
// - Alternative to Knowledge Base (KB = FAQ, eLibrary = formal docs)
// - Versioning via archive function
Use Case 3: Forms & Templates
// Provide forms & templates
{
"title": "Hardware-Request-Form.pdf",
"type": "PDF",
"publisher": "IT Department",
"categoryId": "clx-cat-forms",
"tags": ["hardware", "request", "form"]
}
{
"title": "Monthly-Report-Template.xlsx",
"type": "SPREADSHEET",
"publisher": "Finance",
"categoryId": "clx-cat-templates",
"tags": ["report", "monthly", "template"]
}
// Uses:
// - Self-service for end users
// - Central template management
// - Downloads via the central attachment system
Best Practices
💡 Tips
1. Organization
- • Use collections for related docs
- • Categories by topic (policies, procedures, forms)
- • Tags for cross-topic keywords (gdpr, iso27001, security)
- • Maintain publisher field (for responsibilities)
2. Versioning
- • Archive old version (don't delete)
- • Upload new version with same title
- • Year in title for versioning (e.g., "Policy 2026")
- • uploadedAt shows the date of the version
3. File Management
- • Max file size / allowed formats come from the file settings for ELIBRARY_DOCUMENT (Admin Center → System → File Settings, /admin/file-settings)
- • Batch creates metadata; upload files afterwards per documentId
- • All uploads are scanned by ClamAV before they become downloadable
4. Permissions
- • All users: elibrary.view (can view & download docs)
- • Power users: upload, editOwn (can upload own docs)
- • Admins: editAll, archive, delete (full control)
- • Archive permission for compliance team
Error Handling
| Error Code | HTTP Status | Description |
|---|---|---|
ELIBRARY_DOCUMENT_NOT_FOUND | 404 | Document ID does not exist |
ELIBRARY_COLLECTION_NOT_FOUND | 404 | Collection ID does not exist |
ELIBRARY_CATEGORY_NOT_FOUND | 404 | Category ID does not exist |
NO_FILE | 400 | No file in the upload request (attachment upload) |
FILE_TOO_LARGE | 413 | File over configured limit (file settings) — from the attachment upload |
EXTENSION_NOT_ALLOWED · MIME_TYPE_NOT_ALLOWED | 415 | File type not allowed for ELIBRARY_DOCUMENT (attachment upload) |
FORBIDDEN | 403 | Missing permission (e.g., viewArchived, editAll). If the base permission of the route is missing, error is "Insufficient permissions" and the field required names the permission needed (structure: see API overview) |
LEGACY_QUERY_PARAM_REMOVED | 400 | Unsupported query parameter (search/limit/sortBy/sortOrder/type/categoryId) |
FILTER_FIELD_NOT_SUPPORTED | 400 | Unknown f.<field> in the filter query |
QUERY_SCOPE_CONFLICT | 400 | Contradicting parameters (archived/includeArchived + f.isArchived, standalone + f.collectionId) |
MERGE_DEPTH_EXCEEDED | 400 | Paging depth of the grouped view above 2000 (page × per) |
DOCUMENT_ALREADY_IN_COLLECTION | 400 | Document already belongs to a collection |
Note: The eLibrary is ideal for formal documents (policies, procedures, forms). For FAQ-style content use the Knowledge Base API.