openapi: 3.1.0
info:
  title: Hardcarrx Public API
  version: 1.0.0
  summary: Public API reference for Hardcarrx routing, memory, models, and request logs.
  description: |
    Hardcarrx provides OpenAI-style chat completions with workspace-scoped provider credentials,
    memory operations, model discovery, and request observability.

    This public reference includes only customer-facing routes. Examples use placeholders only.
servers:
  - url: https://api.hardcarrx.com
    description: Production API
security:
  - HardcarrxApiKey: []
tags:
  - name: Chat
    description: OpenAI-compatible chat completion routing.
  - name: Models
    description: Public model discovery.
  - name: Memory
    description: Workspace-scoped memory operations.
  - name: Logs
    description: Request observability for authenticated traffic.
paths:
  /v1/models:
    get:
      operationId: listModels
      tags:
        - Models
      summary: List available models
      description: Returns the public model catalog available through Hardcarrx.
      security: []
      responses:
        "200":
          description: Public model list.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ModelListResponse"
              examples:
                models:
                  summary: Model list
                  value:
                    object: list
                    data:
                      - id: openai/gpt-4o-mini
                        object: model
                        provider: openrouter
                        display_name: GPT-4o mini
                      - id: gpt-4.1-mini
                        object: model
                        provider: openai
                        display_name: GPT-4.1 mini
  /v1/chat/completions:
    post:
      operationId: createChatCompletion
      tags:
        - Chat
      summary: Create a chat completion
      description: |
        Sends an OpenAI-style chat completion request through Hardcarrx.

        You can either use a provider key already stored in Dashboard -> Providers, or send a
        one-request provider key in `provider_key`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChatCompletionRequest"
            examples:
              storedProviderKey:
                summary: Stored provider credential
                value:
                  provider: openai
                  model: gpt-4.1-mini
                  messages:
                    - role: user
                      content: "Reply with exactly: hardcarrx docs live"
              inlineProviderKey:
                summary: Inline provider credential for one request
                value:
                  provider: openrouter
                  provider_key: sk-or-v1-your_provider_key
                  model: openai/gpt-4o-mini
                  messages:
                    - role: user
                      content: "Reply with exactly: hardcarrx docs live"
      responses:
        "200":
          description: Chat completion response.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatCompletionResponse"
              examples:
                completion:
                  summary: Completion
                  value:
                    id: chatcmpl_placeholder
                    object: chat.completion
                    created: 1763090000
                    model: gpt-4.1-mini
                    choices:
                      - index: 0
                        message:
                          role: assistant
                          content: hardcarrx docs live
                        finish_reason: stop
                    usage:
                      prompt_tokens: 14
                      completion_tokens: 5
                      total_tokens: 19
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "402":
          $ref: "#/components/responses/QuotaExceeded"
        "429":
          $ref: "#/components/responses/RateLimited"
        "500":
          $ref: "#/components/responses/ServiceError"
  /memory/store:
    post:
      operationId: storeMemory
      tags:
        - Memory
      summary: Store a memory
      description: Stores workspace-scoped memory for later retrieval.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MemoryStoreRequest"
            examples:
              preference:
                summary: Store a preference
                value:
                  content: Prefer concise launch-readiness summaries.
                  metadata:
                    source: api
                    category: preference
      responses:
        "200":
          description: Memory stored.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MemoryStoreResponse"
              examples:
                stored:
                  summary: Stored
                  value:
                    ok: true
                    memory_id: mem_placeholder
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /v1/memory/query:
    post:
      operationId: queryMemory
      tags:
        - Memory
      summary: Query memory
      description: Retrieves relevant memory for the authenticated workspace.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MemoryQueryRequest"
            examples:
              query:
                summary: Query
                value:
                  query: What launch-readiness details should be remembered?
                  limit: 5
      responses:
        "200":
          description: Query result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MemoryQueryResponse"
              examples:
                results:
                  summary: Results
                  value:
                    results:
                      - memory_id: mem_placeholder
                        content: Prefer concise launch-readiness summaries.
                        score: 0.91
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /v1/request-logs:
    get:
      operationId: listRequestLogs
      tags:
        - Logs
      summary: List request logs
      description: Lists recent authenticated request logs for the current workspace.
      parameters:
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        "200":
          description: Request log list.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestLogListResponse"
              examples:
                logs:
                  summary: Logs
                  value:
                    logs:
                      - request_id: req_placeholder
                        route: /v1/chat/completions
                        status: SUCCESS
                        provider: openrouter
                        model: openai/gpt-4o-mini
                        cache_state: MISS
                        memory_state: SKIPPED
                        created_at: "2026-06-29T12:23:43Z"
                    limit: 25
                    offset: 0
        "401":
          $ref: "#/components/responses/Unauthorized"
