openapi: 3.1.0
info:
  title: Oui Chef Agentic API Gateway
  version: 1.0.0
  description: A structured utility that strips ads/fluff from cooking URLs and returns voice-optimized, cleanly structured recipe steps.
servers:
  - url: https://ouichef.einansatz.com
paths:
  /api/v1/agent/parse:
    post:
      operationId: parseRecipeForAgent
      summary: Parse a cooking URL into structured agent-ready recipe data.
      description: Extracts recipe evidence from the URL, counts prompt tokens with the Google GenAI SDK before each LLM call, reserves estimated raw provider cost plus 50% markup against prepaid API balance, and settles actual usage after generation and any repair pass.
      security:
        - AgentApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - url
              properties:
                url:
                  type: string
                  format: uri
                  maxLength: 2048
                  description: Public http(s) cooking or recipe URL to parse.
      responses:
        "200":
          description: Cleanly structured recipe data optimized for Text-to-Speech engines.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentRecipe"
        "400":
          $ref: "#/components/responses/AgentError"
        "401":
          $ref: "#/components/responses/AgentError"
        "402":
          description: Prepaid API balance is exhausted or insufficient for the required reservation.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentErrorEnvelope"
        "403":
          $ref: "#/components/responses/AgentError"
        "413":
          $ref: "#/components/responses/AgentError"
        "415":
          $ref: "#/components/responses/AgentError"
        "422":
          $ref: "#/components/responses/AgentError"
        "500":
          $ref: "#/components/responses/AgentError"
        "502":
          $ref: "#/components/responses/AgentError"
        "503":
          description: Provider is unavailable or token counting failed before reservation.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentErrorEnvelope"
  /api/v1/agent/policy:
    get:
      operationId: getAgentPolicy
      summary: Read machine pricing and access policy.
      responses:
        "200":
          description: Agent-readable pricing and access policy.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentPolicy"
        "405":
          $ref: "#/components/responses/AgentError"
  /api/v1/agent/register:
    post:
      operationId: registerAgentDeveloper
      summary: Register an agent developer and initialize human Stripe authorization.
      description: Creates a Stripe Checkout Session with the provided email prefilled, stores a pending hashed API key, and returns the checkout URL plus pending key for the agent to show to its human user. The paid amount becomes prepaid API balance after webhook activation.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - email
              properties:
                email:
                  type: string
                  format: email
                amountCents:
                  type: integer
                  default: 500
                  minimum: 100
                  description: Prepaid API balance amount in cents. Minimum is 100 cents; there is no app-defined maximum beyond Stripe's payment limits.
      responses:
        "201":
          description: Pending API key and Checkout URL.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentRegistration"
        "400":
          $ref: "#/components/responses/AgentError"
        "415":
          $ref: "#/components/responses/AgentError"
        "500":
          $ref: "#/components/responses/AgentError"
  /api/v1/agent/top-up:
    post:
      operationId: topUpAgentBalance
      summary: Create a Stripe Checkout Session to add prepaid API balance.
      security:
        - AgentApiKey: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                amountCents:
                  type: integer
                  default: 500
                  minimum: 100
                  description: Prepaid API balance amount in cents. Minimum is 100 cents; there is no app-defined maximum beyond Stripe's payment limits.
      responses:
        "201":
          description: Pending balance top-up Checkout URL.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentTopUp"
        "400":
          $ref: "#/components/responses/AgentError"
        "401":
          $ref: "#/components/responses/AgentError"
        "403":
          $ref: "#/components/responses/AgentError"
        "415":
          $ref: "#/components/responses/AgentError"
        "500":
          $ref: "#/components/responses/AgentError"
  /api/v1/agent/stripeWebhook:
    post:
      operationId: activateAgentApiKeyFromStripeWebhook
      summary: Activate a pending agent API key after Stripe Checkout completion.
      description: Stripe webhook endpoint for checkout.session.completed events. This endpoint verifies the Stripe signature, finds the pending /api_keys document by stripe_session_id, and marks the key active.
      responses:
        "200":
          description: Webhook received.
        "400":
          description: Invalid webhook signature or payload.
        "405":
          description: Method not allowed.
        "500":
          description: Activation failed.
