{"openapi":"3.1.0","info":{"title":"InfoGP API","description":"\nAPI REST para **criar leads** e **consultar dados do CRM** da InfoGP (lojas, marcas, modelos).\nO caso de uso (landing page, app, formulário, integração própria) é decidido por você.\n\n## Autenticação\nTodas as rotas `/api/v1/*` exigem um token de API no header\n`Authorization: Bearer <token>`. Solicite o token à equipe da InfoGP.\nClique em **Authorize** para testar aqui. Sem token → `401`; excesso de\nrequisições → `429`.\n\n## Recursos\n- **Criar lead:** `POST /api/v1/leads`.\n- **Catálogo do CRM:** `GET /api/v1/stores` (o `id` da loja é o `loja_id` do lead),\n  `GET /api/v1/brands`, `GET /api/v1/models?brand=`.\n\n## Identidade e deduplicação\nO lead é identificado pelo **telefone** (normalizado para E.164). Se o telefone já\nexiste, a API responde `200 {\"status\":\"exists\"}` com o lead existente e **não\nduplica** o cadastro.\n\n## Paginação dos GETs de lista\nAceitam `?limit=` (padrão 50, máx 200) e `?offset=`. Resposta em envelope\n`{ \"items\": [...], \"total\": N, \"limit\": L, \"offset\": O }`. Respostas cacheáveis\n(`Cache-Control: public, max-age=300`).\n\n## Erros\n`400` payload inválido (campo em `detail.field`) · `401` token ausente/inválido ·\n`429` rate limit · `503` indisponível.\n","contact":{"name":"InfoGP","url":"https://infogpdev.com/"},"version":"1.0.0"},"servers":[{"url":"https://crm.infogpdev.com","description":"produção"}],"paths":{"/api/v1/stores":{"get":{"tags":["catálogo"],"summary":"Lista lojas ativas do CRM","operationId":"stores_api_v1_stores_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page_StoreOut_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/brands":{"get":{"tags":["catálogo"],"summary":"Lista marcas do CRM","operationId":"brands_api_v1_brands_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page_BrandOut_"}}}}}}},"/api/v1/models":{"get":{"tags":["catálogo"],"summary":"Lista modelos de uma marca (cascata)","operationId":"models_api_v1_models_get","parameters":[{"name":"brand","in":"query","required":true,"schema":{"type":"string","title":"Brand"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page_ModelOut_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/leads":{"post":{"tags":["leads"],"summary":"Cria ou retorna um lead (deduplicação por telefone)","description":"Cria um lead no CRM. Identidade pelo telefone (E.164): telefone já\ncadastrado retorna o lead existente (`status=exists`), sem duplicar. A\norigem é carimbada no servidor a partir do token.","operationId":"create_lead_api_v1_leads_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadIn"}}},"required":true},"responses":{"200":{"description":"Lead já existia (dedup por telefone) — não duplicado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadOut"}}}},"201":{"description":"Lead criado"},"400":{"description":"Payload inválido (campo problemático em detail.field)"},"401":{"description":"Token ausente ou inválido"},"429":{"description":"Rate limit excedido"},"503":{"description":"Indisponível (erro interno)"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BrandOut":{"properties":{"nome":{"type":"string","title":"Nome"}},"type":"object","required":["nome"],"title":"BrandOut"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LeadIn":{"properties":{"nome":{"type":"string","title":"Nome"},"telefone":{"type":"string","title":"Telefone"},"loja_id":{"type":"integer","title":"Loja Id"},"cpf":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cpf"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"marca":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marca"},"modelo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Modelo"}},"type":"object","required":["nome","telefone","loja_id"],"title":"LeadIn","example":{"cpf":"000.000.000-00","email":"maria@email.com","loja_id":12,"marca":"Volkswagen","modelo":"Tera 2026","nome":"Maria da Silva","telefone":"(11) 99999-8888"}},"LeadOut":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"status":{"type":"string","enum":["created","exists"],"title":"Status"}},"type":"object","required":["lead_id","status"],"title":"LeadOut"},"ModelOut":{"properties":{"marca":{"type":"string","title":"Marca"},"modelo":{"type":"string","title":"Modelo"}},"type":"object","required":["marca","modelo"],"title":"ModelOut"},"Page_BrandOut_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BrandOut"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"Page[BrandOut]"},"Page_ModelOut_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ModelOut"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"Page[ModelOut]"},"Page_StoreOut_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/StoreOut"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["items","total","limit","offset"],"title":"Page[StoreOut]"},"StoreOut":{"properties":{"id":{"type":"integer","title":"Id"},"nome":{"type":"string","title":"Nome"},"marca":{"type":"string","title":"Marca"},"cidade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cidade"},"uf":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uf"}},"type":"object","required":["id","nome","marca"],"title":"StoreOut"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Token de API da InfoGP"}}},"tags":[{"name":"leads","description":"Criação e deduplicação de leads."},{"name":"catálogo","description":"Lojas, marcas e modelos do CRM."}],"security":[{"BearerAuth":[]}]}