openapi: 3.0.3
info:
  title: CloudNix API
  description: |
    CloudNix is a unified cloud platform providing compute, storage, networking, and more.
    
    ## Authentication
    All API requests require authentication using an API key. Include your API key in the Authorization header:
    ```
    Authorization: Bearer YOUR_API_KEY
    ```
    
    ## Rate Limiting
    - Free tier: 60 requests/minute
    - Pro tier: 1000 requests/minute
    - Enterprise tier: Custom limits
    
    ## Errors
    CloudNix uses standard HTTP status codes:
    - 200-299: Success
    - 400-499: Client errors
    - 500-599: Server errors
    
  version: 1.0.0
  contact:
    name: CloudNix API Support
    email: api-support@cloudnix.io
    url: https://cloudnix.io/support
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

servers:
  - url: https://api.cloudnix.io/v1
    description: Production
  - url: https://api-staging.cloudnix.io/v1
    description: Staging
  - url: http://localhost:8080/v1
    description: Local Development

tags:
  - name: Authentication
    description: User authentication and API key management
  - name: Compute
    description: Virtual machines and serverless functions
  - name: Storage
    description: Object storage and buckets
  - name: Networking
    description: VPCs, load balancers, and DNS
  - name: Billing
    description: Subscriptions, usage, and invoicing
  - name: KMS
    description: Key management and encryption

security:
  - BearerAuth: []
  - ApiKeyAuth: []

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token obtained from login endpoint
    
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for programmatic access

  schemas:
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          example: "invalid_request"
        message:
          type: string
          example: "The request was invalid"
        details:
          type: object
          additionalProperties: true

    User:
      type: object
      required:
        - id
        - email
      properties:
        id:
          type: integer
          example: 123
        email:
          type: string
          format: email
          example: "user@example.com"
        full_name:
          type: string
          example: "John Doe"
        email_verified:
          type: boolean
          example: true
        mfa_enabled:
          type: boolean
          example: false
        created_at:
          type: string
          format: date-time
        status:
          type: string
          enum: [active, suspended, deleted]

    APIKey:
      type: object
      required:
        - id
        - name
        - scopes
      properties:
        id:
          type: integer
        key_hash:
          type: string
          description: Hashed version of the key (never the plain key)
        name:
          type: string
          example: "Production API Key"
        scopes:
          type: array
          items:
            type: string
          example: ["compute:*", "storage:read"]
        expires_at:
          type: string
          format: date-time
          nullable: true
        last_used_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time

    Instance:
      type: object
      required:
        - id
        - name
        - zone
        - machine_type
        - status
      properties:
        id:
          type: string
          example: "inst-a1b2c3d4"
        name:
          type: string
          example: "web-server-01"
        zone:
          type: string
          example: "us-central1-a"
        machine_type:
          type: string
          example: "e2-standard-4"
        status:
          type: string
          enum: [provisioning, running, stopping, stopped, terminated]
        internal_ip:
          type: string
          example: "10.0.0.5"
        external_ip:
          type: string
          example: "203.0.113.45"
        disk_size_gb:
          type: integer
          example: 50
        image:
          type: string
          example: "ubuntu-22.04-lts"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Function:
      type: object
      required:
        - id
        - name
        - runtime
        - handler
      properties:
        id:
          type: string
          example: "func-x1y2z3w4"
        name:
          type: string
          example: "process-webhook"
        runtime:
          type: string
          enum: [python3.11, nodejs20, go121, rust]
        handler:
          type: string
          example: "index.handler"
        memory_mb:
          type: integer
          example: 256
        timeout_seconds:
          type: integer
          example: 30
        environment_vars:
          type: object
          additionalProperties:
            type: string
        status:
          type: string
          enum: [active, inactive]
        created_at:
          type: string
          format: date-time

    Bucket:
      type: object
      required:
        - id
        - name
        - region
      properties:
        id:
          type: string
          example: "bucket-m5n4o3p2"
        name:
          type: string
          example: "my-app-assets"
        region:
          type: string
          example: "us-east1"
        is_public:
          type: boolean
          example: false
        versioning_enabled:
          type: boolean
          example: false
        cdn_enabled:
          type: boolean
          example: false
        created_at:
          type: string
          format: date-time

    VPC:
      type: object
      required:
        - id
        - name
        - cidr_block
      properties:
        id:
          type: string
          example: "vpc-abc123"
        name:
          type: string
          example: "production-vpc"
        region:
          type: string
          example: "us-central1"
        cidr_block:
          type: string
          example: "10.0.0.0/16"
        dns_enabled:
          type: boolean
          example: true
        status:
          type: string
          enum: [available, pending]
        created_at:
          type: string
          format: date-time

    Subscription:
      type: object
      required:
        - id
        - plan
        - status
      properties:
        id:
          type: integer
        user_id:
          type: integer
        plan:
          type: string
          enum: [free, pro, enterprise]
        status:
          type: string
          enum: [active, canceled, past_due, trialing]
        current_period_start:
          type: string
          format: date-time
        current_period_end:
          type: string
          format: date-time
        cancel_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time

