Frenty - API de Nota Fiscal de Serviço Eletrônica (NFS-e)

Documento de referência apenas para o módulo de NFS-e da Frenty. Qualquer exemplo de CNPJ, e-mail, chaves ou números é fictício e serve somente para teste.

1. Visão Geral

A API de NFS-e da Frenty permite emitir, consultar, cancelar, substituir e buscar notas fiscais de serviço eletrônicas em prefeituras integradas.

Todas as requisições devem ser feitas utilizando protocolo HTTPS, com envio de JSON codificado em UTF-8.

Ambientes

Contato

2. Autenticação

A autenticação é feita por token (Bearer). Cada emitente Frenty possui um token próprio, gerado no cadastro do emitente.

2.1. Gerar novo token do emitente

GET /emitentes/{cnpj}/token

Resposta de exemplo:

{
  "sucesso": true,
  "token": "FR-123e4567-e89b-12d3-a456-426614174000",
  "expira_em": "2026-01-01T00:00:00-03:00"
}

Nas demais chamadas, informe o token no cabeçalho: Authorization: Bearer <token>

2.2. Token Dev

Além do token do cliente (emitente), existe também o token dev. O token dev deve ser enviado em todos os casos onde o desenvolvedor possui permissão para enviar dados em nome do cliente.

Quando utilizar o token dev, informe-o no cabeçalho adicional: X-Dev-Token: <token_dev>

Importante: O token dev deve ser enviado junto com o token do cliente em todas as requisições onde o desenvolvedor tem permissão de operar em nome do cliente.

3. Fluxo de emissão (assíncrono)

O processo de emissão de NFS-e na Frenty é assíncrono e utiliza duas etapas principais:

  1. Envio do RPS via POST /nfse (individual) ou POST /nfse/lote (até 100 notas por chamada).
  2. Consulta do resultado via GET /nfse/{chave}, ou recebimento automático pelo webhook.

Em cidades que suportam emissão nacional/MEI, o comportamento é o mesmo, sendo controlado pelo cadastro do emitente.

4. Endpoints NFS-e

4.1. Envio de NFS-e

POST /nfse

Envia os dados do RPS para geração da NFS-e na prefeitura. Campos que não existirem no layout da cidade serão ignorados, sem causar erro.

Request de exemplo:

POST /nfse
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "emitente": {
    "cnpj": "12345678000199",
    "inscricao_municipal": "123456",
    "razao_social": "Frenty Tecnologia LTDA"
  },
  "tomador": {
    "cpf_cnpj": "98765432000111",
    "razao_social": "Cliente de Teste Frenty",
    "email": "financeiro+teste@frenty.com.br",
    "endereco": {
      "logradouro": "Rua Exemplo",
      "numero": "100",
      "bairro": "Centro",
      "codigo_municipio": "3543402",
      "uf": "SP",
      "cep": "14000000"
    }
  },
  "servico": {
    "codigo_tributacao_municipio": "101",
    "codigo_tributacao_nacional": "140200",
    "descricao": "Serviços de consultoria em tecnologia",
    "aliquota": 0.02,
    "valor_servicos": 1000.00,
    "iss_retido": false
  },
  "rps": {
    "numero": 12345,
    "serie": "A1",
    "tipo": 1
  }
}

Resposta de exemplo (lote em processamento):

{
  "sucesso": true,
  "codigo": 5023,
  "mensagem": "Lote em processamento, consulte novamente em alguns segundos.",
  "chave": "35140812345678000199650010000012341000012345"
}

4.2. Envio em lote

POST /nfse/lote

Permite enviar múltiplas NFS-e em uma única requisição. É permitido enviar até 100 notas por chamada. O processamento é assíncrono, assim como no envio individual.

Request de exemplo (3 notas):

POST /nfse/lote
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "notas": [
    {
      "emitente": {
        "cnpj": "12345678000199",
        "inscricao_municipal": "123456",
        "razao_social": "Frenty Tecnologia LTDA"
      },
      "tomador": {
        "cpf_cnpj": "98765432000111",
        "razao_social": "Cliente de Teste Frenty",
        "email": "financeiro+teste@frenty.com.br",
        "endereco": {
          "logradouro": "Rua Exemplo",
          "numero": "100",
          "bairro": "Centro",
          "codigo_municipio": "3543402",
          "uf": "SP",
          "cep": "14000000"
        }
      },
      "servico": {
        "codigo_tributacao_municipio": "101",
        "codigo_tributacao_nacional": "140200",
        "descricao": "Serviços de consultoria em tecnologia",
        "aliquota": 0.02,
        "valor_servicos": 1000.00,
        "iss_retido": false
      },
      "rps": {
        "numero": 12345,
        "serie": "A1",
        "tipo": 1
      }
    },
    {
      "emitente": {
        "cnpj": "12345678000199",
        "inscricao_municipal": "123456",
        "razao_social": "Frenty Tecnologia LTDA"
      },
      "tomador": {
        "cpf_cnpj": "11122233000144",
        "razao_social": "Empresa Exemplo LTDA",
        "email": "contato@exemplo.com.br",
        "endereco": {
          "logradouro": "Avenida Principal",
          "numero": "500",
          "bairro": "Jardim das Flores",
          "codigo_municipio": "3550308",
          "uf": "SP",
          "cep": "01310100"
        }
      },
      "servico": {
        "codigo_tributacao_municipio": "101",
        "codigo_tributacao_nacional": "140200",
        "descricao": "Desenvolvimento de software",
        "aliquota": 0.02,
        "valor_servicos": 2500.00,
        "iss_retido": false
      },
      "rps": {
        "numero": 12346,
        "serie": "A1",
        "tipo": 1
      }
    },
    {
      "emitente": {
        "cnpj": "12345678000199",
        "inscricao_municipal": "123456",
        "razao_social": "Frenty Tecnologia LTDA"
      },
      "tomador": {
        "cpf_cnpj": "55566677000188",
        "razao_social": "Serviços Digitais ME",
        "email": "financeiro@servicosdigitais.com.br",
        "endereco": {
          "logradouro": "Rua Comercial",
          "numero": "200",
          "bairro": "Centro Empresarial",
          "codigo_municipio": "3509502",
          "uf": "SP",
          "cep": "13020000"
        }
      },
      "servico": {
        "codigo_tributacao_municipio": "101",
        "codigo_tributacao_nacional": "140200",
        "descricao": "Suporte técnico especializado",
        "aliquota": 0.02,
        "valor_servicos": 800.00,
        "iss_retido": false
      },
      "rps": {
        "numero": 12347,
        "serie": "A1",
        "tipo": 1
      }
    }
  ]
}