components:
  securitySchemes:
    HardcarrxApiKey:
      type: http
      scheme: bearer
      bearerFormat: hmpk_
      description: |
        Hardcarrx API key. Send as `Authorization: Bearer hmpk_your_api_key` or `x-api-key`.
  schemas:
    ChatCompletionRequest:
      type: object
      required:
        - provider
        - model
        - messages
      additionalProperties: true
      properties:
        provider:
          type: string
          examples:
            - openai
            - openrouter
        provider_key:
          type: string
          description: Optional provider key for one-request BYOK usage. Omit when using a stored provider credential.
          examples:
            - sk-or-v1-your_provider_key
        model:
          type: string
          examples:
            - gpt-4.1-mini
            - openai/gpt-4o-mini
        messages:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/ChatMessage"
        temperature:
          type: number
          minimum: 0
          maximum: 2
        max_tokens:
          type: integer
          minimum: 1
    ChatMessage:
      type: object
      required:
        - role
        - content
      properties:
        role:
          type: string
          enum:
            - system
            - user
            - assistant
            - tool
        content:
          type: string
    ChatCompletionResponse:
      type: object
      properties:
        id:
          type: string
        object:
          type: string
        created:
          type: integer
        model:
          type: string
        choices:
          type: array
          items:
            type: object
            properties:
              index:
                type: integer
              message:
                $ref: "#/components/schemas/ChatMessage"
              finish_reason:
                type: string
        usage:
          $ref: "#/components/schemas/TokenUsage"
    TokenUsage:
      type: object
      properties:
        prompt_tokens:
          type: integer
        completion_tokens:
          type: integer
        total_tokens:
          type: integer
    ModelListResponse:
      type: object
      properties:
        object:
          type: string
          examples:
            - list
        data:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              object:
                type: string
              provider:
                type: string
              display_name:
                type: string
    MemoryStoreRequest:
      type: object
      required:
        - content
      properties:
        content:
          type: string
        metadata:
          type: object
          additionalProperties: true
    MemoryStoreResponse:
      type: object
      properties:
        ok:
          type: boolean
        memory_id:
          type: string
    MemoryQueryRequest:
      type: object
      required:
        - query
      properties:
        query:
          type: string
        limit:
          type: integer
          minimum: 1
          maximum: 50
          default: 5
    MemoryQueryResponse:
      type: object
      properties:
        results:
          type: array
          items:
            type: object
            properties:
              memory_id:
                type: string
              content:
                type: string
              score:
                type: number
    RequestLogListResponse:
      type: object
      properties:
        logs:
          type: array
          items:
            type: object
            properties:
              request_id:
                type: string
              route:
                type: string
              status:
                type: string
              provider:
                type: string
              model:
                type: string
              cache_state:
                type: string
              memory_state:
                type: string
              created_at:
                type: string
                format: date-time
        limit:
          type: integer
        offset:
          type: integer
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              oneOf:
                - type: integer
                - type: string
            message:
              type: string
  responses:
    BadRequest:
      description: Invalid request payload.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            invalidPayload:
              value:
                error:
                  code: 400
                  message: invalid request payload
    Unauthorized:
      description: Missing or invalid Hardcarrx API key.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            unauthorized:
              value:
                error:
                  code: 401
                  message: missing or invalid Hardcarrx API key
    QuotaExceeded:
      description: Current plan or quota cannot accept this request.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            quota:
              value:
                error:
                  code: 402
                  message: quota exceeded
    RateLimited:
      description: Rate limit reached.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            rateLimit:
              value:
                error:
                  code: 429
                  message: rate limit reached
    ServiceError:
      description: Provider or service error.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
          examples:
            serviceError:
              value:
                error:
                  code: 500
                  message: provider or service error
