openapi: 3.0.3
info:
  title: LogFlux API
  description: |
    The LogFlux API provides endpoints for ingesting encrypted log data into the LogFlux platform.
    
    ## Important: Encryption Requirement
    **All log payloads must be encrypted** before sending to LogFlux. We use AES-256-GCM encryption with PBKDF2 key derivation (600,000 iterations) for maximum security.
    
    ## Authentication
    All authenticated endpoints require API keys in the format:
    ```
    Authorization: Bearer lf_your_api_key_here
    ```
    
    ## Base URLs
    LogFlux provides customer-specific endpoints:
    - Format: `https://[customer-id].ingest.[region].logflux.io/v1`
    - Example: `https://c12345.ingest.us.logflux.io/v1`
    
    Choose the endpoint based on your data residency requirements.
  version: 1.0.0
  contact:
    name: LogFlux Support
    email: support@logflux.io
    url: https://logflux.io/support
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

servers:
  - url: https://{customerId}.ingest.{region}.logflux.io/v1
    description: Customer-specific production server
    variables:
      customerId:
        default: c12345
        description: Your customer ID (format c followed by digits)
      region:
        default: us
        enum:
          - us
          - eu
        description: Region for data residency

tags:
  - name: Health
    description: Service health and version endpoints
  - name: Ingestion
    description: Log ingestion endpoints

