foxnfe (Python SDK)
Estado consolidado em 11/09/2026: consulte estado canônico e limites. O pacote GTM está preparado, não implantado; Trial/Starter ainda não incluem NFS-e no catálogo vigente. Relatos datados preservam o histórico, sem comprovar o estado atual.
SDK oficial FOX NF-e para Python — emissão NF-e, NFSe, cancelamento, consulta e integração MCP.
Requisitos
- Python 3.9+
- requests
>=2.28
Instalação
pip install foxnfe
# ou
poetry add foxnfe
# ou
uv add foxnfe
Quick Start
from foxnfe import Client
client = Client(tenant_slug="minha-empresa")
# Autenticar
auth = client.login("email@empresa.com", "senha-segura")
print(f"Token: {auth.token}")
# Ou usar token existente
client = Client(tenant_slug="minha-empresa", token="seu-token-aqui")
# Ou via with_token (retorna nova instância)
authed = client.with_token("seu-token-aqui")
NF-e
from foxnfe import Client, NfeEmitRequest
client = Client(tenant_slug="minha-empresa", token="seu-token")
payload = NfeEmitRequest(
ambiente=2, # 2=homologação
certificate_id=1,
tomador={
"cnpj": "12345678000190",
"razao_social": "Empresa Tomadora Ltda",
"endereco": {
"logradouro": "Rua das Flores",
"numero": "100",
"municipio": "São Paulo",
"uf": "SP",
"cep": "01310100",
},
},
itens=[{
"codigo": "SRV001",
"descricao": "Serviço de consultoria",
"cfop": "5933",
"quantidade": 1,
"valor_unitario": 1000.00,
"valor_total": 1000.00,
}],
pagamentos=[{"forma": "01", "valor": 1000.00}],
total=1000.00,
)
result = client.nfe.emit(payload)
print(f"NF-e ID: {result['id']}")
# Aguardar autorização (polling automático)
nfe_autorizada = client.nfe.wait_for_authorization(result["id"])
print(f"Status: {nfe_autorizada.status}") # authorized
# Baixar XML
xml_bytes = client.nfe.xml(result["id"])
with open("nfe.xml", "wb") as f:
f.write(xml_bytes)
# Baixar DANFE PDF
pdf_bytes = client.nfe.pdf(result["id"])
with open("danfe.pdf", "wb") as f:
f.write(pdf_bytes)
# Cancelar
client.nfe.cancel(result["id"], "Cancelamento solicitado pelo cliente")
NFSe
from foxnfe import Client, NfseEmitRequest
client = Client(tenant_slug="minha-empresa", token="seu-token")
payload = NfseEmitRequest(
competencia="2026-09", # AAAA-MM
cnpj_prestador="12345678000190",
inscricao_municipal="123456",
razao_social_prestador="Minha Empresa Ltda", # opcional
descricao_servico="Desenvolvimento de software sob encomenda",
codigo_municipio_prestacao="3550308", # IBGE 7 dígitos
valor_servico=5000.00,
# informe cnae OU o trio abaixo
codigo_tributacao_nacional="01.03.01.00", # formato dd.dd.dd.dd
codigo_tributacao_municipal="0103",
aliquota_iss=2.0,
tomador={"cnpj": "98765432000110", "nome": "Cliente S.A."}, # cnpj OU cpf
prestador={"endereco": {
"logradouro": "Av. Paulista", "numero": "1000", "bairro": "Bela Vista",
"codigo_municipio": "3550308", "uf": "SP", "cep": "01310100",
}},
)
result = client.nfse.emit(payload) # também aceita um dict equivalente
nfse = client.nfse.get(result["nfse_id"]) # 202 {nfse_id, status: pending, message}
print(f"Número NFSe: {nfse.numero_nfse}")
# Consultar por RPS ou chave
client.nfse.consult_by_numero("00000001")
client.nfse.consult_by_chave("SP3550308202605010000000000001")
# Cancelar (justificativa 15..255) / Substituir (motivo 15..255 + campos de emissão)
client.nfse.cancel(result["nfse_id"], "Erro nos dados do tomador")
client.nfse.substitute(result["nfse_id"], payload, "Correção dos dados do tomador")
MCP (Model Context Protocol)
from foxnfe import Client
client = Client(tenant_slug="minha-empresa", token="seu-token")
# Inicializar sessão MCP
info = client.mcp.initialize()
print(f"MCP Server: {info['result']['serverInfo']['name']}")
# Listar tools
tools = client.mcp.list_tools()
for tool in tools:
print(f"{tool.name}: {tool.description}")
# Chamar uma tool
result = client.mcp.call_tool("emitir_nfe", {
"ambiente": 2,
"certificate_id": 1,
})
if result.get("result", {}).get("isError"):
print("Tool error:", result["result"]["content"][0]["text"])
else:
print("Tool result:", result["result"]["content"][0]["text"])
Tratamento de Erros
from foxnfe import Client
from foxnfe.exceptions import ApiException, AuthException, FoxNfeException
try:
client.nfe.emit(payload)
except AuthException as e:
# Token inválido ou expirado (401/403)
print(f"Auth error: {e}")
except ApiException as e:
# Erro da API (422, 500, etc.)
print(f"API error {e.status_code}: {e}")
print(f"Body: {e.response_body}")
except FoxNfeException as e:
# Timeout, erro de conexão, etc.
print(f"SDK error: {e}")
Uso com context manager
from foxnfe import Client
# Client usa requests.Session internamente (pode ser fechado manualmente)
client = Client(tenant_slug="minha-empresa", token="seu-token")
try:
result = client.nfe.emit(payload)
finally:
client._session.close()
Configuração avançada
client = Client(
tenant_slug="minha-empresa",
token="seu-token",
base_url="https://foxnfe.centralfox.online/api/v1", # host legado; padrão: https://www.foxnfe.com.br/api/v1
timeout=60.0,
)
Estrutura do pacote
foxnfe/
├── __init__.py # Exports públicos
├── client.py # Cliente HTTP principal
├── nfe.py # Módulo NF-e
├── nfse.py # Módulo NFSe
├── mcp.py # Módulo MCP
├── types.py # Dataclasses com tipagem
└── exceptions.py # Classes de erro
Links
1.3.0 — eventos, rejeições, homologação, RTC, cobertura NFS-e e suporte
ev = client.nfe_events
ev.ator_interessado(15, "11222333000181") # 110150
ev.insucesso_entrega(15, "2026-09-08T10:00:00-03:00", tp_motivo=1) # 110192
ev.inutilizar(serie=1, numero_inicial=10, numero_final=12, justificativa="Numeração pulada por falha do ERP")
ev.contratos(); ev.registrar_evento(15, "econf", {...}) # eventos por contrato (conciliação financeira, RTC…)
client.nfe.rejeicao("539"); client.nfe.homologacao_run(65) # rejeições explicadas / amostras simuladas
client.nfse.cobertura_municipio("2304400") # driver, operações e provas
client.rtc.verify_resolution("550e8400-e29b-41d4-a716-446655440000")
client.support.create_case("Webhook sem entrega desde ontem", priority="high")
Validação local (ids, dígitos, tamanhos, enums) antes do transporte; regra fiscal fica na API. NfeResource.rejection traz a rejeição classificada.
1.3.3 — licença proprietária
- A partir desta versão o SDK é distribuído sob a Licença de Uso dos SDKs FOX NF-e (arquivo
LICENSE): uso permitido somente com contrato de licença do FOX NF-e em vigor. Sem mudança de API. - As versões 1.3.2 e anteriores foram publicadas sob MIT e permanecem sob essa licença.
1.3.2 — correção do contrato NFS-e e URL base canônica
nfse.emit: corpo alinhado aoEmitNfseRequestda API (competencia,cnpj_prestador,inscricao_municipal,descricao_servico,codigo_municipio_prestacao,valor_servico,tomador,prestador.endereco+ opcionais).ambiente,certificate_ideservicosaíram do tipo — não existem no contrato NFS-e. Campos nulos não são enviados.nfse.cancel: enviajustificativa(15..255, validado antes do envio);motivosegue aceito como alias.nfse.substitute: enviamotivo(15..255) + campos de emissão;motivo_cancelamentosegue aceito como alias e não é enviado. Na substituição a API exigecodigo_tributacao_nacional,codigo_tributacao_municipalealiquota_iss(sem rota porcnae).- Respostas de emit/cancel/substitute são
{nfse_id, message}(202); a consulta usanfse_id. - URL base padrão:
https://www.foxnfe.com.br/api/v1(canônico). O host legadohttps://foxnfe.centralfox.online/api/v1continua respondendo e pode ser passado explicitamente.
Landing e Site IA — SEO 1.1.0 (11/09/2026)
Estado, testes e publicação. FAQ único com cinco perguntas, quatro casos B2B, conteúdo pré-renderizado e equivalente para bots/humanos. Esta atualização não altera contratos fiscais nem billing.
Licença
Software proprietário da Central Fox Tecnologia LTDA. Uso permitido somente com contrato de licença do FOX NF-e em vigor (ou avaliação gratuita vigente). Veja o arquivo LICENSE. Licenciamento: contato@centralfox.online.
Metadata
Release files for foxnfe 1.3.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| foxnfe-1.3.3.tar.gz | 22.0 kB | Without provenance | Details for foxnfe-1.3.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| foxnfe-1.3.3-py3-none-any.whl | Python 3 | none | any | Details for foxnfe-1.3.3-py3-none-any.whl |
Total release size: 46.1 kB
Release files / foxnfe-1.3.3.tar.gz
| Download URL | foxnfe-1.3.3.tar.gz |
|---|---|
| Size | 22.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8ec2eebd1e0d3c9153fcb0a1f40c382c20ed49c9d98baf4d62c57a0250010fc0
|
|
BLAKE2b-256 checksum How to use checksums |
aa9e1bdaf9dc825a1edb8ba23db7008dfc7daaf275b559ae7d5f21d576780672
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / foxnfe-1.3.3-py3-none-any.whl
| Download URL | foxnfe-1.3.3-py3-none-any.whl |
|---|---|
| Size | 24.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3a3d44e56780acb2f9fedf326d3bf8ab56528cf6132d34391ed55d1eb07f075f
|
|
BLAKE2b-256 checksum How to use checksums |
a69e15bf6baca842dd1216598700ccc549e2a07f7bcbb8069423ce7435ef5336
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for foxnfe 1.3.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.