{"openapi":"3.1.0","info":{"title":"SINAPI Vivo · API","version":"1.0.0","description":"API de leitura da referência oficial de custos da construção (SINAPI/CAIXA): insumos, composições, árvore analítica e estatísticas. Toda resposta carrega a versão do dado (campo `versao` e header `X-SINAPI-Versao`). Proposta da Levver para a CAIXA (CPSI 0071/2026).","contact":{"name":"Levver","url":"https://levver.ai"}},"servers":[{"url":"https://sinapi.levver.ai/api/v1","description":"Demonstração (perfil proto)"}],"security":[{},{"ApiKeyAuth":[]}],"tags":[{"name":"Catálogo","description":"Insumos e composições do SINAPI"},{"name":"Análise","description":"Cobertura e qualidade do dado"},{"name":"Conferência","description":"Malha fina: confere orçamento contra a referência"},{"name":"Meta","description":"Versão da base"}],"paths":{"/versao":{"get":{"tags":["Meta"],"summary":"Versão vigente da base","operationId":"getVersao","description":"Ponto de partida da integração: além da praça servida, devolve em `disponiveis` TODAS as praças e regimes que a base tem. É essa lista que alimenta o `uf` das outras rotas, e por isso ela não é congelada no contrato.","parameters":[{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}}],"responses":{"200":{"description":"Praça servida e a lista completa das disponíveis","content":{"application/json":{"schema":{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"disponiveis":{"type":"array","items":{"$ref":"#/components/schemas/VersaoDisponivel"}}}}}}}}}},"/insumos":{"get":{"tags":["Catálogo"],"summary":"Lista insumos","operationId":"listInsumos","parameters":[{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}},{"name":"q","in":"query","description":"Busca por descrição ou código","schema":{"type":"string"}},{"name":"classificacao","in":"query","description":"Filtra por classificação","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"size","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Página de insumos","content":{"application/json":{"schema":{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"total":{"type":"integer","example":4876},"page":{"type":"integer","example":1},"size":{"type":"integer","example":25},"items":{"type":"array","items":{"$ref":"#/components/schemas/Insumo"}}}}}}}}}},"/insumos/{codigo}":{"get":{"tags":["Catálogo"],"summary":"Detalhe de um insumo","operationId":"getInsumo","parameters":[{"name":"codigo","in":"path","required":true,"schema":{"type":"integer"},"example":88309},{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}}],"responses":{"200":{"description":"Insumo","content":{"application/json":{"schema":{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"insumo":{"$ref":"#/components/schemas/Insumo"}}}}}},"404":{"description":"Não encontrado nesta base","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/composicoes":{"get":{"tags":["Catálogo"],"summary":"Lista composições","operationId":"listComposicoes","parameters":[{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}},{"name":"q","in":"query","description":"Busca por descrição ou código","schema":{"type":"string"}},{"name":"grupo","in":"query","description":"Filtra por grupo","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"size","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Página de composições","content":{"application/json":{"schema":{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"total":{"type":"integer","example":4876},"page":{"type":"integer","example":1},"size":{"type":"integer","example":25},"items":{"type":"array","items":{"$ref":"#/components/schemas/Composicao"}}}}}}}}}},"/composicoes/{codigo}":{"get":{"tags":["Catálogo"],"summary":"Detalhe de uma composição, com a árvore analítica","operationId":"getComposicao","parameters":[{"name":"codigo","in":"path","required":true,"schema":{"type":"integer"},"example":104658},{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}}],"responses":{"200":{"description":"Composição com árvore","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Composicao"},{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"arvore":{"type":"array","items":{"$ref":"#/components/schemas/ItemArvore"}}}}]}}}},"404":{"description":"Não encontrada nesta base","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}},"/estatisticas":{"get":{"tags":["Análise"],"summary":"Cobertura e qualidade do catálogo","operationId":"getEstatisticas","parameters":[{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}}],"responses":{"200":{"description":"Agregados de cobertura e qualidade","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/conferencia":{"post":{"tags":["Conferência"],"summary":"Confere um orçamento em lote contra a referência do SINAPI","description":"Malha fina como serviço: envie um orçamento (array `itens` de {codigo, quantidade, custo}, ou `texto` com linhas `codigo;quantidade;custo`) e receba cada item conferido contra a referência, com o risco e a exposição de glosa por item e no agregado. Até 1000 itens por lote.","operationId":"conferirLote","parameters":[{"name":"uf","in":"query","description":"Sigla da praça (ex.: AC, SP). Ausente, responde na praça default. Sigla que não existe na base também cai na default, e a resposta diz qual foi usada no campo `versao` e no header X-SINAPI-Versao.","schema":{"type":"string","example":"AC"}},{"name":"regime","in":"query","description":"Regime de desoneração da folha. Muda o custo da mão de obra, e com ele o custo da composição.","schema":{"type":"string","enum":["sem_deson","com_deson"],"default":"sem_deson"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"itens":{"type":"array","items":{"$ref":"#/components/schemas/ItemConferencia"}},"texto":{"type":"string","description":"Alternativa a `itens`: linhas `codigo;quantidade;custo`"}}},"example":{"itens":[{"codigo":104658,"quantidade":120,"custo":245}]}}}},"responses":{"200":{"description":"Conferência do lote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RespostaConferencia"}}}},"400":{"description":"Corpo inválido ou lote vazio","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"413":{"description":"Lote acima de 1000 itens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}},"429":{"description":"Limite de requisições (30/min)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Erro"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Chave de leitura. NA DEMONSTRAÇÃO ELA NÃO É VERIFICADA: nenhuma rota lê este header hoje, e a API responde sem credencial nenhuma. O teto de requisições é contado por sessão, e por IP quando não há sessão, e NÃO por esta chave: um balde escolhido pelo cliente seria um teto que o cliente controla, bastando mandar um valor novo a cada chamada. Em produção ela passa a ser obrigatória e verificada, com cota por chave e trilha por chamada. Está declarada aqui para o cliente já nascer com o campo, e porque enviá-la não quebra nada."}},"schemas":{"Versao":{"type":"object","properties":{"uf":{"type":"string","example":"SP"},"mes":{"type":"string","example":"05/2026"},"regime":{"type":"string","example":"sem desoneração"}}},"VersaoDisponivel":{"type":"object","description":"Uma das praças que a base serve. O `regimeSlug` é o valor que vai no parâmetro `regime`, enquanto `regime` é o texto para exibir. Os dois existem porque o que a máquina manda e o que a pessoa lê não são a mesma coisa.","properties":{"uf":{"type":"string","example":"AC"},"mes":{"type":"string","example":"05/2026"},"regime":{"type":"string","example":"sem desoneração"},"regimeSlug":{"type":"string","enum":["sem_deson","com_deson"]},"rotulo":{"type":"string","description":"Rótulo pronto para exibir","example":"AC · 05/2026 · sem desoneração"}}},"Insumo":{"type":"object","properties":{"codigo":{"type":"integer","example":88309},"classificacao":{"type":"string"},"descricao":{"type":"string"},"unidade":{"type":"string","example":"H"},"origem":{"type":"string","nullable":true,"description":"C (coletado) ou CR (composição representativa)"},"preco":{"type":"number","nullable":true,"description":"Preço publicado; null se sem preço na vigência"}}},"Composicao":{"type":"object","properties":{"codigo":{"type":"integer","example":104658},"grupo":{"type":"string"},"unidade":{"type":"string","example":"M2"},"descricao":{"type":"string"},"custo":{"type":"number","nullable":true,"description":"Custo unitário publicado; null se sem custo"},"pct_as":{"type":"number","description":"Percentual do custo desta composição que a CAIXA obteve com preços de São Paulo por indisponibilidade de coleta na praça. Não é encargo social nem auxílio: é um indicador de procedência do preço, e quanto maior, menos o custo reflete a praça consultada."},"sem_custo":{"type":"boolean"}}},"ItemArvore":{"type":"object","properties":{"tipo":{"type":"string","enum":["INSUMO","COMPOSICAO"]},"codigo":{"type":"integer"},"descricao":{"type":"string"},"unidade":{"type":"string"},"coeficiente":{"type":"number"},"custoUnitario":{"type":"number","nullable":true},"custoTotal":{"type":"number","nullable":true},"situacao":{"type":"string"}}},"Erro":{"type":"object","properties":{"erro":{"type":"string"},"versao":{"$ref":"#/components/schemas/Versao"}}},"ItemConferencia":{"type":"object","required":["codigo","quantidade","custo"],"properties":{"codigo":{"type":"integer","example":104658},"quantidade":{"type":"number","example":120},"custo":{"type":"number","description":"Custo unitário adotado no orçamento conferido","example":245}}},"RespostaConferencia":{"type":"object","properties":{"versao":{"$ref":"#/components/schemas/Versao"},"resumo":{"type":"object","properties":{"total":{"type":"integer"},"naoEncontrados":{"type":"integer"},"acimaReferencia":{"type":"integer"},"totalAdotado":{"type":"number"},"totalReferencia":{"type":"number"},"exposicaoGlosa":{"type":"number","description":"Valor adotado acima da referência (risco de glosa)"}}},"itens":{"type":"array","items":{"type":"object"}},"rejeitadas":{"type":"array","items":{"type":"object","properties":{"indice":{"type":"integer"},"motivo":{"type":"string"}}}}}}}}}