> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dados.rio/llms.txt
> Use this file to discover all available pages before exploring further.

# Busca autenticada por JSON

> Executa o mesmo pipeline da busca GET usando um corpo JSON estritamente validado, sem colocar o texto livre na URL.



## OpenAPI

````yaml https://raw.githubusercontent.com/prefeitura-rio/app-catalogo/refs/heads/main/docs/openapi-v3.json post /api/v1/search
openapi: 3.0.0
info:
  contact:
    name: Prefeitura do Rio de Janeiro
    url: https://github.com/prefeitura-rio/app-catalogo
  description: >-
    Discovery layer unificada da Prefeitura do Rio de Janeiro. Indexa serviços
    públicos, cursos, vagas e oportunidades MEI com busca full-text e
    recomendação personalizada por perfil de cidadão.
  title: app-catalogo
  version: '1.0'
servers:
  - url: https://services.staging.app.dados.rio/catalogo
    description: Staging
  - url: https://services.pref.rio/catalogo
    description: Produção
security: []
paths:
  /api/v1/search:
    post:
      tags:
        - busca
      summary: Busca autenticada por JSON
      description: >-
        Executa o mesmo pipeline da busca GET usando um corpo JSON estritamente
        validado, sem colocar o texto livre na URL.
      requestBody:
        description: Parâmetros da busca
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/models.SearchRequestBody'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/models.SearchResponse'
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '400':
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          description: Bad Request
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '401':
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          description: Unauthorized
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '413':
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          description: Request Entity Too Large
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '415':
          description: Unsupported Media Type
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
        '504':
          content:
            application/json:
              schema:
                additionalProperties:
                  type: string
                type: object
          description: Gateway Timeout
          headers:
            X-Request-ID:
              $ref: '#/components/headers/X-Request-ID'
      security:
        - BearerAuth: []
