openapi: 3.1.0
info:
  title: RedPill AI API
  description: >
    OpenAI-compatible inference served by an Attested Confidential Inference (ACI) gateway
    running in a TEE. Responses carry an x-receipt-id header; verification artifacts are
    available under /aci; /attestation/report and /signature/{id} are legacy aliases.
  version: 2.0.0
  contact:
    name: RedPill AI Support
    url: https://redpill.ai
    email: support@redpill.ai
servers:
  - url: https://api.redpill.ai/v1
    description: Production API

security:
  - bearerAuth: []

paths:
  /models:
    get:
      summary: List Models
      description: >-
        Returns all available models. Models with is_tee=true can be served confidentially, and
        can be listed on their own with `?tee=true`.
      operationId: listModels
      tags: [Models]
      parameters:
        - name: zdr
          in: query
          required: false
          description: >-
            Set to `true` to return only models that can be served under zero data retention,
            meaning the upstream provider does not retain prompt or completion content. A model is
            included when at least one provider that can serve it operates under zero data
            retention. `true` is the only accepted value; any other value returns 400.
          schema:
            type: string
            enum: [ 'true' ]
        - name: tee
          in: query
          required: false
          description: >-
            Set to `true` to return only models offered confidentially, meaning the model object
            carries `is_tee: true`. This reports a model's own capability and does not promise that
            a given request reaches an attested provider; use `provider.aci_verified` on the request
            to require that. `true` is the only accepted value; any other value returns 400.
          schema:
            type: string
            enum: [ 'true' ]
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Model'

  /chat/completions:
    post:
      summary: Create Chat Completion
      description: >
        Creates a model response for the given conversation. The HTTP response includes an
        x-receipt-id header referencing the signed receipt for the response.
      operationId: createChatCompletion
      tags: [Chat]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatCompletionRequest'
            examples:
              confidential:
                summary: Confidential model (is_tee)
                value:
                  model: qwen/qwen3-30b-a3b-instruct-2507
                  messages:
                    - role: user
                      content: Explain attestation in one sentence.
              routed:
                summary: Routed model
                value:
                  model: openai/gpt-4o
                  messages:
                    - role: user
                      content: Hello
      responses:
        '200':
          description: Successful response
          headers:
            x-receipt-id:
              description: Id of the signed receipt for this response.
              schema: { type: string }
            x-aci-identity:
              description: Attested workload identity that served the request.
              schema: { type: string }
            x-aci-keyset-digest:
              description: Digest of the workload's published keyset.
              schema: { type: string }
            x-aci-version:
              description: ACI version, for example aci/1.
              schema: { type: string }
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatCompletionResponse'

  /completions:
    post:
      summary: Create Completion (Legacy)
      description: Legacy text completion. Use /chat/completions for new work.
      operationId: createCompletion
      deprecated: true
      tags: [Completions]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompletionRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompletionResponse'

  /embeddings:
    post:
      summary: Create Embeddings
      description: Generate vector embeddings. Buffered only.
      operationId: createEmbeddings
      tags: [Embeddings]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EmbeddingRequest'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbeddingResponse'

  /aci/attestation:
    get:
      summary: Get ACI Attestation Report
      operationId: getAciAttestationReport
      tags: [Verification]
      servers:
        - url: https://tee.redpill.ai/v1
          description: Attested gateway
      parameters:
        - name: nonce
          in: query
          required: false
          description: Exactly 64 lowercase hex characters (32 random bytes).
          schema:
            type: string
            pattern: '^[0-9a-f]{64}$'
      responses:
        '200':
          description: Canonical nonce-bound ACI attestation report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AciAttestationReport'

  /aci/receipts/{id}:
    get:
      summary: Get ACI Receipt
      operationId: getAciReceipt
      tags: [Verification]
      servers:
        - url: https://tee.redpill.ai/v1
          description: Attested gateway
      parameters:
        - name: id
          in: path
          required: true
          description: Receipt id (rcpt-...) or response/chat id.
          schema: { type: string }
      responses:
        '200':
          description: Canonical signed ACI receipt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Receipt'

  /aci/sessions:
    get:
      summary: List Current ACI Sessions
      operationId: listAciSessions
      tags: [Verification]
      servers:
        - url: https://tee.redpill.ai/v1
          description: Attested gateway
      parameters:
        - name: upstream_name
          in: query
          required: false
          schema: { type: string }
        - name: model
          in: query
          required: false
          schema: { type: string }
      responses:
        '200':
          description: Current attested sessions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AciSessionList'

  /aci/sessions/{session_id}:
    get:
      summary: Get ACI Session
      operationId: getAciSession
      tags: [Verification]
      servers:
        - url: https://tee.redpill.ai/v1
          description: Attested gateway
      parameters:
        - name: session_id
          in: path
          required: true
          description: Bare 64-character lowercase hex session id cited by a receipt.
          schema:
            type: string
            pattern: '^[0-9a-f]{64}$'
      responses:
        '200':
          description: Full immutable attested-session document
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AciSession'

  /attestation/report:
    get:
      summary: Get Attestation Report
      description: >
        Returns the gateway's TEE attestation report. Pass a fresh nonce; the gateway binds it
        into the quote's report_data so you can prove the report is not a replay.
      operationId: getAttestationReport
      tags: [Verification]
      parameters:
        - name: nonce
          in: query
          required: false
          description: Fresh random value in the legacy flexible nonce format.
          schema: { type: string }
      responses:
        '200':
          description: Attestation report
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttestationReport'

  /signature/{id}:
    get:
      summary: Get Receipt
      description: >
        Returns the signed receipt for a response. The id is a receipt id (rcpt-...) or the
        response id (chat id).
      operationId: getReceipt
      tags: [Verification]
      parameters:
        - name: id
          in: path
          required: true
          description: Receipt id or chat id.
          schema: { type: string }
      responses:
        '200':
          description: Signed receipt
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignedReceipt'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key

  schemas:
    Model:
      type: object
      properties:
        id: { type: string, example: qwen/qwen3-30b-a3b-instruct-2507 }
        name: { type: string, example: "Qwen3 30B A3B Instruct" }
        created: { type: integer, example: 1764804811 }
        is_tee: { type: boolean, description: "True if the model can be served confidentially, on a verified TEE provider.", example: true }
        input_modalities:
          type: array
          items: { type: string }
          example: [text]
        output_modalities:
          type: array
          items: { type: string }
          example: [text]
        context_length: { type: integer, example: 262144 }
        max_output_length: { type: integer, example: 262144 }
        pricing:
          type: object
          properties:
            prompt: { type: string, example: "0.00000032" }
            completion: { type: string, example: "0.00000048" }
        supported_parameters:
          type: array
          items: { type: string }
        providers:
          type: array
          items: { type: string }
          example: [near-ai]

    ChatCompletionRequest:
      type: object
      required: [model, messages]
      properties:
        model:
          type: string
          description: Model id. Models with is_tee=true can be served confidentially.
          example: qwen/qwen3-30b-a3b-instruct-2507
        messages:
          type: array
          items:
            type: object
            required: [role, content]
            properties:
              role: { type: string, enum: [system, user, assistant] }
              content: { type: string }
        temperature: { type: number, minimum: 0, maximum: 2 }
        max_tokens: { type: integer }
        stream: { type: boolean, default: false }
        top_p: { type: number, minimum: 0, maximum: 1 }
        provider:
          type: object
          description: >-
            Routing constraints for this request. If no provider satisfies them the request returns
            404 and no prompt is sent. Enforced for the whole request, including failover.
          properties:
            zdr:
              type: boolean
              default: false
              description: >-
                Restrict routing to providers that do not retain prompt or completion content after
                serving the request. `false`, or omitting the field, applies no constraint.
            aci_verified:
              type: boolean
              default: false
              description: >-
                Restrict routing to an upstream the gateway verified inside the TEE before sending
                the prompt. If none is available the request returns 503 and no prompt is sent. The
                `X-Upstream-Verification` header cannot relax this constraint. `false`, or omitting
                the field, applies no constraint.
            aci_session_ids:
              type: array
              minItems: 1
              items: { type: string }
              description: >-
                Restrict routing to specific attested channels, identified by session ids from
                `GET /v1/aci/sessions`. Any listed id may serve the request; if none matches a
                currently verified channel the request returns 503. Implies `aci_verified`, and
                returns 400 when combined with `aci_verified: false`.

    ChatCompletionResponse:
      type: object
      properties:
        id: { type: string }
        object: { type: string, example: chat.completion }
        created: { type: integer }
        model: { type: string }
        choices:
          type: array
          items:
            type: object
            properties:
              index: { type: integer }
              message:
                type: object
                properties:
                  role: { type: string }
                  content: { type: string }
              finish_reason: { type: string }
        usage:
          type: object
          properties:
            prompt_tokens: { type: integer }
            completion_tokens: { type: integer }
            total_tokens: { type: integer }

    CompletionRequest:
      type: object
      required: [model, prompt]
      properties:
        model: { type: string, example: openai/gpt-4o }
        prompt: { type: string, example: "Once upon a time" }
        max_tokens: { type: integer }
        temperature: { type: number, minimum: 0, maximum: 2 }

    CompletionResponse:
      type: object
      properties:
        id: { type: string }
        choices:
          type: array
          items: { type: object }

    EmbeddingRequest:
      type: object
      required: [model, input]
      properties:
        model: { type: string, example: openai/text-embedding-3-small }
        input:
          oneOf:
            - type: string
            - type: array
              items: { type: string }

    EmbeddingResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              embedding:
                type: array
                items: { type: number }
              index: { type: integer }
        usage: { type: object }

    AciAttestationReport:
      type: object
      properties:
        api_version: { type: string, example: aci/1 }
        workload_keyset_digest: { type: string, example: "sha256:3eff0836..." }
        service_capabilities:
          type: object
          properties:
            supported_e2ee_versions:
              type: array
              items: { type: string }
              example: ["2"]
            serving: { type: string, example: aggregator }
        attestation:
          $ref: '#/components/schemas/Attestation'

    AttestationReport:
      allOf:
        - $ref: '#/components/schemas/AciAttestationReport'
        - type: object
          properties:
            signing_address: { type: string, example: "0x79a5061efe5a46b0d1f33b11cf1c5adbedae6b79" }
            signing_algo: { type: string, example: ecdsa }
            signing_public_key: { type: string }
            intel_quote: { type: string }
            nvidia_payload: {}
            all_attestations:
              type: array
              description: Single-entry compatibility array containing the legacy report fields.
              items: { type: object }

    Attestation:
      type: object
      properties:
        tee_type: { type: string, example: tdx }
        report_data: { type: string, description: Commits to the caller nonce and the keyset. }
        source_provenance:
          type: object
          properties:
            repo_url: { type: string }
            repo_commit: { type: string }
            image_digest: { type: [string, "null"] }
            image_provenance: { type: [string, "null"] }
        workload_keyset:
          type: object
          properties:
            subject: { type: [string, "null"] }
            not_after: { type: integer }
            receipt_signing_keys: { type: array, items: { type: object } }
            e2ee_public_keys: { type: array, items: { type: object } }
            tls_public_keys: { type: array, items: { type: object } }
        evidence:
          type: object
          properties:
            quote: { type: string }
            quote_report_data: { type: string }
            event_log: { type: string }
            vm_config: { type: string }
            key_custody: { type: object }

    SignedReceipt:
      type: object
      properties:
        api_version: { type: string, example: aci/1 }
        signing_algo: { type: string, example: ecdsa }
        signing_address: { type: string }
        text:
          type: string
          description: "<request body hash>:<response body hash>. The signed message."
        signature: { type: string, description: ECDSA signature over text. }
        receipt:
          $ref: '#/components/schemas/Receipt'

    Receipt:
      type: object
      properties:
        api_version: { type: string }
        receipt_id: { type: string, example: rcpt-e0eefe63b3673e2a5984951f }
        chat_id: { type: [string, "null"] }
        model: { type: [string, "null"] }
        workload_keyset_digest: { type: string }
        endpoint: { type: string, example: /v1/chat/completions }
        method: { type: string, example: POST }
        served_at: { type: integer }
        key_id: { type: string }
        signature: { type: string }
        event_log:
          type: array
          items:
            type: object
            properties:
              type:
                type: string
                example: upstream.verified
              body_hash: { type: string }
              target_route_id: { type: string }
              model_id: { type: string }
              result: { type: string, example: verified }
              required: { type: boolean }
              session_id: { type: [string, "null"] }

    AciSession:
      type: object
      properties:
        api_version: { type: string, example: aci/1 }
        upstream_name: { type: string }
        endpoint: { type: [string, "null"] }
        verifier_id: { type: string }
        established_at: { type: integer }
        expires_at: { type: integer }
        identity: { type: object }
        channel_binding:
          type: array
          items: { type: object }
        claims: { type: object }
        evidence:
          type: object
          properties:
            digest: { type: string }
            data: { type: string }

    AciSessionList:
      type: object
      properties:
        api_version: { type: string, example: aci/1 }
        sessions:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/AciSession'
              - type: object
                properties:
                  session_id:
                    type: string
                    pattern: '^[0-9a-f]{64}$'
