Storage Service API
The Storage Service provides robust file storage, versioning, and retrieval capabilities across your organization’s infrastructure. This service abstracts away the underlying storage vendor implementation, allowing seamless interaction with files regardless of where they’re physically stored.Base URL
All endpoints are prefixed with/api/v1/document
Authentication
All endpoints require authentication via Bearer token:STORAGE_TOKEN- For storage operationsFETCH_CONFIG- For configuration updates
Architecture Overview
The Storage Service is built on a Node.js backend with MongoDB for metadata persistence. It provides a flexible storage interface that supports three storage vendor backends:- Amazon S3 - For cloud-based storage on AWS
- Azure Blob Storage - For cloud-based storage on Microsoft Azure
- Local Storage - For on-premises file storage
- Configuration Manager - Manages storage configuration settings stored in etcd
- IAM Service - Handles user authentication and authorization
- Key-Value Store - Provides access to configuration data from etcd
Storage Configuration
Storage configuration is maintained in etcd under the/services/storage path. The configuration determines which storage vendor is active and the credentials needed to access it. The service dynamically loads this configuration at runtime and can switch between storage vendors without restarting.
Authentication Modes
The Storage Service offers two authentication modes:- User Authentication - Uses standard user JWT tokens for operations performed by end users
- Service Authentication - Uses scoped tokens with specific permissions for service-to-service communication
Data Models
Document
The Document model represents metadata about files stored in the system, including:- Basic information (name, path, size, MIME type)
- Versioning metadata and history
- Storage location details
- Permissions and ownership
- Custom metadata
Version History
Each versioned document maintains a complete history of changes, including:- Previous versions of the document
- Metadata for each version (size, creation time, creator)
- Storage locations for each version
- Version notes and labels
API Endpoints
Document Management
Document Management
POST /upload - Upload Document
POST /upload - Upload Document
- Request
- Response
POST /api/v1/document/uploadRequest Body Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | The file to upload (multipart/form-data) |
| documentName | string | Yes | Name of the document (no extensions allowed) |
| documentPath | string | No | Optional path for document storage |
| alternateDocumentName | string | No | Alternative name for the document |
| permissions | string | No | Access permissions (owner, editor, commentator, readonly) |
| customMetadata | object | No | Custom metadata to associate with the document |
| isVersionedFile | string | Yes | Whether the document supports versioning (“true”/“false”) |
- User endpoints: 1GB (1024 * 1024 * 1000 bytes)
- Internal endpoints: 100MB (1024 * 1024 * 100 bytes)
- Document name cannot contain extensions or forward slashes
- File must have a valid extension with supported MIME type
- File buffer is required in multipart form data
POST /internal/upload - Internal Upload
POST /internal/upload - Internal Upload
- Request
- Response
POST /api/v1/document/internal/uploadAuthentication: Requires scoped token with STORAGE_TOKEN scope.Request Body: Same structure as public upload endpoint.File Size Limit: 100MB for internal uploads.POST /placeholder - Create Document Placeholder
POST /placeholder - Create Document Placeholder
- Request
- Response
POST /api/v1/document/placeholderRequest Body Parameters:| Parameter | Type | Required | Description |
|---|---|---|---|
| documentName | string | Yes | Name of the document (no extensions allowed) |
| documentPath | string | Yes | Path for document storage |
| alternateDocumentName | string | No | Alternative name for the document |
| permissions | string | No | Access permissions |
| metaData | object | No | Custom metadata |
| isVersionedFile | boolean | No | Whether the document supports versioning |
| extension | string | Yes | File extension (e.g., “pdf”) |
- Document name cannot contain extensions or forward slashes
- Extension must be provided separately
POST /internal/placeholder - Internal Create Placeholder
POST /internal/placeholder - Internal Create Placeholder
- Request
- Response
POST /api/v1/document/internal/placeholderAuthentication: Requires scoped token with STORAGE_TOKEN scope.Request Body: Same structure as public placeholder endpoint.GET /:documentId - Get Document By ID
GET /:documentId - Get Document By ID
- Request
- Response
GET /api/v1/document/:documentIdPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
Authorization: Bearer token (required)
GET /internal/:documentId - Internal Get Document
GET /internal/:documentId - Internal Get Document
- Request
- Response
GET /api/v1/document/internal/:documentIdAuthentication: Requires scoped token with STORAGE_TOKEN scope.DELETE /:documentId/ - Delete Document
DELETE /:documentId/ - Delete Document
- Request
- Response
DELETE /api/v1/document/:documentId/Path Parameters:documentId: MongoDB ObjectId (24-character hex string)
DELETE /internal/:documentId/ - Internal Delete
DELETE /internal/:documentId/ - Internal Delete
- Request
- Response
DELETE /api/v1/document/internal/:documentId/Authentication: Requires scoped token with STORAGE_TOKEN scope.Document Download & Access
Document Download & Access
GET /:documentId/download - Download Document
GET /:documentId/download - Download Document
- Request
- Response
GET /api/v1/document/:documentId/downloadPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
| Parameter | Type | Required | Description |
|---|---|---|---|
| version | string | No | Version number to download (transformed to number, must be > 0) |
| expirationTimeInSeconds | string | No | Expiration time for the signed URL (transformed to number, must be > 0, default: 3600) |
- Version is transformed from string to number and must be greater than 0 if provided
- expirationTimeInSeconds is transformed from string to number and must be greater than 0 if provided
- Version must exist in document’s version history
- Only versioned documents can specify version parameter
- Storage vendor must match current configuration
GET /internal/:documentId/download - Internal Download
GET /internal/:documentId/download - Internal Download
- Request
- Response
GET /api/v1/document/internal/:documentId/downloadAuthentication: Requires scoped token with STORAGE_TOKEN scope.Query Parameters: Same as public download endpoint.GET /:documentId/buffer - Get Document Buffer
GET /:documentId/buffer - Get Document Buffer
- Request
- Response
GET /api/v1/document/:documentId/bufferPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
| Parameter | Type | Required | Description |
|---|---|---|---|
| version | string | No | Version number to retrieve (transformed to number, min: 0) |
- Version is transformed from string to number via
.pipe(z.number().min(0).optional()) - Version must exist if specified
- Version cannot exceed available version history length
GET /internal/:documentId/buffer - Internal Get Buffer
GET /internal/:documentId/buffer - Internal Get Buffer
- Request
- Response
GET /api/v1/document/internal/:documentId/bufferAuthentication: Requires scoped token with STORAGE_TOKEN scope.Query Parameters: Same as public buffer endpoint.PUT /:documentId/buffer - Update Document Buffer
PUT /:documentId/buffer - Update Document Buffer
- Request
- Response
PUT /api/v1/document/:documentId/bufferPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
file: File to upload (multipart/form-data with field name ‘file’)
- Updates the document content in storage
- Increments mutation count
- Updates document size metadata
PUT /internal/:documentId/buffer - Internal Update Buffer
PUT /internal/:documentId/buffer - Internal Update Buffer
- Request
- Response
PUT /api/v1/document/internal/:documentId/bufferAuthentication: Requires scoped token with STORAGE_TOKEN scope.Request Body: Same as public buffer update endpoint.Document Versioning
Document Versioning
POST /:documentId/uploadNextVersion - Upload Next Version
POST /:documentId/uploadNextVersion - Upload Next Version
- Request
- Response
POST /api/v1/document/:documentId/uploadNextVersionPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
| Parameter | Type | Required | Description |
|---|---|---|---|
| file | File | Yes | The new file content (multipart/form-data with field name ‘file’) |
| currentVersionNote | string | No | Note for the current version (if modified) |
| nextVersionNote | string | No | Note for the next version |
- Document must support versioning (
isVersionedFile: true) - File extension must match existing document extension
- Document existence and access verification
- Checks if current document differs from last version
- If changed, creates version entry for current state with currentVersionNote
- Uploads new version with nextVersionNote
- Updates current document content
- Increments mutation count
POST /internal/:documentId/uploadNextVersion - Internal Upload Next Version
POST /internal/:documentId/uploadNextVersion - Internal Upload Next Version
- Request
- Response
POST /api/v1/document/internal/:documentId/uploadNextVersionAuthentication: Requires scoped token with STORAGE_TOKEN scope.Request Body: Same structure as public upload next version endpoint.POST /:documentId/rollBack - Roll Back to Previous Version
POST /:documentId/rollBack - Roll Back to Previous Version
- Request
- Response
POST /api/v1/document/:documentId/rollBackPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
| Parameter | Type | Required | Description |
|---|---|---|---|
| version | string | Yes | Version number to roll back to (transformed to number, min: 0) |
| Parameter | Type | Required | Description |
|---|---|---|---|
| note | string | Yes | Note about the rollback operation |
- Uses RollBackToPreviousVersionSchema which extends GetBufferSchema
- Version comes from query parameter (inherited from GetBufferSchema)
- Note comes from request body
- Document must support versioning
- Target version must exist and be less than current version count
POST /internal/:documentId/rollBack - Internal Roll Back
POST /internal/:documentId/rollBack - Internal Roll Back
- Request
- Response
POST /api/v1/document/internal/:documentId/rollBackAuthentication: Requires scoped token with STORAGE_TOKEN scope.Request Body: Same structure as public rollback endpoint.Direct Upload & Utilities
Direct Upload & Utilities
POST /:documentId/directUpload - Get Direct Upload URL
POST /:documentId/directUpload - Get Direct Upload URL
- Request
- Response
POST /api/v1/document/:documentId/directUploadPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
- Document and document path must exist
- Storage vendor configuration must be valid
- Uses DirectUploadSchema validation
POST /internal/:documentId/directUpload - Internal Direct Upload
POST /internal/:documentId/directUpload - Internal Direct Upload
- Request
- Response
POST /api/v1/document/internal/:documentId/directUploadAuthentication: Requires scoped token with STORAGE_TOKEN scope.GET /:documentId/isModified - Check If Document Is Modified
GET /:documentId/isModified - Check If Document Is Modified
- Request
- Response
GET /api/v1/document/:documentId/isModifiedPath Parameters:documentId: MongoDB ObjectId (24-character hex string)
- Compares current document buffer with latest version in history (or version 0)
- Returns boolean indicating modification status
- Uses buffer comparison for accurate change detection
GET /internal/:documentId/isModified - Internal Check Modified
GET /internal/:documentId/isModified - Internal Check Modified
- Request
- Response
GET /api/v1/document/internal/:documentId/isModifiedAuthentication: Requires scoped token with STORAGE_TOKEN scope.Configuration
Configuration
POST /updateAppConfig - Update App Configuration
POST /updateAppConfig - Update App Configuration
- Request
- Response
POST /api/v1/document/updateAppConfigAuthentication: Requires scoped token with FETCH_CONFIG scope.Behavior:- Reloads application configuration from configuration manager
- Updates storage configuration in dependency injection container
- Recreates storage controller with new configuration
- Allows dynamic reconfiguration without service restart
Schema Definitions
- Document Schema
- DocumentVersion Schema
- StorageInfo Schema
- CustomMetadata Schema
- Storage Vendor Types
- Validation Schemas
Supported MIME Types
The storage service supports an extensive list of MIME types including:- Document Formats
- Image Formats
- Archive Formats
- Media & Other Formats
- PDF:
application/pdf - Microsoft Office: Word (
.docx,.doc), Excel (.xlsx,.xls), PowerPoint (.pptx,.ppt) - OpenDocument:
.odt,.ods,.odp - Text:
.txt,.rtf,.csv,.md,.mdx - Web:
.html,.css,.js,.json,.xml - eBooks:
.epub - Google Workspace:
.gdoc,.gsheet,.gslides,.gdraw
Storage Provider Implementation
The Storage Service uses an adapter pattern to abstract the underlying storage provider implementation.- Amazon S3
- Azure Blob Storage
- Local Storage
- Direct file uploads/downloads via AWS SDK
- Signed URLs with configurable expiration (default: 1 hour)
- Multipart uploads for large files
- Object versioning support
- Comprehensive error handling with specific S3 error types
StorageConfigurationError- Missing credentialsStorageUploadError- Upload failuresStorageDownloadError- Download failuresPresignedUrlError- URL generation failuresMultipartUploadError- Multipart operation failures
File Size Limits & Direct Upload
- Size Limits
- Direct Upload Flow
- Upload: 1GB (1024 * 1024 * 1000 bytes)
- Buffer operations: 100MB (1024 * 1024 * 100 bytes)
- All operations: 100MB (1024 * 1024 * 100 bytes)
- Set via
maxFileSizeForPipesHubServiceconstant - Currently configured to 0MB (all files trigger direct upload evaluation)
- Applied only to S3 and Azure Blob storage
- Local storage always uses direct API upload
Error Handling
All endpoints return structured error responses:VALIDATION_ERROR- Invalid request parametersNOT_FOUND- Document not foundBAD_REQUEST- Invalid request formatFORBIDDEN- File format mismatch or access deniedINTERNAL_SERVER_ERROR- Storage service errors
- Extension validation failures
- File size limit exceeded
- Storage vendor configuration errors
- Version control constraint violations
- MIME type validation failures
200- Success308- Permanent Redirect (for direct uploads)400- Bad Request401- Unauthorized403- Forbidden404- Not Found500- Internal Server Error
Configuration Management
- Storage Configuration
- Service Integration
/services/storage path:- Service loads configuration at startup and via watch mechanism
- Can switch storage vendors without service restart
- Configuration changes trigger adapter reinitialization
- Graceful handling of configuration errors
Important Notes
- Schema Discrepancy: There’s a mismatch between the rollback validator schema (expects version in query) and controller implementation (reads version from body). Documentation follows schema specification.
- File Extensions: Automatically detected from original filename and validated against comprehensive MIME type mappings.
-
Version Control: Optional per document via
isVersionedFileflag, maintains complete history with metadata and notes. - Storage Abstraction: Seamless switching between storage vendors via configuration without code changes.
-
Organization Isolation: All documents are organization-scoped (
orgId) for secure multi-tenancy. -
Soft Deletion: Documents are marked as deleted (
isDeleted: true) rather than physically removed. - Direct Upload: Large files bypass API server for optimal performance, using vendor-specific presigned URLs.
- Internal APIs: Service-to-service communication with scoped authentication using specific token scopes.
-
Mutation Tracking: Documents track change count (
mutationCount) for auditing and optimization. - MIME Type Validation: Extensive validation against supported file types with automatic extension detection.
-
Path Structure: Organized as
{orgId}/PipesHub/{documentPath}/{documentId}/current|versions/for clear file organization. - Cross-Platform Support: Local storage handles Windows, macOS, and Linux filesystem differences transparently.













