openapi: 3.0.3 info: title: YAMS Content Store API description: | HTTP REST API for the YAMS content-addressed storage system. ## Features - Content-addressed storage with SHA-256 hashing - Automatic deduplication - Metadata management - Batch operations - Progress tracking ## Authentication The API supports multiple authentication methods: - **API Key**: Include `X-API-Key` header - **Bearer Token**: Include `Authorization: Bearer ` header - **Basic Auth**: Include `Authorization: Basic ` header version: 1.0.0 contact: name: YAMS Team url: https://github.com/trvon/yams license: name: Apache-2.0 url: https://www.apache.org/licenses/LICENSE-2.0 servers: - url: http://localhost:8080/api/v1 description: Local development server - url: https://api.yams.example.com/api/v1 description: Production server security: - ApiKeyAuth: [] - BearerAuth: [] tags: - name: Content description: Content storage and retrieval operations - name: Metadata description: Content metadata management - name: Batch description: Batch operations - name: System description: System information and health paths: /content: post: tags: - Content summary: Store content description: Upload a file to the content store operationId: storeContent requestBody: required: true content: multipart/form-data: schema: type: object required: - file properties: file: type: string format: binary description: The file to upload metadata: type: string description: JSON-encoded metadata encoding: file: contentType: application/octet-stream responses: "201": description: Content stored successfully content: application/json: schema: $ref: "#/components/schemas/StoreResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/InternalError" /content/{hash}: parameters: - $ref: "#/components/parameters/ContentHash" get: tags: - Content summary: Retrieve content description: Download content by its hash operationId: retrieveContent parameters: - name: Accept in: header description: | Response format: - `application/octet-stream` (default) - Returns the file - `application/json` - Returns metadata only schema: type: string enum: - application/octet-stream - application/json responses: "200": description: Content retrieved successfully content: application/octet-stream: schema: type: string format: binary application/json: schema: $ref: "#/components/schemas/MetadataResponse" "404": $ref: "#/components/responses/NotFound" "500": $ref: "#/components/responses/InternalError" delete: tags: - Content summary: Delete content description: Remove content from the store operationId: deleteContent responses: "200": description: Content deleted successfully content: application/json: schema: $ref: "#/components/schemas/DeleteResponse" "404": $ref: "#/components/responses/NotFound" "401": $ref: "#/components/responses/Unauthorized" "500": $ref: "#/components/responses/InternalError" head: tags: - Content summary: Check if content exists description: Check if content with given hash exists operationId: checkExists responses: "204": description: Content exists "404": description: Content not found /content/{hash}/metadata: parameters: - $ref: "#/components/parameters/ContentHash" get: tags: - Metadata summary: Get metadata description: Retrieve metadata for content operationId: getMetadata responses: "200": description: Metadata retrieved successfully content: application/json: schema: $ref: "#/components/schemas/MetadataResponse" "404": $ref: "#/components/responses/NotFound" put: tags: - Metadata summary: Update metadata description: Update metadata for content operationId: updateMetadata requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ContentMetadata" responses: "200": description: Metadata updated successfully content: application/json: schema: $ref: "#/components/schemas/SuccessResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /content/batch: post: tags: - Batch summary: Store multiple files description: Upload multiple files in a single request operationId: storeBatch requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BatchStoreRequest" responses: "200": description: Batch operation completed content: application/json: schema: $ref: "#/components/schemas/BatchStoreResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" delete: tags: - Batch summary: Delete multiple files description: Remove multiple files by their hashes operationId: deleteBatch requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/BatchDeleteRequest" responses: "200": description: Batch delete completed content: application/json: schema: $ref: "#/components/schemas/BatchDeleteResponse" "400": $ref: "#/components/responses/BadRequest" "401": $ref: "#/components/responses/Unauthorized" /content/search: get: tags: - Content summary: Search content description: Search for content by metadata operationId: searchContent parameters: - name: mimeType in: query description: Filter by MIME type schema: type: string - name: namePattern in: query description: Filter by name pattern (regex) schema: type: string - name: tags in: query description: Filter by tags (comma-separated) schema: type: string - name: limit in: query description: Maximum results to return schema: type: integer default: 100 minimum: 1 maximum: 1000 - name: offset in: query description: Number of results to skip schema: type: integer default: 0 minimum: 0 responses: "200": description: Search results content: application/json: schema: $ref: "#/components/schemas/SearchResponse" /content/stats: get: tags: - System summary: Get statistics description: Retrieve storage statistics operationId: getStats responses: "200": description: Statistics retrieved content: application/json: schema: $ref: "#/components/schemas/StatsResponse" /health: get: tags: - System summary: Health check description: Check system health status operationId: healthCheck security: [] # No auth required responses: "200": description: System is healthy content: application/json: schema: $ref: "#/components/schemas/HealthResponse" "503": description: System is unhealthy content: application/json: schema: $ref: "#/components/schemas/HealthResponse" components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-API-Key description: API key for authentication BearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT bearer token parameters: ContentHash: name: hash in: path required: true description: SHA-256 hash of the content schema: type: string pattern: "^[a-fA-F0-9]{64}$" example: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" schemas: ContentMetadata: type: object properties: mimeType: type: string description: MIME type of the content example: "application/pdf" originalName: type: string description: Original filename example: "document.pdf" description: type: string description: Content description tags: type: array items: type: string description: Tags for categorization example: ["important", "work"] customFields: type: object additionalProperties: type: string description: Custom metadata fields encoding: type: string description: Character encoding (for text) language: type: string description: Language code version: type: integer description: Version number default: 1 owner: type: string description: Owner identifier permissions: type: string description: Permission string StoreResult: type: object required: - contentHash - bytesStored - bytesDeduped - dedupRatio - duration properties: contentHash: type: string description: SHA-256 hash of stored content bytesStored: type: integer format: int64 description: Total bytes stored bytesDeduped: type: integer format: int64 description: Bytes saved by deduplication dedupRatio: type: number format: double description: Deduplication ratio (0.0-1.0) duration: type: integer format: int64 description: Operation duration in milliseconds StoreResponse: type: object required: - success - data properties: success: type: boolean example: true data: $ref: "#/components/schemas/StoreResult" MetadataResponse: type: object required: - success - data properties: success: type: boolean data: type: object properties: hash: type: string metadata: $ref: "#/components/schemas/ContentMetadata" DeleteResponse: type: object required: - success - data properties: success: type: boolean data: type: object properties: deleted: type: boolean hash: type: string BatchStoreRequest: type: object required: - items properties: items: type: array items: type: object required: - filename - content properties: filename: type: string content: type: string format: base64 description: Base64-encoded file content metadata: $ref: "#/components/schemas/ContentMetadata" BatchStoreResponse: type: object properties: success: type: boolean data: type: object properties: items: type: array items: type: object properties: success: type: boolean data: $ref: "#/components/schemas/StoreResult" error: type: string BatchDeleteRequest: type: object required: - hashes properties: hashes: type: array items: type: string pattern: "^[a-fA-F0-9]{64}$" BatchDeleteResponse: type: object properties: success: type: boolean data: type: object properties: items: type: array items: type: object properties: hash: type: string deleted: type: boolean error: type: string SearchResponse: type: object properties: success: type: boolean data: type: object properties: items: type: array items: type: object properties: hash: type: string metadata: $ref: "#/components/schemas/ContentMetadata" total: type: integer limit: type: integer offset: type: integer ContentStats: type: object properties: totalObjects: type: integer format: int64 totalBytes: type: integer format: int64 uniqueBlocks: type: integer format: int64 deduplicatedBytes: type: integer format: int64 dedupRatio: type: number format: double storeOperations: type: integer format: int64 retrieveOperations: type: integer format: int64 deleteOperations: type: integer format: int64 lastOperation: type: string format: date-time StatsResponse: type: object properties: success: type: boolean data: $ref: "#/components/schemas/ContentStats" HealthStatus: type: object properties: isHealthy: type: boolean status: type: string warnings: type: array items: type: string errors: type: array items: type: string lastCheck: type: string format: date-time HealthResponse: type: object properties: success: type: boolean data: $ref: "#/components/schemas/HealthStatus" SuccessResponse: type: object properties: success: type: boolean example: true message: type: string ErrorResponse: type: object required: - error - message - code properties: error: type: string description: Error type message: type: string description: Human-readable error message code: type: integer description: HTTP status code requestId: type: string description: Request ID for tracking responses: BadRequest: description: Bad request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" example: error: Bad Request message: Invalid request parameters code: 400 requestId: 123e4567-e89b-12d3-a456-426614174000 Unauthorized: description: Unauthorized content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" example: error: Unauthorized message: Invalid or missing authentication credentials code: 401 requestId: 123e4567-e89b-12d3-a456-426614174000 NotFound: description: Not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" example: error: Not Found message: Content not found code: 404 requestId: 123e4567-e89b-12d3-a456-426614174000 InternalError: description: Internal server error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" example: error: Internal Server Error message: An unexpected error occurred code: 500 requestId: 123e4567-e89b-12d3-a456-426614174000