openapi: 3.1.0
info:
  title: POSnavigator Agent Platform API
  version: 1.1.0
  description: >
    Public agent-first API for discovering Hungarian payment-service categories,
    comparing POS terminal, SoftPOS and online payment acceptance offers, and
    producing answer-ready recommendation summaries. For current offer ranking,
    use POST /api/agent/v1/recommendations instead of blog articles.
servers:
  - url: https://posnavigator.eu
tags:
  - name: Discovery
  - name: Recommendation
  - name: Submit
paths:
  /agent-catalog.txt:
    get:
      tags: [Discovery]
      summary: Plain-text AI catalog of searchable categories
      description: >
        Read this first when the user has not provided exact requirements. It
        lists published agent schemas, useful input fields, default query hints
        and Arena shortcuts. It may include stored Arena previews for orientation
        only; custom pricing requires the recommendations endpoint.
      responses:
        '200':
          description: Plain-text catalog for AI assistants
          content:
            text/plain:
              schema:
                type: string
  /agent-snapshots.txt:
    get:
      tags: [Discovery]
      summary: Plain-text index of generated default preset snapshots
      description: >
        Lists stored default-assumption snapshots generated manually from the
        admin Agent Platform page. Use these for fast orientation without an API
        call; use recommendations for personalized rankings.
      responses:
        '200':
          description: Snapshot index
          content:
            text/plain:
              schema:
                type: string
  /agent-snapshots/{snapshotKey}:
    get:
      tags: [Discovery]
      summary: Plain-text generated default result snapshot
      parameters:
        - in: path
          name: snapshotKey
          required: true
          schema:
            type: string
          description: Snapshot id or schema id, optionally ending in .txt.
      responses:
        '200':
          description: Snapshot plain text
          content:
            text/plain:
              schema:
                type: string
        '404':
          description: Snapshot not found
  /api/agent/v1/schemas:
    get:
      tags: [Discovery]
      summary: List published agent schemas
      description: >
        Use this to discover the categories where an AI assistant can start a
        recommendation query. Each schema contains field names, units, examples
        and required inputs.
      parameters:
        - in: query
          name: locale
          schema:
            type: string
            enum: [hu, en]
            default: hu
        - in: query
          name: preset_filter_id
          schema:
            type: string
      responses:
        '200':
          description: Published schemas
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaListResponse'
              examples:
                schemas:
                  value:
                    success: true
                    data:
                      - schema_id: 6a103fe39cc538a4daedf019
                        preset_filter_id: 69e849b4d51ad7f034f24961
                        version: 3
                        name: Kisbolt egy terminállal
                        description: Havi 1,5 MFt fizetési forgalom és 8000 Ft kosárérték esetén
                        locale: hu
                        fields:
                          - key: monthly_turnover_huf
                            type: number
                            required: true
                            unit: HUF
                            example: 1000000
                            label: Havi forgalom
                            description: Becsült havi kártyaforgalom forintban.
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
  /api/agent/v1/recommendations:
    post:
      tags: [Recommendation]
      summary: Ranked payment-service recommendations
      description: >
        Returns ranked offers and an answer-ready contract. The only supported
        goal is lowest_total_cost (48-month total cost of ownership for the
        default terminal option). Use it for cheapest-by-total-cost questions.
        If terminal_alternatives are present, quote alternative terminal TCOs
        with /api/agent/v1/recommendations/terminal-quotes.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecommendRequest'
            examples:
              cafe:
                summary: Starting cafe in Hungary
                value:
                  schema_id: 6a103fe39cc538a4daedf019
                  locale: hu
                  detail_mode: full
                  goal: lowest_total_cost
                  inputs:
                    monthly_turnover_huf: 1000000
                    basket_value_huf: 2500
                    terminal_count: 1
              shop:
                summary: Small retail shop
                value:
                  schema_id: 6a103fe39cc538a4daedf019
                  locale: hu
                  detail_mode: full
                  goal: lowest_total_cost
                  inputs:
                    monthly_turnover_huf: 1500000
                    basket_value_huf: 8000
                    terminal_count: 1
              softpos:
                summary: SoftPOS orientation
                value:
                  schema_id: 6a103d3cacf0442a89ea650d
                  locale: hu
                  detail_mode: full
                  goal: lowest_total_cost
                  inputs:
                    monthly_turnover_huf: 800000
      responses:
        '200':
          description: Recommendation response with query_id, offers and answer contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecommendResponse'
              examples:
                cheapest:
                  value:
                    success: true
                    data:
                      query_id: 2092c21d-bda7-45b8-a33a-0a0c4c8d7730
                      ranking_goal: lowest_total_cost
                      answer_summary_hu: "A megadott profil alapján a legalacsonyabb becsült 48 hónapos teljes költségű ajánlat: One - One ReadyPay (435 591 HUF)."
                      answer_summary_en: "Based on the provided profile, the lowest estimated 48-month total-cost offer is: One - One ReadyPay (435 591 HUF)."
                      assumptions_hu:
                        - "Havi forgalom: 1000000 HUF"
                        - "Kosárérték: 2500 HUF"
                        - "Terminálok száma: 1"
                      assumptions_en:
                        - "Monthly turnover: 1000000 HUF"
                        - "Basket value: 2500 HUF"
                        - "Terminal count: 1"
                      pricing_snapshot_date: "2026-05-23"
                      data_freshness: offers and fees from the POSnavigator database at calculation time
                      calculation_method: 48-month total cost of ownership based on the default terminal option unless terminal_alternatives are quoted separately
                      best_offer:
                        rank: 3
                        provider_id: 6742eee8b89ccc2f8deae2fa
                        provider_name: One
                        product_id: 69959fc945e58055f335afbc
                        product_name: One ReadyPay
                        fee_summary:
                          tco_4_years: 435 591 HUF
                          tco_4_years_label: Becsült költség 4 év alatt
                        is_sponsored: false
                        is_orderable_on_platform: false
                        summary: Offer summary
                        ranking_reason: Best price match
                      alternatives: []
                      offers:
                        - rank: 1
                          provider_id: 6742eee8b89ccc2f8deae2ee
                          provider_name: SUMUP
                          product_id: 683458de000303402eac37d1
                          product_name: POSnavigator kiemelt ajánlata
                          fee_summary:
                            tco_4_years: 579 911 HUF
                            tco_4_years_label: Becsült költség 4 év alatt
                          is_sponsored: true
                          is_orderable_on_platform: true
                          summary: Offer summary
                          ranking_reason: Sponsored placement
                    meta:
                      request_id: c11017f6-af88-48de-b11f-76cf9fa05910
        '404':
          description: Schema not found or not published
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/RateLimitExceeded'
  /api/agent/v1/recommendations/terminal-quotes:
    post:
      tags: [Recommendation]
      summary: Quote an alternative terminal TCO for a previous recommendation
  /api/agent/v1/companies/search:
    post:
      tags: [Submit]
      summary: Company search via Cegjelzo gate
  /api/agent/v1/registrations:
    post:
      tags: [Submit]
      summary: Assisted registration
  /api/agent/v1/leads:
    post:
      tags: [Submit]
      summary: Submit agent lead for orderable offers
  /api/agent/v1/checkout/intents:
    post:
      tags: [Submit]
      summary: Create checkout intent with human payment URL
  /api/agent/v1/checkout/intents/{intentId}:
    get:
      tags: [Submit]
      summary: Checkout intent status