paths:
  # ==================== Authentication ====================
  /auth/register:
    post:
      tags:
        - Authentication
      summary: Register a new user
      operationId: registerUser
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
                - password
                - full_name
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  format: password
                  minLength: 8
                full_name:
                  type: string
      responses:
        '201':
          description: User registered successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  user_id:
                    type: integer
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Email already registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /auth/login:
    post:
      tags:
        - Authentication
      summary: Login and get session token
      operationId: login
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - email
                - password
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  format: password
                mfa_code:
                  type: string
                  nullable: true
                remember_me:
                  type: boolean
      responses:
        '200':
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_token:
                    type: string
                  user:
                    $ref: '#/components/schemas/User'
                  expires_at:
                    type: integer
                    format: int64
        '401':
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /auth/keys:
    get:
      tags:
        - Authentication
      summary: List API keys
      operationId: listApiKeys
      responses:
        '200':
          description: List of API keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_keys:
                    type: array
                    items:
                      $ref: '#/components/schemas/APIKey'
    
    post:
      tags:
        - Authentication
      summary: Create new API key
      operationId: createApiKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - scopes
              properties:
                name:
                  type: string
                scopes:
                  type: array
                  items:
                    type: string
                expires_at:
                  type: string
                  format: date-time
                  nullable: true
      responses:
        '201':
          description: API key created
          content:
            application/json:
              schema:
                type: object
                properties:
                  key:
                    type: string
                    description: Plain API key (only shown once)
                  api_key:
                    $ref: '#/components/schemas/APIKey'

  # ==================== Compute ====================
  /compute/instances:
    get:
      tags:
        - Compute
      summary: List compute instances
      operationId: listInstances
      parameters:
        - name: zone
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of instances
          content:
            application/json:
              schema:
                type: object
                properties:
                  instances:
                    type: array
                    items:
                      $ref: '#/components/schemas/Instance'
                  total:
                    type: integer
    
    post:
      tags:
        - Compute
      summary: Create a new instance
      operationId: createInstance
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - zone
                - machine_type
                - image
              properties:
                name:
                  type: string
                zone:
                  type: string
                machine_type:
                  type: string
                image:
                  type: string
                disk_size_gb:
                  type: integer
                  default: 20
      responses:
        '201':
          description: Instance created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Instance'

  /compute/instances/{instanceId}/start:
    post:
      tags:
        - Compute
      summary: Start an instance
      operationId: startInstance
      parameters:
        - name: instanceId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Instance starting
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                  status:
                    type: string

  /compute/instances/{instanceId}/stop:
    post:
      tags:
        - Compute
      summary: Stop an instance
      operationId: stopInstance
      parameters:
        - name: instanceId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Instance stopping

  /compute/functions:
    get:
      tags:
        - Compute
      summary: List functions
      operationId: listFunctions
      responses:
        '200':
          description: List of functions
          content:
            application/json:
              schema:
                type: object
                properties:
                  functions:
                    type: array
                    items:
                      $ref: '#/components/schemas/Function'
    
    post:
      tags:
        - Compute
      summary: Create a new function
      operationId: createFunction
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - runtime
                - handler
              properties:
                name:
                  type: string
                runtime:
                  type: string
                handler:
                  type: string
                memory_mb:
                  type: integer
                timeout_seconds:
                  type: integer
                environment_vars:
                  type: object
      responses:
        '201':
          description: Function created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Function'

  # ==================== Storage ====================
  /storage/buckets:
    get:
      tags:
        - Storage
      summary: List storage buckets
      operationId: listBuckets
      responses:
        '200':
          description: List of buckets
          content:
            application/json:
              schema:
                type: object
                properties:
                  buckets:
                    type: array
                    items:
                      $ref: '#/components/schemas/Bucket'
    
    post:
      tags:
        - Storage
      summary: Create a new bucket
      operationId: createBucket
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - region
              properties:
                name:
                  type: string
                region:
                  type: string
                is_public:
                  type: boolean
                versioning_enabled:
                  type: boolean
      responses:
        '201':
          description: Bucket created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bucket'

  /storage/buckets/{bucketName}/objects:
    get:
      tags:
        - Storage
      summary: List objects in bucket
      operationId: listObjects
      parameters:
        - name: bucketName
          in: path
          required: true
          schema:
            type: string
        - name: prefix
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of objects

  # ==================== Networking ====================
  /network/vpcs:
    get:
      tags:
        - Networking
      summary: List VPCs
      operationId: listVpcs
      responses:
        '200':
          description: List of VPCs
          content:
            application/json:
              schema:
                type: object
                properties:
                  vpcs:
                    type: array
                    items:
                      $ref: '#/components/schemas/VPC'
    
    post:
      tags:
        - Networking
      summary: Create a new VPC
      operationId: createVpc
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - cidr_block
                - region
              properties:
                name:
                  type: string
                cidr_block:
                  type: string
                region:
                  type: string
                dns_enabled:
                  type: boolean
      responses:
        '201':
          description: VPC created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VPC'

  # ==================== Billing ====================
  /billing/subscriptions:
    get:
      tags:
        - Billing
      summary: List subscriptions
      operationId: listSubscriptions
      responses:
        '200':
          description: List of subscriptions
          content:
            application/json:
              schema:
                type: object
                properties:
                  subscriptions:
                    type: array
                    items:
                      $ref: '#/components/schemas/Subscription'
    
    post:
      tags:
        - Billing
      summary: Create a new subscription
      operationId: createSubscription
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - user_id
                - plan
              properties:
                user_id:
                  type: integer
                plan:
                  type: string
                  enum: [free, pro, enterprise]
                payment_method_id:
                  type: string
      responses:
        '201':
          description: Subscription created

  /billing/usage:
    get:
      tags:
        - Billing
      summary: Get usage records
      operationId: getUsage
      parameters:
        - name: user_id
          in: query
          schema:
            type: integer
        - name: start_date
          in: query
          schema:
            type: string
            format: date
        - name: end_date
          in: query
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Usage records
          content:
            application/json:
              schema:
                type: object
                properties:
                  records:
                    type: array
                    items:
                      type: object
                  total_cost:
                    type: number

