Official NFE.io SDK for Node.js 18+ - Modern TypeScript SDK for issuing Brazilian service invoices (NFS-e).
β¨ Version 3.0 - Complete rewrite with TypeScript, zero runtime dependencies, and modern async/await API.
- Features
- Installation
- Quick Start
- Documentation
- Migration from v2
- Examples
- API Reference
- Contributing
- License
- π― Modern TypeScript - Full type safety with TypeScript 5.3+
- π Zero Dependencies - Uses native Node.js fetch API (Node 18+)
- β‘ Async/Await - Clean promise-based API
- π Auto Retry - Built-in exponential backoff retry logic
- π¦ ESM & CommonJS - Works with both module systems
- π§ͺ Well Tested - 80+ tests with 88% coverage
- π Full JSDoc - Complete API documentation
- π‘οΈ Error Handling - Typed error classes for better error handling
Requirements:
- Node.js >= 18.0.0
- TypeScript >= 5.0 (if using TypeScript)
npm install @nfe-io/sdkor
yarn add @nfe-io/sdkor
pnpm add @nfe-io/sdkimport { NfeClient } from '@nfe-io/sdk';
// Initialize the client
const nfe = new NfeClient({
apiKey: 'your-api-key',
environment: 'production' // or 'development'
});
// Create a company
const company = await nfe.companies.create({
federalTaxNumber: '12345678000190',
name: 'My Company Ltd',
email: 'company@example.com',
taxRegime: 1, // Simples Nacional
address: {
country: 'BRA',
postalCode: '01310-100',
street: 'Av. Paulista',
number: '1578',
city: { code: '3550308', name: 'SΓ£o Paulo' },
state: 'SP'
}
});
// Issue a service invoice
const invoice = await nfe.serviceInvoices.create(company.id, {
cityServiceCode: '01234',
description: 'Web development services',
servicesAmount: 1000.00,
borrower: {
type: 'LegalEntity',
federalTaxNumber: 12345678000190,
name: 'Client Company',
email: 'client@example.com',
address: {
country: 'BRA',
postalCode: '01310-100',
street: 'Av. Paulista',
number: '1000',
city: { code: '3550308', name: 'SΓ£o Paulo' },
state: 'SP'
}
}
});
console.log(`Invoice created: ${invoice.number}`);const { NfeClient } = require('@nfe-io/sdk');
const nfe = new NfeClient({
apiKey: process.env.NFE_API_KEY,
environment: 'production'
});
// Same API as ESMThe SDK provides the following resources:
Manage NFS-e (Nota Fiscal de ServiΓ§o EletrΓ΄nica):
// Create invoice (returns immediately or async 202)
const invoice = await nfe.serviceInvoices.create(companyId, invoiceData);
// Create and wait for completion (handles async processing)
const invoice = await nfe.serviceInvoices.createAndWait(companyId, invoiceData, {
maxAttempts: 30,
intervalMs: 2000
});
// List invoices with pagination
const result = await nfe.serviceInvoices.list(companyId, {
page: 1,
pageSize: 50
});
// Retrieve specific invoice
const invoice = await nfe.serviceInvoices.retrieve(companyId, invoiceId);
// Cancel invoice
const cancelledInvoice = await nfe.serviceInvoices.cancel(companyId, invoiceId);
// Send invoice by email
await nfe.serviceInvoices.sendEmail(companyId, invoiceId);
// Download PDF
const pdfBuffer = await nfe.serviceInvoices.downloadPdf(companyId, invoiceId);
// Download XML
const xmlData = await nfe.serviceInvoices.downloadXml(companyId, invoiceId);Manage companies in your account:
// Create company
const company = await nfe.companies.create({
federalTaxNumber: '12345678000190',
name: 'Company Name',
// ... other fields
});
// List all companies
const companies = await nfe.companies.list();
// Get specific company
const company = await nfe.companies.retrieve(companyId);
// Update company
const updated = await nfe.companies.update(companyId, {
email: 'newemail@company.com'
});
// Upload digital certificate
await nfe.companies.uploadCertificate(companyId, {
file: certificateBuffer,
password: 'cert-password'
});Manage legal entities (companies/businesses):
// Create legal person
const person = await nfe.legalPeople.create(companyId, {
federalTaxNumber: '12345678000190',
name: 'Business Name',
email: 'business@example.com',
address: { /* ... */ }
});
// List all legal people
const people = await nfe.legalPeople.list(companyId);
// Find by tax number
const person = await nfe.legalPeople.findByTaxNumber(companyId, '12345678000190');Manage natural persons (individuals):
// Create natural person
const person = await nfe.naturalPeople.create(companyId, {
federalTaxNumber: 12345678901,
name: 'John Doe',
email: 'john@example.com',
address: { /* ... */ }
});
// Find by CPF
const person = await nfe.naturalPeople.findByTaxNumber(companyId, '12345678901');Manage webhook configurations:
// Create webhook
const webhook = await nfe.webhooks.create(companyId, {
url: 'https://myapp.com/webhooks/nfe',
events: ['invoice.issued', 'invoice.cancelled'],
active: true
});
// List webhooks
const webhooks = await nfe.webhooks.list(companyId);
// Update webhook
await nfe.webhooks.update(companyId, webhookId, {
events: ['invoice.issued']
});
// Validate webhook signature
const isValid = nfe.webhooks.validateSignature(
payload,
signature,
secret
);const nfe = new NfeClient({
// Required: Your NFE.io API key
apiKey: 'your-api-key',
// Optional: Environment (default: 'production')
environment: 'production', // or 'sandbox'
// Optional: Custom base URL (overrides environment)
baseUrl: 'https://custom-api.nfe.io/v1',
// Optional: Request timeout in milliseconds (default: 30000)
timeout: 60000,
// Optional: Retry configuration
retryConfig: {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 10000,
backoffMultiplier: 2
}
});The SDK provides typed error classes:
import {
NfeError,
AuthenticationError,
ValidationError,
NotFoundError,
RateLimitError
} from '@nfe-io/sdk';
try {
const invoice = await nfe.serviceInvoices.create(companyId, data);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key:', error.message);
} else if (error instanceof ValidationError) {
console.error('Invalid data:', error.details);
} else if (error instanceof NotFoundError) {
console.error('Resource not found:', error.message);
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded, retry after:', error.retryAfter);
} else if (error instanceof NfeError) {
console.error('API error:', error.code, error.message);
} else {
console.error('Unexpected error:', error);
}
}See MIGRATION.md for a complete migration guide.
Key Changes:
// v2 (callbacks + promises)
var nfe = require('nfe-io')('api-key');
nfe.serviceInvoices.create('company-id', data, function(err, invoice) {
if (err) return console.error(err);
console.log(invoice);
});
// v3 (async/await + TypeScript)
import { NfeClient } from '@nfe-io/sdk';
const nfe = new NfeClient({ apiKey: 'api-key' });
try {
const invoice = await nfe.serviceInvoices.create('company-id', data);
console.log(invoice);
} catch (error) {
console.error(error);
}import { NfeClient } from '@nfe-io/sdk';
const nfe = new NfeClient({
apiKey: process.env.NFE_API_KEY!,
environment: 'production'
});
async function issueInvoice() {
// 1. Get or create company
const companies = await nfe.companies.list();
const company = companies.data[0];
// 2. Create invoice with automatic polling
const invoice = await nfe.serviceInvoices.createAndWait(company.id, {
cityServiceCode: '01234',
description: 'Consultoria em TI',
servicesAmount: 5000.00,
borrower: {
type: 'LegalEntity',
federalTaxNumber: 12345678000190,
name: 'Cliente Exemplo Ltda',
email: 'contato@cliente.com.br',
address: {
country: 'BRA',
postalCode: '01310-100',
street: 'Av. Paulista',
number: '1000',
city: { code: '3550308', name: 'SΓ£o Paulo' },
state: 'SP'
}
}
}, {
maxAttempts: 30,
intervalMs: 2000
});
console.log(`β
Invoice issued: ${invoice.number}`);
// 3. Send by email
await nfe.serviceInvoices.sendEmail(company.id, invoice.id);
console.log('π§ Email sent');
// 4. Download PDF
const pdf = await nfe.serviceInvoices.downloadPdf(company.id, invoice.id);
await fs.promises.writeFile(`invoice-${invoice.number}.pdf`, pdf);
console.log('πΎ PDF saved');
}
issueInvoice().catch(console.error);// Setup webhook to receive invoice events
const webhook = await nfe.webhooks.create(companyId, {
url: 'https://myapp.com/api/webhooks/nfe',
events: [
'invoice.issued',
'invoice.cancelled',
'invoice.error'
],
active: true
});
// In your webhook endpoint
app.post('/api/webhooks/nfe', (req, res) => {
const signature = req.headers['x-nfe-signature'];
const isValid = nfe.webhooks.validateSignature(
req.body,
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
if (event === 'invoice.issued') {
console.log('Invoice issued:', data.id);
}
res.status(200).send('OK');
});async function issueBatchInvoices(companyId: string, invoices: InvoiceData[]) {
const results = await Promise.allSettled(
invoices.map(data =>
nfe.serviceInvoices.createAndWait(companyId, data)
)
);
const succeeded = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
console.log(`β
${succeeded.length} invoices issued`);
console.log(`β ${failed.length} invoices failed`);
return { succeeded, failed };
}Full API documentation is available at:
- TypeDoc Documentation (coming soon)
- Official API Docs
- REST API Reference
# Run all tests (unit + integration)
npm test
# Run only unit tests
npm run test:unit
# Run only integration tests (requires API key)
npm run test:integration
# Run with coverage
npm run test:coverage
# Run with UI
npm run test:uiIntegration tests validate against the real NFE.io API:
# Set your development/test API key
export NFE_API_KEY="your-development-api-key"
export NFE_TEST_ENVIRONMENT="development"
export RUN_INTEGRATION_TESTS="true"
# Run integration tests
npm run test:integrationSee tests/integration/README.md for detailed documentation.
Note: Integration tests make real API calls and may incur costs depending on your plan.
npm run typechecknpm run buildContributions are welcome! Please see CONTRIBUTING.md for guidelines.
The SDK is designed to be extensible. Official extensions:
- @nfe-io/mcp-server - Model Context Protocol server for LLM integration
- @nfe-io/n8n-nodes - n8n workflow automation nodes
MIT Β© NFE.io
- π§ Email: suporte@nfe.io
- π Documentation: https://nfe.io/docs/
- π Issues: https://github.com/nfe/client-nodejs/issues
- OpenAPI spec validation
- Rate limiting helpers
- Pagination helpers
- Request/response interceptors
- Custom retry strategies
- Browser support (via bundlers)
Made with β€οΈ by the NFE.io team