Skip to content

Node.js Examples

All examples use the native fetch API available in Node.js 18+. No external dependencies required.

const API_BASE = 'https://api.suit.pe';
const API_KEY = 'sk_live_YOUR_API_KEY';
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
};
async function emitInvoice() {
const response = await fetch(`${API_BASE}/api/invoices`, {
method: 'POST',
headers,
body: JSON.stringify({
series: 'F001',
correlative: 1,
issueDate: '2026-02-20',
dueDate: '2026-03-20',
currencyCode: 'PEN',
customer: {
identityType: '6',
identityNumber: '20100047218',
name: 'Empresa Cliente SAC',
address: 'Av. Javier Prado 1234, San Isidro'
},
items: [
{
code: 'SRV-001',
description: 'Servicio de consultoria',
quantity: 1,
unitCode: 'ZZ',
unitPrice: 1000.00,
igvType: '10'
}
]
})
});
const result = await response.json();
console.log('Invoice:', result);
// { id: "cm3abc123", status: "ACCEPTED", documentId: "20123456789-01-F001-00000001" }
return result;
}
async function emitReceipt() {
const response = await fetch(`${API_BASE}/api/receipts`, {
method: 'POST',
headers,
body: JSON.stringify({
series: 'B001',
correlative: 1,
issueDate: '2026-02-20',
currencyCode: 'PEN',
customer: {
identityType: '1',
identityNumber: '12345678',
name: 'Juan Perez'
},
items: [
{
code: 'SRV-002',
description: 'Corte de cabello premium',
quantity: 1,
unitCode: 'ZZ',
unitPrice: 50.00,
igvType: '10'
}
]
})
});
return await response.json();
}
async function emitCreditNote() {
const response = await fetch(`${API_BASE}/api/credit-notes`, {
method: 'POST',
headers,
body: JSON.stringify({
series: 'F001',
correlative: 1,
issueDate: '2026-02-21',
currencyCode: 'PEN',
referenceDocumentId: 'F001-00000001',
referenceDocumentType: '01',
responseCode: '01',
responseDescription: 'Anulacion de la operacion',
customer: {
identityType: '6',
identityNumber: '20100047218',
name: 'Empresa Cliente SAC'
},
items: [
{
code: 'SRV-001',
description: 'Servicio de consultoria (anulacion)',
quantity: 1,
unitCode: 'ZZ',
unitPrice: 1000.00,
igvType: '10'
}
]
})
});
return await response.json();
}
async function emitDebitNote() {
const response = await fetch(`${API_BASE}/api/debit-notes`, {
method: 'POST',
headers,
body: JSON.stringify({
series: 'F001',
correlative: 1,
issueDate: '2026-02-21',
currencyCode: 'PEN',
referenceDocumentId: 'F001-00000001',
referenceDocumentType: '01',
responseCode: '01',
responseDescription: 'Intereses por mora',
customer: {
identityType: '6',
identityNumber: '20100047218',
name: 'Empresa Cliente SAC'
},
items: [
{
code: 'INT-001',
description: 'Intereses moratorios - Febrero 2026',
quantity: 1,
unitCode: 'ZZ',
unitPrice: 150.00,
igvType: '10'
}
]
})
});
return await response.json();
}

Send a Comunicacion de Baja (Voided Document)

Section titled “Send a Comunicacion de Baja (Voided Document)”
async function sendVoidedDocument() {
// Step 1: Send the voided document
const response = await fetch(`${API_BASE}/api/voided-documents`, {
method: 'POST',
headers,
body: JSON.stringify({
issueDate: '2026-02-20',
referenceDate: '2026-02-19',
correlative: 1,
items: [
{
series: 'F001',
correlative: 1,
documentType: '01',
reason: 'Error en datos del cliente'
}
]
})
});
const result = await response.json();
console.log('Ticket:', result.ticket);
// Step 2: Poll for the result
const finalResult = await checkTicket(result.id);
console.log('Final status:', finalResult.status);
return finalResult;
}
async function checkTicket(documentId, maxAttempts = 12) {
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(
`${API_BASE}/api/documents/${documentId}/check-ticket`,
{ method: 'POST', headers }
);
const result = await response.json();
if (result.status !== 'SENT') {
return result;
}
// Wait 5 seconds before next attempt
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error('Ticket check timed out');
}
async function listDocuments(options = {}) {
const params = new URLSearchParams({
page: String(options.page || 1),
limit: String(options.limit || 20),
...(options.type && { type: options.type }),
...(options.status && { status: options.status }),
...(options.from && { from: options.from }),
...(options.to && { to: options.to })
});
const response = await fetch(
`${API_BASE}/api/documents?${params}`,
{ headers }
);
return await response.json();
}
// Usage
const invoices = await listDocuments({ type: '01', page: 1, limit: 10 });
import { writeFile } from 'fs/promises';
async function downloadPdf(documentId, outputPath) {
const response = await fetch(
`${API_BASE}/api/documents/${documentId}/pdf`,
{ headers }
);
const buffer = await response.arrayBuffer();
await writeFile(outputPath, Buffer.from(buffer));
console.log(`PDF saved to ${outputPath}`);
}
// Usage
await downloadPdf('cm3abc123', './invoice-F001-1.pdf');
async function retryDocument(documentId) {
const response = await fetch(
`${API_BASE}/api/documents/${documentId}/retry`,
{ method: 'POST', headers }
);
return await response.json();
}
// Automatic invoicing after payment
async function emitInvoiceAfterPayment(payment, customer) {
const response = await fetch(`${API_BASE}/api/invoices`, {
method: 'POST',
headers,
body: JSON.stringify({
series: 'F001',
correlative: payment.invoiceNumber,
issueDate: new Date().toISOString().split('T')[0],
dueDate: payment.dueDate,
currencyCode: 'PEN',
customer: {
identityType: customer.documentType,
identityNumber: customer.documentNumber,
name: customer.name,
address: customer.address
},
items: payment.items.map(item => ({
code: item.code,
description: item.name,
quantity: item.quantity,
unitCode: 'ZZ',
unitPrice: item.price,
igvType: '10'
}))
})
});
const result = await response.json();
if (result.status === 'ACCEPTED') {
console.log('Invoice accepted:', result.documentId);
} else if (result.status === 'REJECTED') {
console.error('Invoice rejected:', result.cdrDescription);
} else if (result.status === 'SUNAT_ERROR') {
console.warn('SUNAT error, will retry later:', result.id);
}
return result;
}