Resposta de exemplo (lote em processamento):

{
  "sucesso": true,
  "codigo": 5023,
  "mensagem": "Lote em processamento, consulte novamente em alguns segundos.",
  "lote_id": "LOTE-20251201-001",
  "chaves": [
    "35140812345678000199650010000012341000012345",
    "35140812345678000199650010000012341000012346",
    "35140812345678000199650010000012341000012347"
  ]
}

Após o envio do lote, consulte cada nota individualmente através de GET /nfse/{chave} ou aguarde as notificações via webhook.

4.3. Consulta por chave

GET /nfse/{chave}

Retorna o resultado do processamento de uma NFS-e enviada anteriormente.

Request de exemplo:

GET /nfse/35140812345678000199650010000012341000012345
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...

Resposta de exemplo (autorizada):

{
  "sucesso": true,
  "codigo": 100,
  "mensagem": "Uso da NFS-e autorizado",
  "status": "Autorizado",
  "numero": "80015",
  "rps_numero": "12345",
  "rps_serie": "A1",
  "chave": "35140812345678000199650010000012341000012345",
  "codigo_verificacao": "FR-82B2",
  "data_hora_evento": "2025-12-01 11:25:22",
  "xml": "...BASE64 DO XML...",
  "pdf": "...BASE64 DO PDF...",
  "link_pdf": "https://nota.prefeitura.exemplo.gov.br/visualizar?nf=80015"
}

4.4. Cancelamento

POST /nfse/cancela

Solicita o cancelamento de uma NFS-e já autorizada, de acordo com as regras da prefeitura.

POST /nfse/cancela
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "chave": "35140812345678000199650010000012341000012345",
  "motivo": "Cancelamento de teste - Frenty"
}

4.5. Substituição de NFS-e

POST /nfse/substitui

Em municípios que suportam substituição, permite cancelar uma NFS-e e gerar outra vinculada à anterior.

Request de exemplo:

POST /nfse/substitui
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "chave_original": "35140812345678000199650010000012341000012345",
  "motivo": "Substituição de teste - Frenty",
  "emitente": { ... },
  "tomador": { ... },
  "servico": { ... },
  "rps": { ... }
}

4.6. Impressão (DANFSe / Preview)

GET /nfse/{chave}/pdf

Retorna o PDF da nota em Base64.

Request de exemplo:

GET /nfse/35140812345678000199650010000012341000012345/pdf
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
POST /nfse/preview

Gera um PDF de pré-visualização com base nos dados do RPS, sem envio à prefeitura.

Request de exemplo:

POST /nfse/preview
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "emitente": { ... },
  "tomador": { ... },
  "servico": { ... },
  "rps": { ... }
}

4.7. Busca de NFS-e

POST /nfse/busca

Permite localizar NFS-e emitidas para um emitente, filtrando por período, número, tomador, status, etc.

Request de exemplo:

POST /nfse/busca
Authorization: Bearer FR-123...
X-Dev-Token: DEV-9876543210abcdef...
Content-Type: application/json

{
  "cnpj_emitente": "12345678000199",
  "data_inicial": "2025-12-01",
  "data_final": "2025-12-31",
  "status": "Autorizado"
}

5. Webhooks

A Frenty pode notificar automaticamente o seu sistema sempre que uma NFS-e mudar de status. Configure a URL de webhook no cadastro do emitente.

5.1. Exemplo de payload

POST https://suaaplicacao.frenty.com.br/webhook/nfse

{
  "tipo": "nfse",
  "evento": "autorizada",
  "chave": "35140812345678000199650010000012341000012345",
  "numero": "80015",
  "status": "Autorizado",
  "xml": "...BASE64...",
  "pdf": "...BASE64..."
}

Caso o webhook esteja configurado, a segunda consulta (via GET /nfse/{chave}) torna-se opcional.

6. Códigos de retorno principais

A lista completa de erros da Frenty é disponibilizada em endpoint próprio de consulta de códigos.