V

VERUS · API de integração

Versão 1

Baixar collection do Postman

Como funciona

O seu sistema chama a API do Verus com a chave da sua conta. O Verus valida os dados, emite a NFS-e na Sefin Nacional usando o certificado digital já cadastrado no Verus e avisa o seu sistema do resultado. O seu sistema não precisa de certificado nem de nenhuma integração com o governo.

  1. No Verus, em Integrações (API), o administrador da conta gera uma chave (e, se quiser, informa o endereço do webhook).
  2. O seu sistema envia POST /api/v1/notas e recebe 202 na hora, com a nota na_fila.
  3. O Verus emite em segundo plano e avisa por webhook: nota.autorizada ou nota.rejeitada (e depois nota.cancelada, se cancelada na tela).
  4. Também dá para consultar a qualquer momento (GET /api/v1/notas/{id}) e baixar o PDF e o XML.

Autenticação

Todas as chamadas levam a chave no cabeçalho. Use sempre HTTPS e guarde a chave como uma senha.

curl https://verusnfe.megasystemsti.com.br/api/v1/conta \
  -H "Authorization: Bearer vrs_SUA_CHAVE" \
  -H "Accept: application/json"

Limite: 120 requisições por minuto por chave. Toda resposta traz um X-Request-Id — informe-o ao suporte se algo der errado.

Emitir uma nota

O serviço precisa estar cadastrado no Verus (a alíquota e os códigos fiscais vêm de lá); informe o servico_codigo ou o servico_id. O tomador é procurado pelo CPF/CNPJ; se não existir, é cadastrado com os dados enviados (um tomador já cadastrado não é alterado pela API). Sem tomador, a nota sai sem tomador identificado. prestador_cnpj só é obrigatório se a conta tiver mais de um prestador.

Requisição

POST /api/v1/notas
{
    "referencia": "pedido-98765",
    "prestador_cnpj": "11222333000181",
    "competencia": "2026-11-10",
    "servico_codigo": "010601",
    "valor": 1500,
    "discriminacao": "Consultoria em TI - novembro/2026",
    "tomador": {
        "cpf_cnpj": "11444777000161",
        "nome": "Cliente Exemplo Ltda",
        "email": "financeiro@clienteexemplo.com.br",
        "endereco": {
            "cep": "74000000",
            "logradouro": "Rua Exemplo",
            "numero": "100",
            "bairro": "Centro",
            "municipio": "Goiânia",
            "uf": "GO",
            "codigo_municipio_ibge": "5208707"
        }
    }
}

Resposta (consulta depois de autorizada)

{"dados": {
    "id": 123,
    "referencia": "pedido-98765",
    "origem": "api",
    "situacao": "autorizada",
    "mensagem": null,
    "prestador": {
        "id": 1,
        "cnpj_cpf": "11222333000181",
        "razao_social": "Sua Empresa Ltda"
    },
    "tomador": {
        "id": 45,
        "cpf_cnpj": "11444777000161",
        "nome": "Cliente Exemplo Ltda"
    },
    "servico": {
        "id": 7,
        "codigo": "010601",
        "nome": "Consultoria em TI"
    },
    "competencia": "2026-11-10",
    "valor": 1500,
    "aliquota_iss": 2,
    "discriminacao": "Consultoria em TI - novembro/2026",
    "serie_dps": "900",
    "numero_dps": 58,
    "numero_nfse": "1024",
    "chave_acesso": "52087071241601316000171000000000102426111234567890",
    "emitida_em": "2026-11-10T14:03:22-03:00",
    "cancelada_em": null,
    "motivo_cancelamento": null,
    "criada_em": "2026-11-10T14:03:20-03:00",
    "atualizada_em": "2026-11-10T14:03:22-03:00",
    "links": {
        "self": "https://verusnfe.megasystemsti.com.br/api/v1/notas/123",
        "pdf": "https://verusnfe.megasystemsti.com.br/api/v1/notas/123/pdf",
        "xml": "https://verusnfe.megasystemsti.com.br/api/v1/notas/123/xml"
    }
}}
Referência = proteção contra nota duplicada. Use em referencia um identificador único do seu sistema (ex.: o número do pedido). Se a rede cair e o seu sistema repetir o envio, o Verus devolve a mesma nota e não emite outra. Só uma nota rejeitada pode ser reenviada com a mesma referência (com os dados corrigidos).

Campos opcionais: competencia (padrão: hoje), discriminacao (padrão: nome do serviço), aliquota_iss (padrão: a do serviço), desconto_incondicionado, informacoes_complementares, retencoes.irrf, retencoes.csll, retencoes.inss, tomador.retem_issqn.

Situações da nota

na_filaRecebida, aguardando a emissão.
processandoEnviada à Sefin, aguardando a resposta. Se a Sefin não responder com clareza, o Verus confirma sozinho em poucos minutos — não envie de novo com outra referência.
autorizadaEmitida. Tem número, chave de acesso, PDF e XML.
rejeitadaRecusada (o motivo vem em "mensagem"). Corrija e reenvie com a mesma referência.
cancelamento_em_andamentoCancelamento pedido, aguardando confirmação.
canceladaCancelada (o cancelamento é feito pela tela do Verus).
importadaNota antiga trazida para o Verus (histórico).

Webhook

Quando a nota termina, o Verus faz um POST no endereço configurado (só HTTPS e endereço público) com o corpo abaixo. Responda com qualquer status 2xx. Se o seu sistema falhar, o Verus tenta de novo em 1 min, 5 min, 15 min, 1 h e 3 h. O mesmo aviso pode chegar mais de uma vez: use entrega_id / o id da nota para ignorar repetições.