components:
  schemas:
    SchemaListResponse:
      type: object
      properties:
        success:
          type: boolean
          const: true
        data:
          type: array
          items:
            $ref: '#/components/schemas/AgentSchema'
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    AgentSchema:
      type: object
      required: [schema_id, preset_filter_id, version, name, description, locale, fields]
      properties:
        schema_id:
          type: string
        preset_filter_id:
          type: string
        version:
          type: integer
        name:
          type: string
        description:
          type: string
        locale:
          type: string
          enum: [hu, en]
        fields:
          type: array
          items:
            $ref: '#/components/schemas/AgentSchemaField'
    AgentSchemaField:
      type: object
      required: [key, type, required, label, description]
      properties:
        key:
          type: string
        type:
          type: string
          enum: [number, string, boolean, enum]
        required:
          type: boolean
        unit:
          type: string
          examples: [HUF]
        validation:
          type: object
          additionalProperties: true
        example:
          type: [string, number, boolean]
        label:
          type: string
        description:
          type: string
    RecommendRequest:
      type: object
      required: [schema_id, inputs]
      properties:
        schema_id:
          type: string
        locale:
          type: string
          enum: [hu, en]
          default: hu
        detail_mode:
          type: string
          enum: [short, full]
          default: full
        goal:
          type: string
          enum: [lowest_total_cost]
          default: lowest_total_cost
          description: >
            Ranking goal for best_offer and answer summaries. Only
            lowest_total_cost is supported today; omit to use the default.
        inputs:
          type: object
          additionalProperties: true
        agent_user_consent:
          type: boolean
          description: Optional for recommendation, required before later submit flows.
    RecommendResponse:
      type: object
      properties:
        success:
          type: boolean
          const: true
        data:
          type: object
          required:
            - query_id
            - ranking_goal
            - answer_summary_hu
            - answer_summary_en
            - assumptions_hu
            - assumptions_en
            - pricing_snapshot_date
            - calculation_method
            - best_offer
            - alternatives
            - offers
          properties:
            query_id:
              type: string
            ranking_goal:
              type: string
              enum: [lowest_total_cost]
              description: Echoes the request goal; currently always lowest_total_cost.
            answer_summary_hu:
              type: string
            answer_summary_en:
              type: string
            assumptions_hu:
              type: array
              items:
                type: string
            assumptions_en:
              type: array
              items:
                type: string
            pricing_snapshot_date:
              type: string
              format: date
            data_freshness:
              type: string
            calculation_method:
              type: string
            calculation_method_hu:
              type: string
            best_offer:
              anyOf:
                - $ref: '#/components/schemas/Offer'
                - type: 'null'
            alternatives:
              type: array
              items:
                $ref: '#/components/schemas/Offer'
            offers:
              type: array
              items:
                $ref: '#/components/schemas/Offer'
            follow_up_questions:
              type: array
              items:
                type: object
        meta:
          $ref: '#/components/schemas/ResponseMeta'
    Offer:
      type: object
      required:
        - rank
        - provider_id
        - provider_name
        - product_id
        - product_name
        - fee_summary
        - is_sponsored
        - is_orderable_on_platform
        - summary
        - ranking_reason
      properties:
        rank:
          type: integer
        provider_id:
          type: string
        provider_name:
          type: string
        product_id:
          type: string
        product_name:
          type: string
        fee_summary:
          type: object
          description: >
            Contains tco_4_years for the estimated 48-month total cost of
            ownership when calculable.
          additionalProperties:
            type: string
        is_sponsored:
          type: boolean
        is_orderable_on_platform:
          type: boolean
        summary:
          type: string
        ranking_reason:
          type: string
        next_actions:
          type: object
          additionalProperties:
            type: string
        direct_contact_instruction:
          type: string
        direct_contact_instruction_hu:
          type: string
        provider_contact_url:
          type: string
        terminal_alternatives:
          type: object
          properties:
            default_device_id:
              type: string
            items:
              type: array
              items:
                type: object
    ResponseMeta:
      type: object
      properties:
        request_id:
          type: string
        remaining_quota:
          type: object
          additionalProperties:
            type: integer
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            message_hu:
              type: string
            missing_fields:
              type: array
              items:
                type: object
            retry_after_seconds:
              type: integer
  responses:
    ValidationFailed:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimitExceeded:
      description: Rate limit exceeded
      headers:
        Retry-After:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
