{
  "openapi": "3.1.0",
  "info": {
    "title": "MarioCar Seminovos — API pública da vitrine",
    "version": "1.0.0",
    "summary": "Estoque de carros seminovos da MarioCar (Recife/PE), em JSON, sem autenticação.",
    "description": "API somente-leitura do estoque público da MarioCar Seminovos. Nenhum endpoint exige chave ou login: é o mesmo dado que qualquer pessoa vê no site.\n\nO estoque muda toda semana — consulte na hora, não guarde cópia. Não há limite de taxa publicado; use com parcimônia (um pedido por vez, sem paralelismo agressivo).\n\nAs páginas da vitrine também respondem em Markdown quando o pedido traz `Accept: text/markdown`, na mesma URL da página. Útil pra agente que prefere texto a JSON.\n\n**Erros.** Toda resposta de erro tem o mesmo formato: `{ \"error\": \"mensagem\" }`, com `message` a mais no 401. 400 = faltou parâmetro. 404 = não existe ou saiu do estoque. 401 = o caminho não é público (a API pública não pede credencial nenhuma).",
    "contact": {
      "name": "MarioCar Seminovos",
      "url": "https://www.mariocaroficial.com/vitrine/sobre",
      "email": "contato@mariocarautos.com"
    },
    "license": {
      "name": "Uso livre para consulta e recomendação do estoque"
    }
  },
  "servers": [
    {
      "url": "https://www.mariocaroficial.com",
      "description": "Produção"
    }
  ],
  "tags": [
    {
      "name": "Estoque",
      "description": "Veículos disponíveis para venda"
    },
    {
      "name": "Veículo",
      "description": "Detalhe de um veículo"
    },
    {
      "name": "Loja",
      "description": "Dados da loja"
    }
  ],
  "paths": {
    "/api/garage/vitrine": {
      "get": {
        "tags": [
          "Estoque"
        ],
        "operationId": "listarEstoque",
        "summary": "Lista os veículos disponíveis",
        "description": "Devolve todos os veículos publicados na vitrine. Sem parâmetros, traz o estoque inteiro.",
        "parameters": [
          {
            "name": "marca",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Toyota",
            "description": "Filtra por marca."
          },
          {
            "name": "modelo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "COROLLA",
            "description": "Filtra por modelo."
          },
          {
            "name": "placa",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "TDA8D31",
            "description": "Busca um veículo específico pela placa."
          },
          {
            "name": "slug",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Busca pelo slug usado na URL da página do veículo."
          }
        ],
        "responses": {
          "200": {
            "description": "Estoque atual",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "veiculos": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Veiculo"
                      }
                    },
                    "filtros": {
                      "type": "object",
                      "description": "Valores distintos disponíveis para filtrar (marcas, anos, faixas)."
                    },
                    "total": {
                      "type": "integer",
                      "example": 19
                    }
                  },
                  "required": [
                    "veiculos",
                    "total"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NaoEncontrado"
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/vitrine/similares": {
      "get": {
        "tags": [
          "Veículo"
        ],
        "operationId": "listarSimilares",
        "summary": "Veículos parecidos com um dado veículo",
        "description": "Usa marca, faixa de preço, categoria e ano para ranquear. Se não houver bons candidatos, completa com os mais recentes.",
        "parameters": [
          {
            "name": "placa",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "TDA8D31"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 3
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lista de similares",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "similares": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Veiculo"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ParametroFaltando"
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/garage/ficha-tecnica": {
      "get": {
        "tags": [
          "Veículo"
        ],
        "operationId": "obterFichaTecnica",
        "summary": "Ficha técnica do modelo",
        "description": "Informe `id` do veículo, ou a combinação `marca` + `modelo` + `ano`.",
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "v1788006699086"
          },
          {
            "name": "marca",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "Toyota"
          },
          {
            "name": "modelo",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "YARIS"
          },
          {
            "name": "ano",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "2023"
          }
        ],
        "responses": {
          "200": {
            "description": "Ficha técnica",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ficha": {
                      "type": "object",
                      "description": "Campos variam por modelo. Exemplos: tipo_motor, cilindradas, combustivel, torque, direcao, tracao, transmissao, vel_maxima.",
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ParametroFaltando"
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/garage/360": {
      "get": {
        "tags": [
          "Veículo"
        ],
        "operationId": "obter360",
        "summary": "Fotos em 360° do veículo, quando existirem",
        "parameters": [
          {
            "name": "veiculo_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "v1788006699086"
          }
        ],
        "responses": {
          "200": {
            "description": "Disponibilidade e imagens do 360",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "has360": {
                      "type": "boolean",
                      "example": false
                    },
                    "imagens": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "has360"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ParametroFaltando"
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/reviews/google": {
      "get": {
        "tags": [
          "Loja"
        ],
        "operationId": "obterAvaliacoes",
        "summary": "Avaliações da loja no Google",
        "responses": {
          "200": {
            "description": "Nota média, total e avaliações recentes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "rating": {
                      "type": "number",
                      "example": 4.9
                    },
                    "total": {
                      "type": "integer"
                    },
                    "reviews": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    },
                    "source": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": [
          "Loja"
        ],
        "operationId": "obterSaude",
        "summary": "O site está de pé?",
        "description": "Sem autenticação, devolve só o estado geral. O detalhe por serviço existe, mas é restrito a quem tem sessão na loja.",
        "responses": {
          "200": {
            "description": "Estado geral",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "healthy",
                        "degraded",
                        "critical"
                      ]
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "status",
                    "timestamp"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/api/version": {
      "get": {
        "tags": [
          "Loja"
        ],
        "operationId": "obterVersao",
        "summary": "Identificador da versão publicada do site",
        "responses": {
          "200": {
            "description": "Versão",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "v": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NaoAutorizado"
          }
        }
      }
    },
    "/vitrine/estoque": {
      "get": {
        "tags": [
          "Estoque"
        ],
        "operationId": "estoqueEmMarkdown",
        "summary": "Estoque em Markdown (negociação de conteúdo)",
        "description": "A MESMA URL da página devolve Markdown quando o cabeçalho `Accept` pede `text/markdown`. Sem esse cabeçalho, devolve o HTML normal da página. Vale para qualquer caminho abaixo de /vitrine, inclusive a página de cada carro.",
        "parameters": [
          {
            "name": "Accept",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "text/markdown"
              ]
            },
            "example": "text/markdown"
          }
        ],
        "responses": {
          "200": {
            "description": "Tabela do estoque em Markdown",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "Caminho que não corresponde a nenhum veículo"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Veiculo": {
        "type": "object",
        "description": "Veículo publicado na vitrine. Nenhum campo de custo, margem, fornecedor ou dado pessoal é exposto.",
        "properties": {
          "id": {
            "type": "string",
            "example": "v1788006699086"
          },
          "placa": {
            "type": "string",
            "example": "TDA8D31"
          },
          "slug": {
            "type": "string",
            "description": "Caminho da página do veículo: /vitrine/{slug}"
          },
          "marca": {
            "type": "string",
            "example": "Vw"
          },
          "modelo": {
            "type": "string",
            "example": "SAVEIRO"
          },
          "versao": {
            "type": "string"
          },
          "ano_fabricacao": {
            "type": "integer",
            "example": 2024
          },
          "ano_modelo": {
            "type": "integer",
            "example": 2025
          },
          "cor": {
            "type": "string"
          },
          "combustivel": {
            "type": "string"
          },
          "cambio": {
            "type": "string"
          },
          "km": {
            "type": "integer",
            "example": 47688
          },
          "preco": {
            "type": "integer",
            "description": "Preço de venda em reais, sem centavos."
          },
          "preco_venda": {
            "type": "integer"
          },
          "fipe_valor": {
            "type": [
              "integer",
              "null"
            ]
          },
          "promocao": {
            "type": "integer",
            "description": "1 quando o veículo está em promoção."
          },
          "promocao_preco_de": {
            "type": [
              "integer",
              "null"
            ]
          },
          "promocao_ate": {
            "type": [
              "string",
              "null"
            ]
          },
          "reservado": {
            "type": "integer"
          },
          "unico_dono": {
            "type": "integer"
          },
          "garantia_fabrica": {
            "type": "integer"
          },
          "revisado_autorizada": {
            "type": "integer"
          },
          "laudo_cautelar": {
            "type": [
              "string",
              "null"
            ]
          },
          "opcionais": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "foto_destaque": {
            "type": [
              "string",
              "null"
            ],
            "description": "Caminho relativo. Prefixe com https://www.mariocaroficial.com/api para baixar."
          },
          "fotos_preview": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "total_fotos": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "example": "anuncios"
          }
        },
        "required": [
          "id",
          "placa",
          "marca",
          "modelo",
          "preco_venda"
        ]
      },
      "Erro": {
        "type": "object",
        "description": "Formato único de erro da API. `error` é a mensagem legível; `message` só aparece em 401.",
        "properties": {
          "error": {
            "type": "string",
            "example": "placa requerida"
          },
          "message": {
            "type": "string",
            "example": "Authentication required"
          }
        },
        "required": [
          "error"
        ]
      }
    },
    "responses": {
      "ParametroFaltando": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            },
            "example": {
              "error": "placa requerida"
            }
          }
        },
        "description": "Parâmetro obrigatório ausente ou inválido."
      },
      "NaoEncontrado": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            },
            "example": {
              "error": "Veículo não encontrado"
            }
          }
        },
        "description": "Recurso não existe, ou o veículo saiu do estoque."
      },
      "NaoAutorizado": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            },
            "example": {
              "error": "Unauthorized",
              "message": "Authentication required"
            }
          }
        },
        "description": "Caminho de API que não é público. A API pública não exige credencial; se veio 401, o caminho está errado."
      }
    }
  },
  "externalDocs": {
    "description": "Documentação em português, com exemplos prontos",
    "url": "https://www.mariocaroficial.com/docs"
  }
}