paths:
  /health:
    get:
      tags:
        - Health
      summary: Health check
      description: Check if the service is running
      operationId: getHealth
      security: []
      responses:
        '200':
          description: Service is healthy
          content:
            text/plain:
              schema:
                type: string
                example: OK

  /version:
    get:
      tags:
        - Health
      summary: Version information
      description: Get API version and compatibility information
      operationId: getVersion
      security: []
      responses:
        '200':
          description: Version information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionInfo'

  /ingest:
    post:
      tags:
        - Ingestion
      summary: Ingest single log entry
      description: Send an encrypted log entry to LogFlux
      operationId: ingestLog
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LogEntry'
            examples:
              encrypted:
                summary: Encrypted log entry
                value:
                  node: "app-server-01"
                  payload: "YWJjZGVmZ2hpams...base64-encrypted-data..."
                  loglevel: 7
                  timestamp: "2024-01-17T10:30:45Z"
                  encryption_mode: 1
                  iv: "dGVzdGl2MTIzNDU2"
                  salt: "c2FsdDMyYnl0ZXNsb25nZm9ya2V5ZGVyaXZhdGlvbg=="
      responses:
        '200':
          description: Log entry processed successfully
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
                example: 600
              description: Maximum requests per minute
            X-RateLimit-Remaining:
              schema:
                type: integer
                example: 599
              description: Requests remaining in current window
            X-RateLimit-Reset:
              schema:
                type: integer
                example: 1705493445
              description: Unix timestamp when rate limit resets
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalError'

  /batch:
    post:
      tags:
        - Ingestion
      summary: Batch ingest log entries
      description: Submit multiple encrypted log entries in a single request (max 100 entries)
      operationId: batchIngestLogs
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchLogEntries'
            examples:
              batch:
                summary: Batch of encrypted log entries
                value:
                  entries:
                    - node: "app-server-01"
                      payload: "YWJjZGVmZ2hpams...base64-encrypted-data..."
                      loglevel: 7
                      timestamp: "2024-01-17T10:30:45Z"
                      encryption_mode: 1
                      iv: "dGVzdGl2MTIzNDU2"
                      salt: "c2FsdDMyYnl0ZXNsb25nZm9ya2V5ZGVyaXZhdGlvbg=="
                    - node: "app-server-01"
                      payload: "WFlaZGVmZ2hpams...base64-encrypted-data..."
                      loglevel: 5
                      timestamp: "2024-01-17T10:30:46Z"
                      encryption_mode: 1
                      iv: "YW5vdGhlcml2MTIz"
                      salt: "ZGlmZmVyZW50c2FsdDMyYnl0ZXNmb3JrZXlkZXJpdmU="
      responses:
        '200':
          description: Batch processed successfully
          headers:
            X-RateLimit-Limit:
              schema:
                type: integer
                example: 600
            X-RateLimit-Remaining:
              schema:
                type: integer
                example: 599
            X-RateLimit-Reset:
              schema:
                type: integer
                example: 1705493445
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
        '500':
          $ref: '#/components/responses/InternalError'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: |
        API key authentication using Bearer token format.
        Example: `Authorization: Bearer lf_your_api_key_here`

  schemas:
    VersionInfo:
      type: object
      properties:
        api_version:
          type: string
          example: "v1"
        service:
          type: string
          example: "logflux-ingestor"
        supported_versions:
          type: array
          items:
            type: string
          example: ["v1"]
        deprecated_versions:
          type: array
          items:
            type: string
          example: []

    LogEntry:
      type: object
      required:
        - node
        - payload
        - loglevel
        - timestamp
        - encryption_mode
        - iv
        - salt
      properties:
        node:
          type: string
          description: Source identifier
          maxLength: 255
          example: "app-server-01"
        payload:
          type: string
          description: Encrypted log data (base64 encoded)
          maxLength: 1048576
          example: "YWJjZGVmZ2hpams...base64-encrypted-data..."
        loglevel:
          type: integer
          description: |
            Syslog-compatible severity level:
            - 1: EMERGENCY - System is unusable
            - 2: ALERT - Action must be taken immediately
            - 3: CRITICAL - Critical conditions
            - 4: ERROR - Error conditions
            - 5: WARNING - Warning conditions
            - 6: NOTICE - Normal but significant
            - 7: INFO - Informational messages
            - 8: DEBUG - Debug-level messages
          minimum: 1
          maximum: 8
          example: 7
        timestamp:
          type: string
          format: date-time
          description: Event timestamp (ISO 8601 with timezone)
          example: "2024-01-17T10:30:45Z"
        encryption_mode:
          type: integer
          description: |
            Encryption algorithm used:
            - 1: AES256-GCM_PBKDF2-SHA256-600K (Current Standard)
            - 2: AES256-GCM_SCRYPT (Future)
            - 3: AES256-GCM_ARGON2 (Future)
            - 4: ChaCha20-Poly1305_ARGON2 (Future)
          enum: [1, 2, 3, 4]
          example: 1
        iv:
          type: string
          description: Initialization vector (base64 encoded, 12 bytes)
          example: "dGVzdGl2MTIzNDU2"
        salt:
          type: string
          description: Salt for key derivation (base64 encoded, 32 bytes)
          example: "c2FsdDMyYnl0ZXNsb25nZm9ya2V5ZGVyaXZhdGlvbg=="

    BatchLogEntries:
      type: object
      required:
        - entries
      properties:
        entries:
          type: array
          description: Array of log entries (max 100)
          maxItems: 100
          items:
            $ref: '#/components/schemas/LogEntry'

    SuccessResponse:
      type: object
      properties:
        status:
          type: string
          example: "success"
        message:
          type: string
          example: "Log entry processed successfully"
        request_id:
          type: string
          example: "req_abc123def456"

    ErrorResponse:
      type: object
      required:
        - status
        - error
      properties:
        status:
          type: string
          example: "error"
        error:
          type: object
          properties:
            code:
              type: string
              example: "INVALID_API_KEY"
            message:
              type: string
              example: "The provided API key is invalid"
            details:
              type: string
              example: "API key must start with 'lf_'"
        request_id:
          type: string
          example: "req_abc123def456"

  responses:
    BadRequest:
      description: Bad request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalid_log_level:
              value:
                status: "error"
                error:
                  code: "INVALID_LOG_LEVEL"
                  message: "Log level out of range"
                  details: "Log level must be between 1 and 8"
            invalid_encryption_mode:
              value:
                status: "error"
                error:
                  code: "INVALID_ENCRYPTION_MODE"
                  message: "Unsupported encryption mode"
                  details: "Only encryption mode 1 is currently supported"
            invalid_timestamp:
              value:
                status: "error"
                error:
                  code: "INVALID_TIMESTAMP"
                  message: "Timestamp format error"
                  details: "Timestamp must be in ISO 8601 format with timezone"

    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalid_api_key:
              value:
                status: "error"
                error:
                  code: "INVALID_API_KEY"
                  message: "The provided API key is invalid"
                  details: "API key must start with 'lf_'"

    PayloadTooLarge:
      description: Payload too large
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            payload_too_large:
              value:
                status: "error"
                error:
                  code: "PAYLOAD_TOO_LARGE"
                  message: "Payload exceeds size limit"
                  details: "Maximum payload size is 1MB"

    RateLimitExceeded:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
            example: 600
        X-RateLimit-Remaining:
          schema:
            type: integer
            example: 0
        X-RateLimit-Reset:
          schema:
            type: integer
            example: 1705493445
        Retry-After:
          schema:
            type: integer
            example: 45
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rate_limit:
              value:
                status: "error"
                error:
                  code: "RATE_LIMIT_EXCEEDED"
                  message: "API rate limit exceeded"
                  retry_after: 45

    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            internal_error:
              value:
                status: "error"
                error:
                  code: "INTERNAL_ERROR"
                  message: "Internal server error"

externalDocs:
  description: LogFlux API Documentation
  url: https://docs.logflux.io/api