openapi: 3.0.3 info: title: Tingz Deployer API description: A secure, lightweight HTTP service for deploying static sites. The service receives tarball artifacts, validates and publishes them under a per-user directory structure for docs.yigid.dev. Designed for CI/CD automation with GitHub Actions, GitLab CI, etc. version: 1.0.0 contact: name: Yigid BALABAN email: hey@yigid.dev url: https://yigid.dev/ license: name: AGPL-3.0-only url: https://opensource.org/license/agpl-v3 servers: - url: https://docs.yigid.dev description: Production server - url: http://localhost:8080 description: Development server paths: /api/v1/auth: post: tags: - Authentication summary: Create or reroll user token description: Creates a new user or generates a new token for an existing user. Admin only endpoint. operationId: createOrRerollUser security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' example: username: alice responses: '200': description: User created or token rerolled successfully content: application/json: schema: $ref: '#/components/schemas/AuthResponse' example: status: ok token: 82lz0BVOWtV4uVj9DBZBuKMeyVDwidL2 '400': description: Invalid request body or username format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidBody: summary: Invalid request body value: status: error error: invalid request body invalidUsername: summary: Invalid username format value: status: error error: invalid username format '401': description: Unauthorized - Invalid admin token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: invalid admin token '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: failed to create user delete: tags: - Authentication summary: Delete user description: Deletes a user and optionally their files. Admin only endpoint. operationId: deleteUser security: - AdminAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeleteUserRequest' examples: persistFiles: summary: Delete user but keep files value: username: alice files: persist deleteFiles: summary: Delete user and all files value: username: alice files: delete responses: '200': description: User deleted successfully content: application/json: schema: $ref: '#/components/schemas/SuccessResponse' example: status: ok '400': description: Invalid request body, username format, or files parameter content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: invalidBody: summary: Invalid request body value: status: error error: invalid request body invalidUsername: summary: Invalid username format value: status: error error: invalid username format invalidFiles: summary: Invalid files parameter value: status: error error: files must be 'persist' or 'delete' '401': description: Unauthorized - Invalid admin token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: invalid admin token '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: user not found /api/v1/deploy: post: tags: - Deployment summary: Deploy static site description: Uploads and deploys a static site tarball. Creates a new release and atomically updates the live site via symlink swap. operationId: deploySite security: - UserAuth: [] requestBody: required: true content: multipart/form-data: schema: type: object required: - project - file properties: project: type: string description: Project name (must match username validation pattern) pattern: ^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$ minLength: 1 maxLength: 64 example: myproject file: type: string format: binary description: Tarball file (.tar.gz) containing the static site responses: '200': description: Deployment successful content: application/json: schema: $ref: '#/components/schemas/DeployResponse' example: status: ok project: myproject username: alice url: https://docs.yigid.dev/alice/myproject/ release: 20251014T180806 '400': description: Invalid request - missing file, invalid project name, or multipart form parsing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missingFile: summary: Missing or invalid file value: status: error error: missing or invalid file invalidProject: summary: Invalid project name format value: status: error error: invalid project name format parseError: summary: Failed to parse multipart form value: status: error error: failed to parse multipart form '401': description: Unauthorized - Invalid user token content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: unauthorized '413': description: Request entity too large - Upload exceeds maximum size limit content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: status: error error: request body too large '500': description: Internal server error during deployment content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: extractionError: summary: Failed to extract tarball value: status: error error: 'failed to extract tarball: path contains ''..'' component which is not allowed: ../../etc/passwd' generalError: summary: General deployment error value: status: error error: deployment failed /api/v1/status: get: tags: - Health summary: Health check description: Returns the current status of the service operationId: getStatus responses: '200': description: Service is healthy content: application/json: schema: $ref: '#/components/schemas/StatusResponse' example: status: ok /api/hello: get: tags: - Info summary: Service information description: Returns basic information about the service and author operationId: getHello responses: '200': description: Service information content: application/json: schema: $ref: '#/components/schemas/HelloResponse' example: message: Close the world, .txen eht nepO author: Yigid BALABAN authorHomepage: https://yigid.dev/ components: securitySchemes: AdminAuth: type: http scheme: bearer description: Admin bearer token for user management operations UserAuth: type: http scheme: bearer description: User bearer token for deployment operations schemas: CreateUserRequest: type: object required: - username properties: username: type: string description: Username for the new user (lowercase letters, numbers, hyphens, underscores only) pattern: ^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$ minLength: 1 maxLength: 64 example: alice DeleteUserRequest: type: object required: - username properties: username: type: string description: Username of the user to delete pattern: ^[a-z0-9]([a-z0-9_-]{0,62}[a-z0-9])?$ minLength: 1 maxLength: 64 example: alice files: type: string description: Whether to persist or delete user files enum: - persist - delete default: persist example: persist AuthResponse: type: object required: - status - token properties: status: type: string enum: - ok example: ok token: type: string description: 32-character alphanumeric token for API access minLength: 32 maxLength: 32 example: 82lz0BVOWtV4uVj9DBZBuKMeyVDwidL2 DeployResponse: type: object required: - status - project - username - url - release properties: status: type: string enum: - ok example: ok project: type: string description: Project name example: myproject username: type: string description: Username who deployed example: alice url: type: string format: uri description: Public URL where the site is accessible example: https://docs.yigid.dev/alice/myproject/ release: type: string description: 'Release ID (timestamp format: YYYYMMDDTHHMMSS)' pattern: ^[0-9]{8}T[0-9]{6}$ example: 20251014T180806 StatusResponse: type: object required: - status properties: status: type: string enum: - ok example: ok HelloResponse: type: object required: - message - author - authorHomepage properties: message: type: string description: Service message example: Close the world, .txen eht nepO author: type: string description: Author information example: Yigid BALABAN authorHomepage: type: string format: uri description: Author homepage URL example: https://yigid.dev/ SuccessResponse: type: object required: - status properties: status: type: string enum: - ok example: ok ErrorResponse: type: object required: - status - error properties: status: type: string enum: - error example: error error: type: string description: Error message describing what went wrong example: invalid username format tags: - name: Authentication description: User management operations (admin only) - name: Deployment description: Static site deployment operations - name: Health description: Service health and status endpoints - name: Info description: Service information endpoints