{
  "openapi": "3.1.0",
  "info": {
    "title": "API pública da Premium Sorte",
    "version": "1.0.0",
    "summary": "Dados públicos de premiumsorte.com para agentes de IA e integrações. Somente leitura.",
    "description": "Busca de páginas, glossário de rifas e sorteios, comparativos com outras plataformas, calculadora de rifa e canais de contato comercial. Tudo o que a API devolve já está publicado no site.\n\n**Autenticação:** nenhuma. A API é aberta: não exige chave, token nem cadastro (no API key required). Por ser somente leitura, dá para testar à vontade: nenhuma chamada altera dados.\n\n**Erros:** respostas 4xx e 5xx em `application/problem+json` (RFC 9457), com `code` estável e `hint` de correção.\n\n**Paginação:** listas devolvem `itens`, `total` e `proximoCursor`; passe o cursor no parâmetro `cursor` para ler a próxima página.\n\n**Versionamento e política de descontinuação (deprecation policy):** a versão fica no caminho (`/api/v1`) e mudanças incompatíveis entram num novo caminho. Se uma versão for descontinuada, a data sai na documentação (https://premiumsorte.com/desenvolvedores) e as respostas dessa versão passam a trazer os cabeçalhos `Deprecation` e `Sunset`.\n\nFree, open and read-only: no API key, no sign-up, and every call is safe to repeat, so no separate sandbox is needed.\n\n**Uso justo:** não há cota anunciada por cliente; a API divide a capacidade do site, e abusos podem ser bloqueados pela proteção do Cloudflare.",
    "contact": {
      "name": "Premium Sorte",
      "url": "https://premiumsorte.com/contato",
      "email": "contato@premiumsorte.com"
    }
  },
  "externalDocs": {
    "description": "Documentação para desenvolvedores",
    "url": "https://premiumsorte.com/desenvolvedores"
  },
  "servers": [
    {
      "url": "https://premiumsorte.com/api/v1",
      "description": "Produção"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "site",
      "description": "Páginas e índice do site"
    },
    {
      "name": "glossario",
      "description": "Termos do mercado de rifas e sorteios"
    },
    {
      "name": "comparativos",
      "description": "Comparações com outras plataformas de rifa"
    },
    {
      "name": "ferramentas",
      "description": "Cálculos e contato comercial"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "descreverApi",
        "tags": [
          "site"
        ],
        "summary": "Descreve a API",
        "description": "Nome, versão, autenticação (nenhuma), links para a documentação e a especificação, e a lista de rotas.",
        "responses": {
          "200": {
            "description": "Descrição da API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DescricaoDaApi"
                }
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/paginas": {
      "get": {
        "operationId": "buscarPaginas",
        "tags": [
          "site"
        ],
        "summary": "Busca páginas do site",
        "description": "Busca por palavras no título, no resumo e na seção das páginas públicas (produto, legalização de rifas e sorteios no Brasil, comparativos, segmentos, ferramentas, blog e glossário), da mais para a menos relevante. Sem `busca`, lista todas as páginas na ordem do llms.txt.",
        "parameters": [
          {
            "name": "busca",
            "in": "query",
            "required": false,
            "description": "Palavras de busca em português, por exemplo \"legalizar rifa\".",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "description": "Itens por página, de 1 a 50 (padrão 10).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor de paginação: o valor de proximoCursor devolvido pela página anterior.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de resultados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListaDePaginas"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/glossario": {
      "get": {
        "operationId": "listarTermosDoGlossario",
        "tags": [
          "glossario"
        ],
        "summary": "Lista os termos do glossário",
        "description": "Termos do mercado de rifas e sorteios (cota, cota premiada, baixa automática, whitelabel e outros), com definição curta.",
        "parameters": [
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "description": "Itens por página, de 1 a 50 (padrão 10).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor de paginação: o valor de proximoCursor devolvido pela página anterior.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de termos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListaDeTermos"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/glossario/{termo}": {
      "get": {
        "operationId": "obterTermoDoGlossario",
        "tags": [
          "glossario"
        ],
        "summary": "Definição completa de um termo",
        "description": "Aceita o slug (\"cota-premiada\") ou o nome do termo, sem diferenciar acento e caixa (\"Cota premiada\").",
        "parameters": [
          {
            "name": "termo",
            "in": "path",
            "required": true,
            "description": "Slug ou nome do termo.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Termo encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TermoDetalhado"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/comparativos": {
      "get": {
        "operationId": "listarComparativos",
        "tags": [
          "comparativos"
        ],
        "summary": "Lista as plataformas comparadas",
        "description": "Plataformas de rifa comparadas com a Premium Sorte, com modelo de cobrança, resumo de preços que o concorrente divulga (quando divulga) e mês de verificação dos dados.",
        "parameters": [
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "description": "Itens por página, de 1 a 50 (padrão 10).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 10
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Cursor de paginação: o valor de proximoCursor devolvido pela página anterior.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Página de comparativos.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListaDeComparativos"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/comparativos/{plataforma}": {
      "get": {
        "operationId": "obterComparativo",
        "tags": [
          "comparativos"
        ],
        "summary": "Comparação recurso a recurso com uma plataforma",
        "description": "Tabela lado a lado, pontos fortes e fracos do concorrente e fontes públicas. Aceita o slug (\"suprasorte\") ou o nome (\"Supra Sorte\").",
        "parameters": [
          {
            "name": "plataforma",
            "in": "path",
            "required": true,
            "description": "Slug ou nome da plataforma.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Comparativo encontrado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComparativoDetalhado"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Erro404"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/calculadora-rifa": {
      "get": {
        "operationId": "calcularRifa",
        "tags": [
          "ferramentas"
        ],
        "summary": "Calcula o resultado de uma rifa",
        "description": "Arrecadação, custos, lucro com 100%, 75% e 50% das cotas vendidas, ponto de equilíbrio em cotas e margem. A taxa percentual incide sobre o que foi arrecadado em cada cenário. Mesmo cálculo da calculadora de rifa do site. Valores em reais; impostos sobre o prêmio não entram.",
        "parameters": [
          {
            "name": "valorPremio",
            "in": "query",
            "required": true,
            "description": "Valor do prêmio em reais (até 1 trilhão).",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 1000000000000
            }
          },
          {
            "name": "numeroCotas",
            "in": "query",
            "required": true,
            "description": "Quantidade de cotas à venda (até 100 milhões).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100000000
            }
          },
          {
            "name": "precoCota",
            "in": "query",
            "required": true,
            "description": "Preço de cada cota em reais.",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 1000000000000
            }
          },
          {
            "name": "custosExtras",
            "in": "query",
            "required": false,
            "description": "Outros custos da campanha em reais.",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1000000000000
            }
          },
          {
            "name": "taxaPercentual",
            "in": "query",
            "required": false,
            "description": "Taxa percentual sobre a arrecadação, de 0 a 100.",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 100
            }
          },
          {
            "name": "taxaFixa",
            "in": "query",
            "required": false,
            "description": "Taxa fixa total em reais.",
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 1000000000000
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resultado do cálculo.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResultadoRifa"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Erro400"
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/contato": {
      "get": {
        "operationId": "obterContatoComercial",
        "tags": [
          "ferramentas"
        ],
        "summary": "Canais para pedir uma proposta",
        "description": "WhatsApp com mensagem pronta, e-mail e página de contato. Não envia nenhuma mensagem. Os preços são por proposta personalizada.",
        "parameters": [
          {
            "name": "mensagem",
            "in": "query",
            "required": false,
            "description": "Contexto opcional para a mensagem inicial do WhatsApp (até 500 caracteres).",
            "schema": {
              "type": "string",
              "maxLength": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Canais de contato.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contato"
                }
              }
            }
          },
          "405": {
            "$ref": "#/components/responses/Erro405"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DescricaoDaApi": {
        "type": "object",
        "required": [
          "nome",
          "versao",
          "autenticacao",
          "documentacao",
          "especificacao",
          "rotas"
        ],
        "properties": {
          "nome": {
            "type": "string",
            "description": "Nome da API."
          },
          "versao": {
            "type": "string",
            "description": "Versão no caminho."
          },
          "descricao": {
            "type": "string",
            "description": "O que a API oferece."
          },
          "autenticacao": {
            "type": "string",
            "description": "Como autenticar (nenhuma: API aberta)."
          },
          "documentacao": {
            "type": "string",
            "format": "uri"
          },
          "especificacao": {
            "type": "string",
            "format": "uri"
          },
          "servidorMcp": {
            "type": "string",
            "format": "uri",
            "description": "Servidor MCP com as mesmas funções."
          },
          "rotas": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "metodo",
                "caminho",
                "descricao"
              ],
              "properties": {
                "metodo": {
                  "type": "string"
                },
                "caminho": {
                  "type": "string"
                },
                "descricao": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Pagina": {
        "type": "object",
        "required": [
          "url",
          "titulo",
          "resumo",
          "secao"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "titulo": {
            "type": "string",
            "description": "Título da página."
          },
          "resumo": {
            "type": "string",
            "description": "Resumo em uma frase."
          },
          "secao": {
            "type": "string",
            "description": "Seção do site."
          }
        }
      },
      "ListaDePaginas": {
        "type": "object",
        "description": "Páginas encontradas.",
        "required": [
          "itens",
          "total",
          "proximoCursor"
        ],
        "properties": {
          "itens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Pagina"
            }
          },
          "total": {
            "type": "integer",
            "description": "Total de itens na lista completa."
          },
          "proximoCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Valor para o parâmetro cursor da próxima página; null quando não há mais itens."
          }
        }
      },
      "Termo": {
        "type": "object",
        "required": [
          "slug",
          "termo",
          "definicao",
          "url"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "termo": {
            "type": "string",
            "description": "Nome do termo."
          },
          "definicao": {
            "type": "string",
            "description": "Definição curta."
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ListaDeTermos": {
        "type": "object",
        "description": "Termos do glossário.",
        "required": [
          "itens",
          "total",
          "proximoCursor"
        ],
        "properties": {
          "itens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Termo"
            }
          },
          "total": {
            "type": "integer",
            "description": "Total de itens na lista completa."
          },
          "proximoCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Valor para o parâmetro cursor da próxima página; null quando não há mais itens."
          }
        }
      },
      "TermoDetalhado": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Termo"
          },
          {
            "type": "object",
            "required": [
              "texto",
              "relacionados"
            ],
            "properties": {
              "texto": {
                "type": "string",
                "description": "Explicação completa, como publicada no site."
              },
              "relacionados": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "slug",
                    "url"
                  ],
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "Comparativo": {
        "type": "object",
        "required": [
          "slug",
          "nome",
          "site",
          "modelo",
          "precoResumo",
          "dataVerificacao",
          "urls"
        ],
        "properties": {
          "slug": {
            "type": "string"
          },
          "nome": {
            "type": "string",
            "description": "Nome da plataforma concorrente."
          },
          "site": {
            "type": "string",
            "format": "uri"
          },
          "modelo": {
            "type": "string",
            "description": "Modelo de negócio e de cobrança do concorrente."
          },
          "precoResumo": {
            "type": "string",
            "description": "Resumo de preços como o concorrente divulga; pode dizer que não há preço público."
          },
          "dataVerificacao": {
            "type": "string",
            "description": "Mês de verificação dos dados (AAAA-MM)."
          },
          "urls": {
            "type": "object",
            "required": [
              "alternativa",
              "comparativo"
            ],
            "properties": {
              "alternativa": {
                "type": "string",
                "format": "uri"
              },
              "comparativo": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "ListaDeComparativos": {
        "type": "object",
        "description": "Plataformas comparadas.",
        "required": [
          "itens",
          "total",
          "proximoCursor"
        ],
        "properties": {
          "itens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Comparativo"
            }
          },
          "total": {
            "type": "integer",
            "description": "Total de itens na lista completa."
          },
          "proximoCursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Valor para o parâmetro cursor da próxima página; null quando não há mais itens."
          }
        }
      },
      "ComparativoDetalhado": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Comparativo"
          },
          {
            "type": "object",
            "required": [
              "tabela",
              "pontosFortesConcorrente",
              "pontosFracosConcorrente",
              "fontes",
              "observacao"
            ],
            "properties": {
              "tabela": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "recurso",
                    "premiumSorte",
                    "concorrente"
                  ],
                  "properties": {
                    "recurso": {
                      "type": "string"
                    },
                    "premiumSorte": {
                      "type": "string"
                    },
                    "concorrente": {
                      "type": "string"
                    }
                  }
                }
              },
              "pontosFortesConcorrente": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "pontosFracosConcorrente": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "fontes": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "observacao": {
                "type": "string",
                "description": "Natureza e limites dos dados do concorrente."
              }
            }
          }
        ]
      },
      "Cenario": {
        "type": "object",
        "required": [
          "vendido",
          "arrecadacao",
          "custos",
          "lucro"
        ],
        "properties": {
          "vendido": {
            "type": "number",
            "description": "Fração das cotas vendidas (1, 0,75 ou 0,5)."
          },
          "arrecadacao": {
            "type": "number",
            "description": "Valor arrecadado no cenário, em reais."
          },
          "custos": {
            "type": "number",
            "description": "Custos no cenário, em reais."
          },
          "lucro": {
            "type": "number",
            "description": "Lucro no cenário, em reais (negativo é prejuízo)."
          }
        }
      },
      "ResultadoRifa": {
        "type": "object",
        "required": [
          "arrecadacaoMaxima",
          "custosFixos",
          "cenarios",
          "pontoEquilibrioCotas",
          "pontoEquilibrioAlcancavel",
          "margem100"
        ],
        "properties": {
          "arrecadacaoMaxima": {
            "type": "number",
            "description": "Arrecadação com todas as cotas vendidas, em reais."
          },
          "custosFixos": {
            "type": "number",
            "description": "Prêmio, custos extras e taxa fixa, em reais."
          },
          "cenarios": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Cenario"
            }
          },
          "pontoEquilibrioCotas": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Cotas para cobrir os custos; null quando a taxa consome todo o preço."
          },
          "pontoEquilibrioAlcancavel": {
            "type": "boolean",
            "description": "false quando nem vendendo todas as cotas a rifa se paga."
          },
          "margem100": {
            "type": "number",
            "description": "Margem sobre a arrecadação máxima, em %."
          }
        }
      },
      "Contato": {
        "type": "object",
        "required": [
          "whatsapp",
          "email",
          "pagina",
          "modeloComercial"
        ],
        "properties": {
          "whatsapp": {
            "type": "object",
            "required": [
              "numero",
              "link"
            ],
            "properties": {
              "numero": {
                "type": "string"
              },
              "link": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "pagina": {
            "type": "string",
            "format": "uri"
          },
          "modeloComercial": {
            "type": "string",
            "description": "Como a proposta comercial é definida."
          }
        }
      },
      "Problema": {
        "type": "object",
        "description": "Erro no formato RFC 9457 (application/problem+json).",
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "code",
          "hint"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string",
            "description": "Resumo do tipo de erro."
          },
          "status": {
            "type": "integer",
            "description": "Mesmo status HTTP da resposta."
          },
          "detail": {
            "type": "string",
            "description": "O que deu errado nesta chamada."
          },
          "code": {
            "type": "string",
            "description": "Código estável para tratar o erro.",
            "enum": [
              "parametro_obrigatorio",
              "parametro_invalido",
              "limite_invalido",
              "cursor_invalido",
              "termo_nao_encontrado",
              "plataforma_nao_encontrada",
              "rota_nao_encontrada",
              "metodo_nao_permitido",
              "erro_interno"
            ]
          },
          "hint": {
            "type": "string",
            "description": "Como corrigir a chamada."
          }
        }
      }
    },
    "responses": {
      "Erro400": {
        "description": "Parâmetro ausente ou inválido.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problema"
            }
          }
        }
      },
      "Erro404": {
        "description": "Recurso não encontrado.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problema"
            }
          }
        }
      },
      "Erro405": {
        "description": "Método não permitido (use GET).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problema"
            }
          }
        }
      },
      "Erro500": {
        "description": "Erro interno.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problema"
            }
          }
        }
      }
    }
  }
}