POST https://seusistema.com.br/webhooks/verus
X-Verus-Evento: nota.autorizada
X-Verus-Timestamp: 1762790602
X-Verus-Assinatura: sha256=5d0c...

{"evento": "nota.autorizada", "entrega_id": "8f1c...", "enviado_em": "2026-11-10T14:03:23-03:00", "dados": { ...mesma nota da consulta... }}

Confira a assinatura antes de confiar no aviso: calcule HMAC-SHA256(segredo_do_webhook, X-Verus-Timestamp + "." + corpo_bruto) em hexadecimal e compare com o valor depois de sha256=. Recuse avisos com timestamp de mais de 5 minutos.

// PHP
$esperado = hash_hmac('sha256', $_SERVER['HTTP_X_VERUS_TIMESTAMP'].'.'.file_get_contents('php://input'), $segredo);
$valido = hash_equals('sha256='.$esperado, $_SERVER['HTTP_X_VERUS_ASSINATURA']);

// Node.js
const esperado = crypto.createHmac('sha256', segredo).update(req.headers['x-verus-timestamp'] + '.' + corpoBruto).digest('hex');
const valido = crypto.timingSafeEqual(Buffer.from('sha256=' + esperado), Buffer.from(req.headers['x-verus-assinatura']));

Erros

Todo erro vem no mesmo formato. O codigo é estável (use-o no seu sistema); a mensagem é para pessoas.

{"erro": {"codigo": "dados_invalidos", "mensagem": "Alguns dados enviados não são válidos.", "campos": {"valor": ["O campo valor é obrigatório."]}}}
401chave_ausente / chave_invalida / chave_revogadaProblema com a chave.
403plano_sem_api / conta_inativaA conta não pode usar a API.
404nao_encontradoRegistro inexistente nesta conta.
409nota_sem_arquivoPDF/XML ainda não disponível.
422dados_invalidos / limite_do_plano / certificado_ausente / certificado_vencido / sem_prestadorDados ou situação da conta impedem a emissão.
429limite_de_requisicoesMuitas chamadas; veja o cabeçalho Retry-After.
502falha_sefinA Sefin não respondeu ao buscar PDF/XML; tente de novo.

Endpoints

Conta

GET /api/v1/conta — Dados da conta

Conta da chave, plano e consumo da cota de notas. Bom para testar se a chave funciona.

Notas

POST /api/v1/notas — Emitir nota

Valida, grava e responde 202 na hora com a nota "na_fila". A emissão na Sefin acontece em segundo plano; o resultado chega pelo webhook e pela consulta. Repetir a mesma "referencia" devolve a nota já existente (200, cabeçalho X-Verus-Ja-Recebida) e nunca emite outra. Se a nota daquela referência foi rejeitada, o novo envio corrige os dados e tenta de novo.

GET /api/v1/notas — Listar notas

Notas da conta, mais recentes primeiro, 50 por página (máx. 100).

  • situacao — na_fila, processando, autorizada, rejeitada, cancelamento_em_andamento, cancelada, importada
  • prestador_id — id do prestador
  • competencia_de — AAAA-MM-DD
  • competencia_ate — AAAA-MM-DD
  • atualizadas_desde — data/hora ISO 8601 — para sincronizar só o que mudou
  • origem — api ou sistema
  • pagina — número da página
  • por_pagina — 1 a 100

GET /api/v1/notas/{id} — Consultar nota

Situação e dados de uma nota.

GET /api/v1/notas/referencia/{referencia} — Consultar pela referência

A mesma consulta, usando a referência do seu sistema.

GET /api/v1/notas/{id}/pdf — Baixar PDF (DANFSe)

Arquivo PDF. Disponível para notas autorizadas, canceladas ou importadas (senão: 409 nota_sem_arquivo).

GET /api/v1/notas/{id}/xml — Baixar XML

XML oficial da NFS-e.

Cadastros

GET /api/v1/prestadores — Listar prestadores

Empresas prestadoras da conta, com o resumo do certificado.

GET /api/v1/prestadores/{id} — Consultar prestador

Um prestador.

GET /api/v1/certificados — Certificados digitais

Situação do certificado de cada prestador: valido, vencendo (30 dias), vencido ou ausente. Nunca devolve o arquivo nem a senha.

GET /api/v1/tomadores — Listar tomadores

Clientes (tomadores) cadastrados, 50 por página.

  • cpf_cnpj — filtra por documento
  • prestador_id — id do prestador
  • busca — parte do nome
  • pagina — número da página
  • por_pagina — 1 a 100

GET /api/v1/tomadores/{id} — Consultar tomador

Um tomador.

GET /api/v1/servicos — Listar serviços

Catálogo de serviços. O "codigo" (ou o código de tributação nacional) é o que se usa em servico_codigo na emissão.

  • prestador_id — id do prestador
  • codigo — código do serviço

GET /api/v1/servicos/{id} — Consultar serviço

Um serviço.

Listas paginadas devolvem {"dados": [...], "paginacao": {"pagina", "por_pagina", "total", "ultima_pagina"}}; consultas de um registro devolvem {"dados": {...}}.

Testes

Para integrar sem emitir nota de verdade, use uma empresa prestadora configurada em homologação no Verus. Notas de homologação seguem o mesmo fluxo, mas não têm valor fiscal.