components:
  securitySchemes:
    AgentApiKey:
      type: http
      scheme: bearer
      bearerFormat: sk_ouichef_<secret>
      description: Dedicated M2M API key activated through /api/v1/agent/register and Stripe Checkout.
  responses:
    AgentError:
      description: Semantic agent-readable error.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AgentErrorEnvelope"
  schemas:
    AgentIngredient:
      type: object
      additionalProperties: false
      required:
        - name
        - quantity
        - unit
        - notes
      properties:
        name:
          type: string
        quantity:
          type:
            - number
            - "null"
        unit:
          type:
            - string
            - "null"
        notes:
          type:
            - string
            - "null"
    AgentRecipe:
      type: object
      additionalProperties: false
      required:
        - title
        - sourceUrl
        - servings
        - prepTime
        - cookTime
        - ingredients
        - instructions
      properties:
        title:
          type: string
        sourceUrl:
          type:
            - string
            - "null"
        servings:
          type:
            - number
            - "null"
        prepTime:
          type:
            - string
            - "null"
        cookTime:
          type:
            - string
            - "null"
        ingredients:
          type: array
          items:
            $ref: "#/components/schemas/AgentIngredient"
        instructions:
          type: array
          items:
            type: string
    AgentPolicy:
      type: object
      required:
        - service
        - version
        - utility
        - authentication
        - billing
        - reservation
      properties:
        service:
          type: string
        version:
          type: string
        utility:
          type: string
        authentication:
          type: object
        billing:
          type: object
          required:
            - model
            - currency
            - markupPercent
            - topUp
          properties:
            model:
              type: string
              enum:
                - prepaid_balance
            currency:
              type: string
              enum:
                - USD
            markupPercent:
              type: integer
              enum:
                - 50
            topUp:
              type: object
              properties:
                defaultAmountCents:
                  type: integer
                minAmountCents:
                  type: integer
                maxAmountCents:
                  type:
                    - integer
                    - "null"
                  description: Null means Oui Chef does not impose an app-level maximum.
        reservation:
          type: object
          required:
            - estimate
            - failureCodes
            - missingUsageMetadata
            - settlement
          properties:
            estimate:
              type: string
              description: Describes pre-call reservation using provider token counting, configured max output tokens, raw provider cost, and 50% markup.
            failureCodes:
              type: array
              items:
                type: string
                enum:
                  - insufficient_balance
                  - balance_exhausted
            missingUsageMetadata:
              type: string
              enum:
                - charge_reserved_estimate
            settlement:
              type: string
              description: Describes release of reservation and actual usage settlement.
    AgentRegistration:
      type: object
      additionalProperties: false
      required:
        - status
        - message
        - amountCents
        - checkout_url
        - pending_key
      properties:
        amountCents:
          type: integer
        status:
          type: string
          enum:
            - pending
        message:
          type: string
        checkout_url:
          type: string
          format: uri
        pending_key:
          type: string
          description: Pending API key. It is rejected by /api/v1/agent/parse until Stripe Checkout completes.
    AgentTopUp:
      type: object
      additionalProperties: false
      required:
        - status
        - message
        - amountCents
        - checkout_url
      properties:
        amountCents:
          type: integer
        status:
          type: string
          enum:
            - pending
        message:
          type: string
        checkout_url:
          type: string
          format: uri
    AgentErrorEnvelope:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - retryable
          properties:
            code:
              type: string
              description: Semantic machine-readable error code, including insufficient_balance, balance_exhausted, and token_count_failed.
            details:
              type: object
              additionalProperties: true
            message:
              type: string
            retryable:
              type: boolean
