{
  "openapi": "3.1.0",
  "info": {
    "title": "API do BAIXA XML",
    "version": "1",
    "description": "Download de XML de NF-e por chave, lote e SPED, notas da captura automática e webhooks. Documentação: https://baixaxml.com.br/desenvolvedores"
  },
  "servers": [
    {
      "url": "https://baixaxml.com.br/api"
    }
  ],
  "security": [
    {
      "chaveApi": []
    }
  ],
  "components": {
    "securitySchemes": {
      "chaveApi": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  },
  "tags": [
    {
      "name": "Consulta por chave",
      "description": "Uma chave, o XML na resposta. Para integrar nota a nota no seu sistema."
    },
    {
      "name": "Lotes",
      "description": "Muitas chaves de uma vez. O lote roda em segundo plano: acompanhe pelo status ou receba o webhook `lote.concluido`."
    },
    {
      "name": "SPED",
      "description": "Envie a EFD ICMS/IPI ou a EFD Contribuições e baixe os XMLs das notas escrituradas, com filtros. Analisar é gratuito; o download vira um lote."
    },
    {
      "name": "Captura automática (certificado A1)",
      "description": "As notas emitidas contra os CNPJs da sua conta, direto da SEFAZ. Certificados e empresas são cadastrados no painel; pela API você lê as notas. Em liberação gradual."
    },
    {
      "name": "Webhooks",
      "description": "Avisamos uma URL sua quando algo acontece, em vez de você consultar em intervalos. Veja a seção \"Recebendo webhooks\" para validar a assinatura."
    },
    {
      "name": "Conta e créditos",
      "description": "Saldo, preços e extrato."
    }
  ],
  "paths": {
    "/nfe/consulta/{chave}": {
      "get": {
        "operationId": "consultarChave",
        "tags": [
          "Consulta por chave"
        ],
        "summary": "Consultar o XML de uma NF-e",
        "description": "Busca o XML original (com a assinatura do emitente) pela chave de acesso. A mesma chave consultada de novo em até 24 horas não é cobrada outra vez. Com `formato=xml`, a resposta é o próprio arquivo.\n\n**Cobrança:** 1 XML na faixa de preço da conta, só se encontrar. O valor cobrado vem no cabeçalho `X-Cobrado-Centavos`.",
        "parameters": [
          {
            "name": "chave",
            "in": "path",
            "required": true,
            "description": "Chave de acesso, 44 dígitos.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "formato",
            "in": "query",
            "required": false,
            "description": "`xml` para receber o arquivo cru em vez de JSON.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "chave": "35241012345678000190550010000123451234567892",
                  "xml": "<nfeProc xmlns=\"http://www.portalfiscal.inf.br/nfe\" versao=\"4.00\">…</nfeProc>",
                  "cobradoCentavos": 6,
                  "repetida": false
                }
              }
            }
          },
          "400": {
            "description": "Saldo insuficiente (`error: \"SaldoInsuficiente\"`, com `faltamCentavos`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          },
          "404": {
            "description": "A fonte não tem o XML (`NaoEncontrada`). Nada é cobrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Fonte fora do ar (`FonteIndisponivel`), com `Retry-After`. Nada é cobrado.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/nfe/lote/chaves": {
      "post": {
        "operationId": "criarLote",
        "tags": [
          "Lotes"
        ],
        "summary": "Criar um lote",
        "description": "Envie as chaves em texto (uma por linha, ou separadas por vírgula). Sequências de 44 dígitos são extraídas e repetidas são descartadas. O valor do lote é reservado na hora.\n\n**Cobrança:** Reserva o lote inteiro na criação; no fim, cobra só os XMLs entregues e devolve o resto.",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "jobId": "nfe_1728480000000_k2x9q1a",
                  "total": 1200,
                  "custoCentavos": 7200,
                  "status": "PENDENTE"
                }
              }
            }
          },
          "400": {
            "description": "Saldo insuficiente (`error: \"SaldoInsuficiente\"`, com `faltamCentavos`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "chaves"
                ],
                "properties": {
                  "chaves": {
                    "type": "string",
                    "description": "As chaves, em texto livre."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/nfe/lote": {
      "post": {
        "operationId": "criarLoteArquivo",
        "tags": [
          "Lotes"
        ],
        "summary": "Criar um lote a partir de arquivo",
        "description": "O mesmo, enviando um `.csv` ou `.txt` (até 200 MB) em `multipart/form-data`. As chaves podem estar em qualquer coluna.\n\n**Cobrança:** Igual ao lote por texto.",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "jobId": "nfe_1728480000000_k2x9q1a",
                  "total": 85000,
                  "custoCentavos": 340000,
                  "status": "PENDENTE"
                }
              }
            }
          },
          "400": {
            "description": "Saldo insuficiente (`error: \"SaldoInsuficiente\"`, com `faltamCentavos`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "arquivo"
                ],
                "properties": {
                  "arquivo": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV ou TXT com as chaves."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listarLotes",
        "tags": [
          "Lotes"
        ],
        "summary": "Listar os lotes",
        "description": "Os lotes da conta, do mais recente para o mais antigo.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": [
                  {
                    "id": "nfe_1728480000000_k2x9q1a",
                    "status": "CONCLUIDO",
                    "total": 1200,
                    "ok": 1183,
                    "notfound": 17,
                    "erro": 0,
                    "createdAt": "2026-10-09T13:00:00.000Z",
                    "finishedAt": "2026-10-09T13:41:00.000Z"
                  }
                ]
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/nfe/lote/{jobId}": {
      "get": {
        "operationId": "statusLote",
        "tags": [
          "Lotes"
        ],
        "summary": "Status de um lote",
        "description": "`status`: `PENDENTE`, `PROCESSANDO`, `CONCLUIDO` ou `ERRO`. `progresso` vai de 0 a 1.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "O `jobId` da criação.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "id": "nfe_1728480000000_k2x9q1a",
                  "status": "PROCESSANDO",
                  "total": 1200,
                  "ok": 640,
                  "notfound": 9,
                  "erro": 0,
                  "processados": 649,
                  "pendentes": 551,
                  "progresso": 0.5408
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          },
          "404": {
            "description": "Lote inexistente ou de outra conta.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "cancelarLote",
        "tags": [
          "Lotes"
        ],
        "summary": "Cancelar ou apagar um lote",
        "description": "Cancela o lote em andamento (cobra só o que já foi entregue) ou apaga um lote concluído e os arquivos dele.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "O `jobId`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "ok": true,
                  "removido": "nfe_1728480000000_k2x9q1a"
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/nfe/lote/{jobId}/resultados": {
      "get": {
        "operationId": "resultadosLote",
        "tags": [
          "Lotes"
        ],
        "summary": "Resultado por chave",
        "description": "O que aconteceu com cada chave já processada: `ok`, `notfound` (a fonte não tem) ou `erro` (falha que persistiu). JSON paginado, ou o arquivo inteiro com `formato=csv`.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "O `jobId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filtra por `ok`, `notfound` ou `erro`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "formato",
            "in": "query",
            "required": false,
            "description": "`csv` para baixar tudo (`chave;status;motivo`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pagina",
            "in": "query",
            "required": false,
            "description": "Página, a partir de 1.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "porPagina",
            "in": "query",
            "required": false,
            "description": "Até 1.000 (padrão 500).",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "jobId": "nfe_1728480000000_k2x9q1a",
                  "status": "CONCLUIDO",
                  "total": 1200,
                  "pagina": 1,
                  "porPagina": 500,
                  "itens": [
                    {
                      "chave": "35241012345678000190550010000123451234567892",
                      "status": "ok"
                    },
                    {
                      "chave": "3524…",
                      "status": "notfound",
                      "motivo": "Nota não localizada"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/nfe/lote/{jobId}/xml/{chave}": {
      "get": {
        "operationId": "xmlDoLote",
        "tags": [
          "Lotes"
        ],
        "summary": "XML de uma chave do lote",
        "description": "Um arquivo só, sem precisar baixar o ZIP.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "O `jobId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chave",
            "in": "path",
            "required": true,
            "description": "Chave de acesso.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          },
          "404": {
            "description": "A chave não tem XML neste lote.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/nfe/lote/{jobId}/download": {
      "get": {
        "operationId": "zipDoLote",
        "tags": [
          "Lotes"
        ],
        "summary": "ZIP do lote",
        "description": "Todos os XMLs obtidos até agora — funciona também com o lote em andamento. Os arquivos ficam disponíveis por 48 horas depois do fim do lote.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "O `jobId`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          },
          "404": {
            "description": "Nenhum XML ainda.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sped/analises": {
      "post": {
        "operationId": "enviarSped",
        "tags": [
          "SPED"
        ],
        "summary": "Enviar arquivos SPED",
        "description": "`multipart/form-data` com um ou mais TXT do SPED, ou ZIP com eles (até 300 MB cada). A análise roda em segundo plano.",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
                  "status": "PROCESSANDO"
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "arquivos"
                ],
                "properties": {
                  "arquivos": {
                    "type": "string",
                    "format": "binary",
                    "description": "Os arquivos (campo repetido)."
                  },
                  "nome": {
                    "type": "string",
                    "description": "Nome para identificar a análise."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/sped/analises/{id}": {
      "get": {
        "operationId": "verSped",
        "tags": [
          "SPED"
        ],
        "summary": "Situação e resumo da análise",
        "description": "Quantidade de notas, período e a situação (`PROCESSANDO`, `CONCLUIDA`, `ERRO`).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id da análise.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/sped/analises/{id}/baixar": {
      "post": {
        "operationId": "baixarSped",
        "tags": [
          "SPED"
        ],
        "summary": "Baixar os XMLs das notas do SPED",
        "description": "Cria um lote com as chaves das notas que atendem aos filtros (todos opcionais). A partir daí é um lote comum.\n\n**Cobrança:** Igual ao lote.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id da análise.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "jobId": "nfe_1728480000000_k2x9q1a",
                  "total": 5508,
                  "custoCentavos": 33048
                }
              }
            }
          },
          "400": {
            "description": "Saldo insuficiente (`error: \"SaldoInsuficiente\"`, com `faltamCentavos`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "competencias": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`AAAA` ou `AAAA-MM`."
                  },
                  "cfops": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "CFOPs, 4 dígitos."
                  },
                  "operacoes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`E` (entrada) e/ou `S` (saída)."
                  },
                  "emissoes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "`P` (própria) e/ou `T` (terceiros)."
                  },
                  "modelos": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Ex.: `55`."
                  },
                  "situacoes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Código de situação do SPED, 2 dígitos."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/dfe/plano": {
      "get": {
        "operationId": "planoCaptura",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "Plano da captura",
        "description": "Faixa paga, CNPJs em uso, data e valor da renovação, e quanto custaria ativar mais um CNPJ agora.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/dfe/empresas": {
      "get": {
        "operationId": "empresasCaptura",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "Empresas monitoradas",
        "description": "Situação de cada CNPJ, última consulta à SEFAZ, certificado e contagem de notas.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/dfe/notas/alteracoes": {
      "get": {
        "operationId": "alteracoesNotas",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "Notas novas ou alteradas",
        "description": "Leitura incremental: guarde o `cursor` e mande na próxima chamada para receber só o que mudou (nota nova, XML completo que chegou, cancelamento). Repita enquanto `temMais` for `true`.",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "O da resposta anterior. Vazio = desde o começo.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "empresaId",
            "in": "query",
            "required": false,
            "description": "Só desta empresa.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "description": "Até 500 (padrão 100).",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "itens": [
                    {
                      "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
                      "chave": "35241012345678000190550010000123451234567892",
                      "emitenteDoc": "12345678000190",
                      "emitenteNome": "FORNECEDOR SA",
                      "valor": "1500.50",
                      "dataEmissao": "2026-10-08T14:22:00.000Z",
                      "situacao": "AUTORIZADA",
                      "xmlCompleto": true,
                      "disponivel": true,
                      "manifestacao": "CIENCIA",
                      "empresa": {
                        "cnpj": "98765432000110",
                        "nome": "Cliente Ltda"
                      },
                      "alteradaEm": "2026-10-09T10:01:12.000Z"
                    }
                  ],
                  "cursor": "MjAyNi0xMC0wOVQxMDowMToxMi4wMDBafDZmOTI…",
                  "temMais": false
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/dfe/notas": {
      "get": {
        "operationId": "listarNotasCaptura",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "Buscar notas recebidas",
        "description": "Listagem paginada com filtros, como no painel.",
        "parameters": [
          {
            "name": "empresaId",
            "in": "query",
            "required": false,
            "description": "Empresa.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "de",
            "in": "query",
            "required": false,
            "description": "Emissão a partir de (`AAAA-MM-DD`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ate",
            "in": "query",
            "required": false,
            "description": "Emissão até.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "situacao",
            "in": "query",
            "required": false,
            "description": "`AUTORIZADA`, `CANCELADA` ou `DENEGADA`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "busca",
            "in": "query",
            "required": false,
            "description": "Emitente, CNPJ ou chave.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "pagina",
            "in": "query",
            "required": false,
            "description": "Página.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "porPagina",
            "in": "query",
            "required": false,
            "description": "Itens por página.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/dfe/notas/{id}/xml": {
      "get": {
        "operationId": "xmlCaptura",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "XML de uma nota recebida",
        "description": "O XML completo, quando já chegou da SEFAZ.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id da nota (não a chave).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Só o resumo chegou até agora.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          },
          "404": {
            "description": "Nota inexistente ou de outra conta.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/dfe/notas/zip": {
      "get": {
        "operationId": "zipCaptura",
        "tags": [
          "Captura automática (certificado A1)"
        ],
        "summary": "ZIP das notas recebidas",
        "description": "Os XMLs completos que atendem aos mesmos filtros da busca.",
        "parameters": [
          {
            "name": "empresaId",
            "in": "query",
            "required": false,
            "description": "Empresa.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "de",
            "in": "query",
            "required": false,
            "description": "Emissão a partir de.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ate",
            "in": "query",
            "required": false,
            "description": "Emissão até.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/integracoes/webhooks/eventos": {
      "get": {
        "operationId": "eventosWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Eventos disponíveis",
        "description": "Os nomes que podem ser assinados.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": [
                  "lote.concluido",
                  "captura.xml_disponivel",
                  "captura.nota_cancelada"
                ]
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/integracoes/webhooks": {
      "get": {
        "operationId": "listarWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "Listar webhooks",
        "description": "Os endpoints cadastrados e a última entrega de cada um.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      },
      "post": {
        "operationId": "criarWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Cadastrar um webhook",
        "description": "URL `https://` pública e os eventos. O `segredo` de assinatura aparece só nesta resposta — guarde. Até 5 por conta.",
        "parameters": [],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "id": "6f92dd6b-5352-4c7f-a065-db421f252f4d",
                  "url": "https://seu-sistema.com.br/webhooks/baixaxml",
                  "eventos": [
                    "lote.concluido"
                  ],
                  "ativo": true,
                  "segredo": "whsec_…"
                }
              }
            }
          },
          "400": {
            "description": "URL que não é https, de rede interna, evento desconhecido ou limite atingido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusCode": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url",
                  "eventos"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Onde entregar."
                  },
                  "eventos": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Um ou mais eventos."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/integracoes/webhooks/{id}": {
      "patch": {
        "operationId": "atualizarWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Alterar um webhook",
        "description": "Troca URL ou eventos, ou pausa com `ativo: false`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id do webhook.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [],
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Nova URL."
                  },
                  "eventos": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Novos eventos."
                  },
                  "ativo": {
                    "type": "boolean",
                    "description": "Pausar/retomar."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removerWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Remover um webhook",
        "description": "Entregas pendentes dele são descartadas.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id do webhook.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/integracoes/webhooks/{id}/teste": {
      "post": {
        "operationId": "testarWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Enviar um evento de teste",
        "description": "Entrega um evento `teste` agora e devolve o resultado (status HTTP da sua URL ou o erro).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id do webhook.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/integracoes/webhooks/{id}/segredo": {
      "post": {
        "operationId": "novoSegredoWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Gerar outro segredo",
        "description": "Para rotação ou se o segredo vazou. O antigo deixa de valer na hora.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id do webhook.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/integracoes/webhooks/{id}/entregas": {
      "get": {
        "operationId": "entregasWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Últimas entregas",
        "description": "As 50 mais recentes, com situação (`entregue`, `pendente`, `falhou`), tentativas e o último erro.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Id do webhook.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/creditos": {
      "get": {
        "operationId": "saldo",
        "tags": [
          "Conta e créditos"
        ],
        "summary": "Saldo",
        "description": "Disponível, reservado em lotes em andamento e a tabela de preços.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/creditos/orcamento": {
      "get": {
        "operationId": "orcamento",
        "tags": [
          "Conta e créditos"
        ],
        "summary": "Quanto custa",
        "description": "O preço por XML e o total para N chaves, já com o volume dos últimos 30 dias da conta, e se o saldo cobre.",
        "parameters": [
          {
            "name": "chaves",
            "in": "query",
            "required": true,
            "description": "Quantidade de chaves.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "example": {
                  "chaves": 1200,
                  "volumeRecente": 8400,
                  "precoUnitarioCentavos": 6,
                  "totalCentavos": 7200,
                  "saldoCentavos": 25000,
                  "suficiente": true,
                  "faltamCentavos": 0
                }
              }
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    },
    "/creditos/precos": {
      "get": {
        "operationId": "precos",
        "tags": [
          "Conta e créditos"
        ],
        "summary": "Tabela de preços",
        "description": "As faixas por volume. Pública.",
        "security": [],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/creditos/extrato": {
      "get": {
        "operationId": "extrato",
        "tags": [
          "Conta e créditos"
        ],
        "summary": "Extrato",
        "description": "Recargas, reservas, consumos e devoluções, com o saldo depois de cada um.",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {}
            }
          },
          "401": {
            "description": "Chave de API ausente ou inválida."
          }
        }
      }
    }
  }
}