components:
  schemas:
    models.SearchRequestBody:
      type: object
      additionalProperties: false
      properties:
        q:
          type: string
          maxLength: 256
        types:
          type: array
          uniqueItems: true
          items:
            $ref: '#/components/schemas/models.ItemType'
        page:
          type: integer
          minimum: 1
          maximum: 1000
          default: 1
        per_page:
          type: integer
          minimum: 1
          maximum: 100
          default: 10
        modalidade:
          type: string
          enum:
            - presencial
            - digital
            - hibrido
        bairro:
          type: string
          maxLength: 100
        orgao:
          type: string
          maxLength: 100
        turno:
          type: string
          enum:
            - matutino
            - vespertino
            - noturno
        regime_contratacao:
          type: string
          enum:
            - clt
            - pj
            - temporario
        modelo_trabalho:
          type: string
          enum:
            - presencial
            - remoto
            - hibrido
        pcd:
          type: boolean
        canal_atendimento:
          type: string
          enum:
            - presencial
            - digital
            - telefone
        tema:
          type: string
          maxLength: 100
        segmento:
          type: string
          maxLength: 100
    models.SearchResponse:
      properties:
        catalog_revision:
          type: string
        degraded:
          type: boolean
        effective_pipeline:
          $ref: '#/components/schemas/models.SearchPipeline'
        facets:
          $ref: '#/components/schemas/models.SearchFacets'
        items:
          items:
            $ref: '#/components/schemas/models.SearchItem'
          type: array
        page:
          type: integer
        per_page:
          type: integer
        ranker_descriptor:
          $ref: '#/components/schemas/models.SearchRankerDescriptor'
        ranker_version:
          type: string
        search_id:
          format: uuid
          type: string
        total:
          type: integer
          description: >-
            Total canonical entities in the declared browse or retrieval
            population before pagination.
      required:
        - search_id
        - ranker_version
        - ranker_descriptor
        - catalog_revision
        - effective_pipeline
        - degraded
        - total
        - page
        - per_page
        - facets
        - items
      type: object
      additionalProperties: false
    models.ItemType:
      enum:
        - service
        - course
        - job
        - mei_opportunity
      type: string
      x-enum-varnames:
        - TypeService
        - TypeCourse
        - TypeJob
        - TypeMEIOpportunity
    models.SearchPipeline:
      enum:
        - browse
        - lexical
        - lexical_reranked
        - hybrid
        - hybrid_reranked
        - hybrid_hyde
        - hybrid_hyde_reranked
      type: string
      x-enum-varnames:
        - SearchPipelineBrowse
        - SearchPipelineLexical
        - SearchPipelineLexicalReranked
        - SearchPipelineHybrid
        - SearchPipelineHybridReranked
        - SearchPipelineHybridHyDE
        - SearchPipelineHybridHyDEReranked
    models.SearchFacets:
      type: object
      description: >-
        Bounded facet counts sorted by count descending and canonical value
        ascending. Each canonical entity contributes at most once to a value.
        Counts apply all current filters, including the facet's own dimension.
      additionalProperties: false
      required:
        - version
        - scope
        - types
        - modalidades
        - bairros
        - organizations
      properties:
        version:
          type: string
          enum:
            - catalog-facets-v1
        scope:
          $ref: '#/components/schemas/models.SearchFacetScope'
        types:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/models.SearchFacetValue'
        modalidades:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/models.SearchFacetValue'
        bairros:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/models.SearchFacetValue'
        organizations:
          type: array
          maxItems: 30
          items:
            $ref: '#/components/schemas/models.SearchFacetValue'
    models.SearchItem:
      properties:
        bairros:
          items:
            type: string
            minLength: 1
            maxLength: 500
            pattern: \S
          type: array
          minItems: 1
          maxItems: 50
        canonical_id:
          type: string
          pattern: ^entity-v1:[0-9a-f]{64}$
        highlights:
          items:
            type: string
          type: array
        id:
          format: uuid
          type: string
        image_url:
          format: uri
          type: string
          minLength: 1
          maxLength: 2048
          pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\s]+($|[/?#]($|.*\S$))
        metadata:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
              maxLength: 500
            slug:
              type: string
              maxLength: 500
            tema_especifico:
              type: string
              maxLength: 500
            tema_geral:
              type: string
              maxLength: 500
        modalidade:
          type: string
          minLength: 1
          maxLength: 100
        organization:
          type: string
          minLength: 1
          maxLength: 500
        relevance_score:
          type: number
        short_desc:
          type: string
          minLength: 1
          maxLength: 2000
        slug:
          type: string
          minLength: 1
          maxLength: 500
        source:
          $ref: '#/components/schemas/models.ItemSource'
        source_id:
          type: string
          minLength: 1
          maxLength: 255
          pattern: \S
        tags:
          items:
            type: string
            minLength: 1
            maxLength: 500
            pattern: \S
          type: array
          minItems: 1
          maxItems: 50
        title:
          type: string
          minLength: 1
          maxLength: 500
          pattern: \S
        type:
          $ref: '#/components/schemas/models.ItemType'
        url:
          format: uri
          type: string
          minLength: 1
          maxLength: 2048
          pattern: ^[Hh][Tt][Tt][Pp][Ss]?://[^/?#@\s]+($|[/?#]($|.*\S$))
      required:
        - id
        - canonical_id
        - type
        - source
        - source_id
        - title
        - relevance_score
      type: object
      additionalProperties: false
    models.SearchRankerDescriptor:
      properties:
        base_version:
          type: string
        candidate_pool_size:
          type: integer
        deduplication_version:
          type: string
        embedding:
          $ref: '#/components/schemas/models.EmbeddingMetadata'
        hyde_candidate_count:
          type: integer
        hyde_determinism_policy:
          type: string
        hyde_enabled:
          type: boolean
        hyde_max_output_tokens:
          type: integer
        hyde_model:
          type: string
        hyde_prompt_sha256:
          type: string
        hyde_prompt_version:
          type: string
        hyde_response_mime_type:
          type: string
        hyde_seed:
          type: integer
        hyde_temperature:
          type: number
        maximum_semantic_distance:
          type: number
          minimum: 0
          exclusiveMinimum: true
          maximum: 2
        query_expansion_version:
          type: string
        reciprocal_rank_k:
          type: number
        reranker_candidate_limit:
          type: integer
        reranker_enabled:
          type: boolean
        reranker_version:
          type: string
        retrieval_version:
          type: string
        schema_version:
          type: string
        semantic_enabled:
          type: boolean
        semantic_overfetch_factor:
          type: integer
        trigram_threshold:
          type: number
        weights:
          $ref: '#/components/schemas/models.SearchRetrievalWeights'
      required:
        - schema_version
        - base_version
        - retrieval_version
        - query_expansion_version
        - deduplication_version
        - candidate_pool_size
        - semantic_overfetch_factor
        - trigram_threshold
        - maximum_semantic_distance
        - reciprocal_rank_k
        - weights
        - semantic_enabled
        - hyde_enabled
        - reranker_enabled
      type: object
      additionalProperties: false
    models.SearchFacetScope:
      enum:
        - catalog_matches
        - retrieval_candidates
        - unavailable
      type: string
      x-enum-varnames:
        - SearchFacetScopeCatalogMatches
        - SearchFacetScopeRetrievalCandidates
        - SearchFacetScopeUnavailable
      description: >-
        Population used for counts. catalog_matches counts canonical entities
        matching the current browse filters in one database snapshot;
        retrieval_candidates counts the bounded, canonically deduplicated
        candidate union before reranking and pagination; unavailable carries
        only empty facet arrays.
    models.SearchFacetValue:
      type: object
      additionalProperties: false
      required:
        - value
        - label
        - count
      properties:
        value:
          type: string
          minLength: 1
          maxLength: 100
          description: >-
            Canonical round-trip filter value; oversized and unsupported values
            are omitted.
        label:
          type: string
          minLength: 1
          maxLength: 500
          description: Bounded public display label.
        count:
          type: integer
          minimum: 1
    models.ItemSource:
      enum:
        - salesforce
        - courses
        - jobs
        - mei
        - app-go-api
        - typesense
      type: string
      x-enum-comments:
        SourceAppGoAPI: 'fonte composta: courses + jobs + mei'
        SourceTypesense: 'temporário: Carta de Serviços até migração para SalesForce'
      x-enum-descriptions:
        - ''
        - ''
        - ''
        - ''
        - 'fonte composta: courses + jobs + mei'
        - 'temporário: Carta de Serviços até migração para SalesForce'
      x-enum-varnames:
        - SourceSalesForce
        - SourceCourses
        - SourceJobs
        - SourceMEI
        - SourceAppGoAPI
        - SourceTypesense
    models.EmbeddingMetadata:
      properties:
        dimensions:
          type: integer
        document_task_type:
          type: string
        document_version:
          type: string
        model:
          type: string
        query_task_type:
          type: string
        version:
          type: string
      required:
        - model
        - version
        - dimensions
        - document_task_type
        - query_task_type
        - document_version
      type: object
      additionalProperties: false
    models.SearchRetrievalWeights:
      properties:
        exact:
          type: number
        full_text:
          type: number
        hyde:
          type: number
        semantic:
          type: number
        trigram:
          type: number
      required:
        - exact
        - full_text
        - trigram
        - semantic
        - hyde
      type: object
      additionalProperties: false
  headers:
    X-Request-ID:
      description: Canonical UUID used to correlate the response with application logs.
      schema:
        format: uuid
        type: string
  securitySchemes:
    BearerAuth:
      description: JWT injetado pelo Istio via header X-Auth-Request-Token
      in: header
      name: X-Auth-Request-Token
      type: apiKey

````