API & MCP
Erros
Erros têm sempre o mesmo formato: ok: false, um error estável (para o seu código), uma message humana, o docs e o requestId. Trate pelo error, nunca pela mensagem.
Um cliente acima do raio de atendimento de uma conta que pede contato fora dele (o exemplo de Cotação):
{
"ok": false,
"error": "fora-da-area",
"message": "O cliente está acima do raio de atendimento do perfil, e a conta pede contato em vez de preço fora do raio. A resposta traz distanciaKm, raioKm e destino.",
"docs": "https://app.ionluz.com.br/docs/api",
"requestId": "req_9f2c1a7b3d4e5f6a90",
"kwp": 5.91,
"fase": "bi",
"distanciaKm": 103,
"raioKm": 50,
"destino": "Campinas"
}| error | HTTP | O que fazer |
|---|---|---|
chave-invalida | 401 | Confira o cabeçalho Authorization: Bearer ilz_...; a chave pode ter sido revogada ou trocada, ou a conta está suspensa. |
plano-sem-api | 403 | Chave válida, mas o plano da conta não inclui API. A API pública é do plano Máquina, R$ 97 por mês. Assine em /plano. |
chave-de-teste | 403 | Recurso que a chave de teste não alcança, como /v1/proposals e a ferramenta get_proposal. Use a chave viva do plano Máquina. |
teto-teste | 429 | A chave de teste usou a cota do dia: 50 por dia na conta, somando as requisições REST e as chamadas de ferramenta do MCP; conectar e listar as ferramentas não gasta. A cota volta à meia-noite de Brasília. Sem Retry-After, porque a janela não é de segundos. |
metodo-nao-permitido | 405 | Método HTTP errado (ex.: GET em /v1/quote, POST em /v1/coverage). A resposta traz dica com o método certo. |
json | 400 | Corpo não é JSON válido. Verifique o Content-Type: application/json. |
payload-grande | 413 | Corpo passou de 4 KB. |
consumo | 400 | Sem consumoKwhMes e sem valorContaBrl, ou consumoKwhMes zero ou negativo sem o valor da conta junto. |
consumo-fora-de-faixa | 400 | consumoKwhMes acima do plausível. Confira a unidade: o campo é kWh por mês. |
valor-conta | 400 | valorContaBrl que não é um número maior que zero. É o valor total de uma conta de luz, em reais. Veja Pelo valor da conta de luz. |
valor-conta-fora-de-faixa | 400 | O consumo estimado pelo valorContaBrl passa do plausível. Confira a unidade: o campo é o valor de uma conta, em reais. |
valor-conta-na-taxa-minima | 422 | A conta não passa da taxa mínima da distribuidora para a ligação: não há consumo para a energia solar compensar. A resposta traz taxaMinimaKwh, taxaMinimaBrl, tarifaBrlKwh e fase. Diga isso ao cliente e confira a ligação. |
fase-invalida | 422 | fases não reconhecida. Envie mono, bi ou tri (ou monofasico, bifasico e trifasico, com ou sem acento). |
consentimento-obrigatorio | 400 | Gravação (não-preview) sem consent: true. Colete o consentimento do titular e reenvie. |
contato-obrigatorio | 400 | O lead da entrada de leads veio sem telefone (com DDD) e sem e-mail. Confira o mapeamento dos campos na integração. |
consentimento-invalido | 400 | Na entrada de leads, faltou o texto, a data ou a fonte do consentimento, ou a data não deu para ler. A resposta traz campos com o que faltou. |
origem-invalida | 400 | origem fora de meta-formulario, make, zapier e outro. A resposta traz parametro e aceito; sem o campo, vale outro. |
opcao-invalida | 400 | opcao fora de economica, recomendada e bateria, numa conta com o motor novo (vale mesmo com as opções desligadas). A resposta traz parametro e aceito. Nas contas sem o motor novo o campo é ignorado. |
faixa-nao-atendida | 422 | A faixa foi marcada como "não atendo" na sua cobertura (a resposta traz motivo: "nao-atendo"), ou nenhum kit, nem o do catálogo padrão, atende esse porte e essa fase. Trate como pedido de contato; consulte /v1/coverage. |
fora-da-area | 422 | O cliente está acima do raio de atendimento do seu perfil, e fora do raio a sua conta pede contato em vez de preço. A resposta traz distanciaKm, raioKm e destino. Grave o contato e responda você, ou, no perfil, escolha cotar e cobrar o deslocamento acima do raio. |
sem-preco-configurado | 422 | A formação de preço da conta não gerou valor para esse sistema e a referência de mercado não pôde substituir. Revise em Formação de preço. A resposta traz kwp e fase. |
teto-leads | 429 | A conta chegou ao limite de 50.000 propostas desta origem (a API e a página de captação contam separado). Vem sem Retry-After: não adianta repetir; fale com o suporte. |
rate | 429 | Muitas requisições. Espere o Retry-After. |
idempotencia | 422 | Idempotency-Key reutilizada com corpo diferente. Use uma chave nova por operação. |
em-processamento | 409 | Outra requisição com a mesma Idempotency-Key ainda está processando. Repita em instantes. |
proposta-nao-encontrada | 404 | Nenhuma proposta com este id nesta conta. Confira o id, ou liste em /v1/proposals. |
parametro-invalido | 400 | Parâmetro de query fora do aceito (limit, origem). A resposta traz parametro e aceito com os valores válidos. |
interno | 500 | Erro nosso. Repita; se persistir, escreva para suporte@ionluz.com.br com o requestId. |
Campos que vêm junto do erro
| Campo | Em quais erros |
|---|---|
kwp, fase | faixa-nao-atendida, fora-da-area, sem-preco-configurado |
motivo: "nao-atendo" | faixa-nao-atendida, quando a faixa foi marcada "não atendo" |
distanciaKm, raioKm, destino | fora-da-area |
parametro, aceito | parametro-invalido, opcao-invalida, origem-invalida |
campos | consentimento-invalido: o que faltou do consentimento (texto, data, fonte) |
taxaMinimaKwh, taxaMinimaBrl, tarifaBrlKwh, fase | valor-conta-na-taxa-minima |
dica | metodo-nao-permitido |
Os links da proposta (pdfUrl e propostaUrl)
Os links são públicos e não pedem chave. O navegador recebe uma página explicando o problema; os outros clientes recebem { "ok": false, "error": "<código>" }.
| Situação | Resposta do pdfUrl |
|---|---|
| Token do link alterado | 403 token |
| Proposta que não existe | 404 nao-encontrada |
| Conta suspensa | 403 conta-suspensa |
| Muitas aberturas seguidas do mesmo PDF | 429 rate, com Retry-After |
| Fila de geração de PDF cheia | 503 pdf-ocupado, com Retry-After |
| Falha ao gerar o PDF | 500 pdf: tente de novo em instantes |
| Motor novo: "eu aprovo antes" pendente | 409 em-confirmacao (o propostaUrl abre e mostra que o valor está em confirmação) |
| Motor novo: publicação só com o pedido | 409 preco-nao-publicado |
| Motor novo: proposta recusada pela empresa | 409 proposta-encerrada |
Erros do MCP (códigos JSON-RPC e o resultado com isError): veja MCP, para agentes de IA. A documentação de cada erro também está em https://app.ionluz.com.br/api/v1/openapi.json, com um exemplo por código.
API v1 · ionluz, propostas solares honestas. Dúvidas? Cite o
requestId ao escrever para suporte@ionluz.com.br.