Skip to main content

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

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

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 ao EmitNfseRequest da API (competencia, cnpj_prestador, inscricao_municipal, descricao_servico, codigo_municipio_prestacao, valor_servico, tomador, prestador.endereco + opcionais). ambiente, certificate_id e servico saíram do tipo — não existem no contrato NFS-e. Campos nulos não são enviados.
  • nfse.cancel: envia justificativa (15..255, validado antes do envio); motivo segue aceito como alias.
  • nfse.substitute: envia motivo (15..255) + campos de emissão; motivo_cancelamento segue aceito como alias e não é enviado. Na substituição a API exige codigo_tributacao_nacional, codigo_tributacao_municipal e aliquota_iss (sem rota por cnae).
  • Respostas de emit/cancel/substitute são {nfse_id, message} (202); a consulta usa nfse_id.
  • URL base padrão: https://www.foxnfe.com.br/api/v1 (canônico). O host legado https://foxnfe.centralfox.online/api/v1 continua 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.

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)

Source distribution for foxnfe 1.3.3
File Size Uploaded
foxnfe-1.3.3.tar.gz 22.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for foxnfe 1.3.3
File Interpreter ABI Platform
foxnfe-1.3.3-py3-none-any.whl Python 3 none any Details

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

Release history Release notifications | RSS feed

This release

1.3.3 This release

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page