Notas fiscais de serviço (service_invoices)
client.service_invoices cobre a NFS-e da API v1,
servida por https://api.nfe.io com a api_key. Todos os métodos recebem o company_id da empresa
emissora como primeiro argumento.
Métodos
service_invoices.create(company_id, params, *, external_id=None, options=None) -> ServiceInvoice
service_invoices.create_and_wait(company_id, params, *, external_id=None, timeout=120.0, ...) -> ServiceInvoice
service_invoices.retrieve(company_id, invoice_id, *, options=None) -> ServiceInvoice
service_invoices.list(company_id, *, page_index=1, page_count=10, issued_begin=None, issued_end=None,
created_begin=None, created_end=None, options=None) -> OffsetPage[ServiceInvoice]
service_invoices.find_by_external_id(company_id, external_id, *, wait=0.0, options=None) -> ServiceInvoice | None
service_invoices.wait(company_id, invoice_id, *, timeout=120.0, ...) -> ServiceInvoice
service_invoices.cancel(company_id, invoice_id, *, options=None) -> ServiceInvoice
service_invoices.cancel_and_wait(company_id, invoice_id, *, timeout=120.0, ...) -> ServiceInvoice
service_invoices.send_email(company_id, invoice_id, *, options=None) -> None
service_invoices.download_pdf(company_id, invoice_id, *, options=None) -> bytes
service_invoices.download_xml(company_id, invoice_id, *, options=None) -> bytes
service_invoices.download_cancellation_xml(company_id, invoice_id, *, options=None) -> bytes
Os parâmetros de espera (timeout, initial_interval, max_interval, backoff,
not_found_grace, raise_on_failure) estão em
Síncrono, assíncrono e polling.
Emitir
from decimal import Decimal
from nfeio import NfeClient
from nfeio.types import ServiceInvoiceCreateParams
client = NfeClient()
company_id = "ID_DA_EMPRESA"
params: ServiceInvoiceCreateParams = {
"cityServiceCode": "10677",
"description": "Manutenção e suporte técnico",
"servicesAmount": Decimal("250.00"),
"borrower": {
"type": "LegalEntity",
"name": "Cliente Exemplo Ltda",
"federalTaxNumber": "11222333000181",
"email": "[email protected]",
"address": {
"country": "BRA",
"postalCode": "80010000",
"street": "Rua Exemplo",
"number": "100",
"district": "Centro",
"city": {"code": "4106902", "name": "Curitiba"},
"state": "PR",
},
},
}
invoice = client.service_invoices.create_and_wait(company_id, params, external_id="pedido-5001")
print(invoice.id, invoice.flow_status, invoice["number"])
- O corpo usa as chaves da API.
ServiceInvoiceCreateParamslista os campos conhecidos para o seu editor e para o mypy; campos fora dele também são enviados como estão. external_idé enviado comoexternalId. Passe pelo argumento, não dentro deparams: se os dois vierem e forem diferentes, o SDK recusa comInvalidParameterError.createdevolve a nota aceita (em geral comflow_statusintermediário) e nunca é repetido depois que o pedido pode ter chegado à API. Veja Tratamento de erros.- Para a NFS-e no layout da Reforma Tributária, acrescente
ibsCbsenbsCode: veja Emissão RTC.
Consultar
from nfeio import NfeClient
client = NfeClient()
invoice = client.service_invoices.retrieve("ID_DA_EMPRESA", "ID_DA_NOTA")
print(invoice.flow_status, invoice.flow_message)
print(invoice.services_amount, invoice.iss_tax_amount, invoice.amount_net) # Decimal
print(invoice.issued_on) # datetime com fuso
if invoice.borrower is not None:
print(invoice.borrower.federal_tax_number) # str com zeros à esquerda
print(invoice["rpsNumber"], invoice["checkCode"]) # qualquer campo pelo nome do JSON
Propriedades tipadas de ServiceInvoice: id, external_id, environment, flow_status,
flow_message, status, services_amount, base_tax_amount, deductions_amount, iss_rate,
iss_tax_amount, amount_net, issued_on, cancelled_on, created_on, modified_on, borrower
e provider (com id e federal_tax_number). O resto fica no acesso por chave.
Buscar por external_id
from nfeio import NfeClient
client = NfeClient()
invoice = client.service_invoices.find_by_external_id("ID_DA_EMPRESA", "pedido-5001", wait=30)
if invoice is None:
print("nenhuma nota com esse external_id")
else:
print(invoice.id, invoice.flow_status)
Devolve a nota ou None. Com wait, repete a busca com backoff por até wait segundos, o que
cobre o atraso de indexação logo após a emissão. É a base da
receita de reconciliação.
Listar
from nfeio import NfeClient
client = NfeClient()
page = client.service_invoices.list("ID_DA_EMPRESA", page_count=50, issued_begin="2026-09-01")
for invoice in page.auto_paging_iter():
print(invoice.id, invoice.flow_status, invoice.issued_on)
page_index começa em 1 e page_count vai de 1 a 50. Mais em Paginação.
Cancelar
from nfeio import InvoiceProcessingError, NfeClient
client = NfeClient()
try:
invoice = client.service_invoices.cancel_and_wait("ID_DA_EMPRESA", "ID_DA_NOTA")
print(invoice.flow_status) # "Cancelled"
except InvoiceProcessingError as erro:
print("cancelamento recusado:", erro.flow_status, erro.flow_message)
cancel só pede o cancelamento e devolve a nota no estado intermediário (como
WaitingSendCancel). cancel_and_wait espera Cancelled.
Reenviar por e-mail e baixar
from pathlib import Path
from nfeio import NfeClient
client = NfeClient()
company_id = "ID_DA_EMPRESA"
invoice_id = "ID_DA_NOTA"
client.service_invoices.send_email(company_id, invoice_id)
Path("nota.pdf").write_bytes(client.service_invoices.download_pdf(company_id, invoice_id))
Path("nota.xml").write_bytes(client.service_invoices.download_xml(company_id, invoice_id))
Detalhes do redirecionamento e do XML de cancelamento em Downloads.
Veja também
- Emissão RTC:
ibsCbsenbsCode. - Webhooks: o resultado da emissão por push.
- Referência da API de NFS-e v1.