openapi: 3.0.0 info: title: Timestamping Service API description: API for creating and verifying timestamps on a blockchain version: 1.0.0 contact: name: Timestamping Service Team email: support@timestamping-service.example.com url: https://timestamping-service.example.com servers: - url: / description: Default server tags: - name: API description: API operations for timestamping and status - name: Admin description: Administrative operations - name: Auth description: Authentication and user management operations paths: /api/timestamp: post: security: - BearerAuth: [] tags: - API summary: Create a new timestamp description: Submit data to be timestamped on the blockchain operationId: createTimestamp requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TimestampRequest' responses: '202': description: Accepted - Timestamp job submitted successfully content: application/json: schema: $ref: '#/components/schemas/TimestampResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/batch/timestamp: post: security: - BearerAuth: [] tags: - API summary: Create multiple timestamps in a batch description: Submit multiple data items to be timestamped on the blockchain operationId: createBatchTimestamp requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BatchTimestampRequest' responses: '202': description: Accepted - Batch timestamp jobs submitted successfully content: application/json: schema: $ref: '#/components/schemas/BatchTimestampResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/verify: post: security: - BearerAuth: [] tags: - API summary: Verify a timestamp certificate description: Verify the authenticity of a timestamp certificate operationId: verifyTimestamp requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VerifyRequest' responses: '200': description: OK - Verification result content: application/json: schema: $ref: '#/components/schemas/VerifyResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/batch/verify: post: security: - BearerAuth: [] tags: - API summary: Verify multiple timestamp certificates in a batch description: Verify the authenticity of multiple timestamp certificates operationId: verifyBatchTimestamp requestBody: required: true content: application/json: schema: type: object required: - certificates properties: certificates: type: array description: Array of timestamp certificates to verify items: type: string example: certificates: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." responses: '200': description: OK - Batch verification results content: application/json: schema: $ref: '#/components/schemas/BatchVerifyResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/status/{jobId}: get: security: - BearerAuth: [] tags: - API summary: Get the status of a timestamp job description: Retrieve the current status of a timestamp job by its ID operationId: getJobStatus parameters: - name: jobId in: path description: ID of the job to get status for required: true schema: type: string responses: '200': description: OK - Job status retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StatusResponse' '400': description: Bad Request - Missing job ID content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found - Job not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/verify/{jobId}: get: security: - BearerAuth: [] tags: - API summary: Get verification details for a timestamp job description: Retrieve comprehensive block details and verification information for a specific timestamp job operationId: getJobVerification parameters: - name: jobId in: path description: ID of the job to get verification details for required: true schema: type: string responses: '200': description: OK - Job verification details retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StatusResponse' '400': description: Bad Request - Missing job ID content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found - Job not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /api/batch/status: post: security: - BearerAuth: [] tags: - API summary: Get the status of multiple timestamp jobs description: Retrieve the current status of multiple timestamp jobs by their IDs operationId: getBatchJobStatus requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BatchStatusRequest' responses: '200': description: OK - Batch job statuses retrieved successfully content: application/json: schema: $ref: '#/components/schemas/BatchStatusResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '504': description: Gateway Timeout content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /admin/dashboard: get: security: - BearerAuth: [] tags: - Admin summary: Admin dashboard description: HTML dashboard for administrators operationId: getAdminDashboard responses: '200': description: OK - Admin dashboard HTML content: text/html: schema: type: string '405': description: Method Not Allowed /admin/metrics: get: security: - BearerAuth: [] tags: - Admin summary: Get system metrics description: Retrieve system metrics including blockchain height and queue length operationId: getMetrics responses: '200': description: OK - System metrics content: application/json: schema: $ref: '#/components/schemas/MetricsResponse' '405': description: Method Not Allowed /admin/blockchain: get: security: - BearerAuth: [] tags: - Admin summary: Get blockchain information description: Retrieve information about the blockchain operationId: getBlockchainInfo responses: '200': description: OK - Blockchain information content: application/json: schema: $ref: '#/components/schemas/BlockchainInfoResponse' '405': description: Method Not Allowed /admin/queue: get: security: - BearerAuth: [] tags: - Admin summary: Get queue information description: Retrieve information about the job queue operationId: getQueueInfo responses: '200': description: OK - Queue information content: application/json: schema: $ref: '#/components/schemas/QueueInfoResponse' '405': description: Method Not Allowed /admin/timestamps: get: security: - BearerAuth: [] tags: - Admin summary: Get recent timestamps description: Retrieve the most recent timestamps (up to 10) operationId: getRecentTimestamps responses: '200': description: OK - Recent timestamps content: application/json: schema: type: array items: $ref: '#/components/schemas/BlockInfo' '405': description: Method Not Allowed /admin/hash: get: security: - BearerAuth: [] tags: - Admin summary: Get block by hash description: Retrieve a block by its hash operationId: getBlockByHash parameters: - name: hash in: query description: Hash of the block to retrieve required: true schema: type: string - name: format in: query description: Format of the hash (base64 or raw) required: false schema: type: string enum: [base64, raw] default: base64 responses: '200': description: OK - Block information content: application/json: schema: $ref: '#/components/schemas/BlockInfo' '400': description: Bad Request - Missing or invalid hash '404': description: Not Found - Block not found '405': description: Method Not Allowed /auth/login: post: tags: - Auth summary: Login to the system description: Authenticate with username and password to receive a JWT token operationId: login requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LoginRequest' responses: '200': description: OK - Login successful content: application/json: schema: $ref: '#/components/schemas/LoginResponse' '401': description: Unauthorized - Invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/validate: get: tags: - Auth summary: Validate a token description: Validate a JWT token and get user information operationId: validateToken parameters: - name: Authorization in: header description: | JWT token with Bearer prefix. Example: `Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY` required: false schema: type: string example: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY" - name: token in: query description: | JWT token (alternative to Authorization header). Example: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY` required: false schema: type: string example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY" responses: '200': description: OK - Token is valid content: application/json: schema: $ref: '#/components/schemas/TokenValidationResponse' '401': description: Unauthorized - Invalid or expired token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/users: get: tags: - Auth summary: List all users description: Get a list of all users (admin only) operationId: listUsers security: - BearerAuth: [] responses: '200': description: OK - List of users content: application/json: schema: type: array items: $ref: '#/components/schemas/UserResponse' '401': description: Unauthorized - Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: tags: - Auth summary: Create a new user description: Create a new user (admin only) operationId: createUser security: - BearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' responses: '201': description: Created - User created successfully content: application/json: schema: $ref: '#/components/schemas/UserResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Conflict - User already exists content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /auth/users/{username}: get: tags: - Auth summary: Get a user description: Get a specific user by username (admin only) operationId: getUser security: - BearerAuth: [] parameters: - name: username in: path description: Username of the user to get required: true schema: type: string responses: '200': description: OK - User details content: application/json: schema: $ref: '#/components/schemas/UserResponse' '401': description: Unauthorized - Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found - User not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' put: tags: - Auth summary: Update a user description: Update a specific user by username (admin only) operationId: updateUser security: - BearerAuth: [] parameters: - name: username in: path description: Username of the user to update required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateUserRequest' responses: '200': description: OK - User updated successfully content: application/json: schema: $ref: '#/components/schemas/UserResponse' '400': description: Bad Request - Invalid input content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found - User not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' delete: tags: - Auth summary: Delete a user description: Delete a specific user by username (admin only) operationId: deleteUser security: - BearerAuth: [] parameters: - name: username in: path description: Username of the user to delete required: true schema: type: string responses: '204': description: No Content - User deleted successfully '401': description: Unauthorized - Invalid or missing token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not Found - User not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: | JWT token obtained from the /auth/login endpoint. To use this token: 1. First call the /auth/login endpoint with your username and password 2. Copy the token value from the response 3. Click the "Authorize" button at the top of this page 4. In the authorization popup, paste the token value (without "Bearer " prefix) 5. Click "Authorize" to apply the token to all secured endpoints The token must be included in the Authorization header as: `Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY` schemas: TimestampRequest: type: object required: - data properties: data: type: string description: Data to be timestamped hashAlg: type: string description: Hash algorithm to use (defaults to SHA256 if not provided) example: data: "Hello, world!" hashAlg: "SHA256" TimestampResponse: type: object properties: jobId: type: string description: ID of the submitted timestamp job example: jobId: "550e8400-e29b-41d4-a716-446655440000" BatchTimestampRequest: type: object required: - items properties: items: type: array description: Array of timestamp requests items: $ref: '#/components/schemas/TimestampRequest' example: items: - data: "Hello, world!" hashAlg: "SHA256" - data: "Another message" hashAlg: "SHA256" BatchTimestampResponse: type: object properties: jobIds: type: array description: Array of job IDs for the submitted timestamp jobs items: type: string example: jobIds: - "550e8400-e29b-41d4-a716-446655440000" - "650e8400-e29b-41d4-a716-446655440001" VerifyRequest: type: object required: - certificate properties: certificate: type: string description: Timestamp certificate to verify example: certificate: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." VerifyResponse: type: object properties: valid: type: boolean description: Whether the certificate is valid timestamp: type: string format: date-time description: Timestamp when the data was recorded (only present if valid) blockIndex: type: integer format: uint64 description: Index of the block containing the timestamp (only present if valid) example: valid: true timestamp: "2023-01-01T12:00:00Z" blockIndex: 42 BatchVerifyResponse: type: object properties: results: type: array description: Array of verification results items: $ref: '#/components/schemas/VerifyResponse' example: results: - valid: true timestamp: "2023-01-01T12:00:00Z" blockIndex: 42 - valid: false BatchStatusRequest: type: object required: - jobIds properties: jobIds: type: array description: Array of job IDs to get status for items: type: string example: jobIds: - "550e8400-e29b-41d4-a716-446655440000" - "650e8400-e29b-41d4-a716-446655440001" BatchStatusResponse: type: object properties: results: type: object description: Map of job IDs to status responses additionalProperties: $ref: '#/components/schemas/StatusResponse' example: results: "550e8400-e29b-41d4-a716-446655440000": id: "550e8400-e29b-41d4-a716-446655440000" status: "completed" result: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." completedAt: "2023-01-01T12:05:00Z" "650e8400-e29b-41d4-a716-446655440001": id: "650e8400-e29b-41d4-a716-446655440001" status: "pending" StatusResponse: type: object properties: id: type: string description: Job ID status: type: string description: Job status (pending, completed, failed) error: type: string description: Error message (only present if status is failed) result: type: string description: Job result (only present if status is completed) completedAt: type: string format: date-time description: Timestamp when the job was completed (only present if status is completed or failed) metadata: type: object description: Additional metadata about the job example: id: "550e8400-e29b-41d4-a716-446655440000" status: "completed" result: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." completedAt: "2023-01-01T12:05:00Z" metadata: blockIndex: 42 timestamp: "2023-01-01T12:00:00Z" certificate: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." block: index: 42 timestamp: "2023-01-01T12:00:00Z" hash: "QmFzZTY0IGVuY29kZWQgaGFzaA==" previousHash: "UHJldmlvdXMgYmxvY2sgaGFzaA==" hashAlgorithm: "SHA256" transactionCount: 1 transactions: - id: "block-42" timestamp: "2023-01-01T12:00:00Z" type: "block" dataHash: "SGFzaCBvZiB0aGUgZGF0YQ==" chain: height: 1024 lastBlockTime: "2023-01-01T12:05:00Z" ErrorResponse: type: object properties: error: type: string description: Error message code: type: string description: Error code example: error: "Invalid input data" code: "VALIDATION_ERROR" MetricsResponse: type: object properties: blockchainHeight: type: integer format: uint64 description: Current height of the blockchain queueLength: type: integer description: Current length of the job queue example: blockchainHeight: 1024 queueLength: 5 BlockchainInfoResponse: type: object properties: height: type: integer format: uint64 description: Current height of the blockchain example: height: 1024 QueueInfoResponse: type: object properties: length: type: integer description: Current length of the job queue example: length: 5 BlockInfo: type: object properties: index: type: integer format: uint64 description: Block index timestamp: type: string description: Block timestamp data: type: string format: byte description: Block data hash: type: string format: byte description: Block hash example: index: 42 timestamp: "2023-01-01T12:00:00Z" data: "SGVsbG8sIHdvcmxkIQ==" hash: "QmFzZTY0IGVuY29kZWQgaGFzaA==" LoginRequest: type: object required: - username - password properties: username: type: string description: Username for authentication password: type: string description: Password for authentication format: password example: username: "admin" password: "admin123" LoginResponse: type: object properties: token: type: string description: JWT token for authentication expiresAt: type: string format: date-time description: Token expiration time user: type: object properties: id: type: string description: User ID username: type: string description: Username role: type: string description: User role (admin, user, etc.) example: token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIiwiZXhwIjoxNjcyNjYxNjAwLCJpYXQiOjE2NzI1NzUyMDAsIm5iZiI6MTY3MjU3NTIwMCwiaXNzIjoidGltZXN0YW1waW5nLXNlcnZpY2UifQ.8yF71oHxDCQ5-OW2c-KR7q-PJxbaHvmDGmSlOFREIQY" expiresAt: "2023-01-02T12:00:00Z" user: id: "550e8400-e29b-41d4-a716-446655440000" username: "admin" role: "admin" TokenValidationResponse: type: object properties: valid: type: boolean description: Whether the token is valid userId: type: string description: User ID (only present if valid) username: type: string description: Username (only present if valid) role: type: string description: User role (only present if valid) expiresAt: type: string format: date-time description: Token expiration time (only present if valid) example: valid: true userId: "550e8400-e29b-41d4-a716-446655440000" username: "admin" role: "admin" expiresAt: "2023-01-02T12:00:00Z" UserResponse: type: object properties: id: type: string description: User ID username: type: string description: Username role: type: string description: User role (admin, user, etc.) example: id: "550e8400-e29b-41d4-a716-446655440000" username: "admin" role: "admin" CreateUserRequest: type: object required: - username - password - role properties: username: type: string description: Username for the new user password: type: string description: Password for the new user format: password role: type: string description: Role for the new user (admin, user, etc.) example: username: "newuser" password: "password123" role: "user" UpdateUserRequest: type: object properties: password: type: string description: New password (optional) format: password role: type: string description: New role (optional) example: password: "newpassword123" role: "admin"