Nota de debito POST
La nota de debito incrementa el valor de un comprobante ya emitido (intereses,
recargos, ajustes). La estructura del comprobante es la misma que en
Factura ; cambia el contenido de info, la coleccion
motivos y el ejemplo.
Ejemplo en el ambiente de pruebas . Los comprobantes no tienen validez fiscal.
POST /v1/contribuyentes/{identificacion}/comprobantes
infoTributaria.codDoc = "05"
Estructura del comprobante#
Clave
Tipo
Obligatorio
Descripcion
origenReferencia
string
Si
Sistema de origen (max. 64)
referenciaExterna
string
Si
Referencia estable de tu sistema (max. 128)
infoTributaria
object
Si
Identidad del documento
info
object
Si
Cabecera de la nota
motivos
array
Si
Objetos {razon, valor}
infoAdicional
array
No
Hasta 20 objetos {nombre, valor}
infoTributaria: ruc (13), codDoc (05), estab (3), ptoEmi (3) y
secuencial (9) obligatorios. La clave de acceso la asigna la plataforma; no la envies.
Campos de info#
Campo
Tipo
Obligatorio
Regla
fechaEmision
string
Si
dd/MM/yyyy
tipoIdentificacionComprador
string
Si
Catalogos de identificacion
identificacionComprador
string
Si
Documento del comprador
razonSocialComprador
string
Si
Razon social
codDocModificado
string
Si
Tipo del documento de referencia
numDocModificado
string
Si
Formato ddd-ddd-ddddddddd
fechaEmisionDocSustento
string
Si
dd/MM/yyyy
totalSinImpuestos
number
Si
Base
impuestos
array
Si
codigo, codigoPorcentaje, tarifa, baseImponible, valor
valorTotal
number
Si
Valor total de la nota
pagos
array
Si
formaPago y total obligatorios
motivos#
Razones que sustentan la nota de debito.
Campo
Tipo
Obligatorio
Descripcion
razon
string
Si
Descripcion del motivo
valor
number
Si
Importe asociado al motivo
info.impuestos#
Campo
Tipo
Obligatorio
Descripcion
codigo
string
Si
Impuesto: 2 IVA, 3 ICE, 5 IRBPNR
codigoPorcentaje
string
Si
Codigo de tarifa (ve Catalogos )
tarifa
number
Si
Porcentaje de la tarifa
baseImponible
number
Si
Base sobre la que se calcula
valor
number
Si
Valor del impuesto
pagos#
Campo
Tipo
Obligatorio
Descripcion
formaPago
string
Si
Codigo de forma de pago
total
number
Si
Monto con esta forma de pago
plazo
number
No
Plazo
unidadTiempo
string
Condicional
Obligatorio si plazo > 0
infoAdicional#
Campo
Tipo
Obligatorio
Descripcion
nombre
string
Si
Nombre del campo adicional
valor
string
Si
Valor del campo adicional
Ejemplo de solicitud#
HTTP SDK
cURL .NET Python Node.js PHP Java
curl -s -X POST "https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes" \
-H "X-Api-Key: $ECUAFACT_API_KEY" \
-H "Idempotency-Key: ND-2026-0002" \
-H "Content-Type: application/json" \
-d @comprobante.json
using System.Text;
using var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-Api-Key", apiKey);
http.DefaultRequestHeaders.Add("Idempotency-Key", "ND-2026-0002");
string json = await File.ReadAllTextAsync("comprobante.json");
using var contenido = new StringContent(json, Encoding.UTF8, "application/json");
using var respuesta = await http.PostAsync(
"https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes",
contenido);
Console.WriteLine($"{(int)respuesta.StatusCode} {await respuesta.Content.ReadAsStringAsync()}");
import json, os, requests
headers = {
"X-Api-Key": os.environ["ECUAFACT_API_KEY"],
"Idempotency-Key": "ND-2026-0002",
}
with open("comprobante.json", encoding="utf-8") as archivo:
cuerpo = json.load(archivo)
r = requests.post(
"https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes",
headers=headers, json=cuerpo, timeout=30)
print(r.status_code, r.text)
import { readFile } from 'node:fs/promises';
const cuerpo = await readFile('comprobante.json', 'utf8');
const res = await fetch(
'https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes',
{
method: 'POST',
headers: {
'X-Api-Key': process.env.ECUAFACT_API_KEY,
'Idempotency-Key': 'ND-2026-0002',
'Content-Type': 'application/json'
},
body: cuerpo
});
console.log(res.status, await res.text());
<?php
$ch = curl_init('https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-Api-Key: ' . getenv('ECUAFACT_API_KEY'),
'Idempotency-Key: ND-2026-0002',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => file_get_contents('comprobante.json'),
]);
$respuesta = curl_exec($ch);
$estado = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo $estado . ' ' . $respuesta;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
HttpClient cliente = HttpClient.newHttpClient();
String cuerpo = Files.readString(Path.of("comprobante.json"));
HttpRequest peticion = HttpRequest.newBuilder()
.uri(URI.create("https://staging-api.mynexusapi.com/v1/contribuyentes/0123456789/comprobantes"))
.header("X-Api-Key", System.getenv("ECUAFACT_API_KEY"))
.header("Idempotency-Key", "ND-2026-0002")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(cuerpo))
.build();
HttpResponse<String> respuesta = cliente.send(peticion, HttpResponse.BodyHandlers.ofString());
System.out.println(respuesta.statusCode() + " " + respuesta.body());
.NET Python Node.js PHP Java
using Ecuafact.Sdk;
// client: cliente EcuafactClient - ver SDK .NET
EmisionResultado resultado = await client.EmitirAsync(comprobante);
Console.WriteLine($"Operacion {resultado.Admission.IdOperacion} / codigo: {resultado.Admission.Codigo}");
from ecuafact import EcuafactClient
# client: cliente EcuafactClient - ver SDK Python
resultado = client.emitir(comprobante)
print(f"Operacion {resultado.admission.id_operacion} / codigo: {resultado.admission.codigo}")
import { EcuafactClient } from "@ecuafact/sdk";
// client: cliente EcuafactClient - ver SDK Node.js
const resultado = await client.emitir(comprobante);
console.log(`Operacion ${resultado.admission.idOperacion} / codigo: ${resultado.admission.codigo}`);
<?php
use Ecuafact\Sdk\EcuafactClient;
// $client: cliente EcuafactClient - ver SDK PHP
$resultado = $client->emitir($comprobante);
echo 'Operacion ' . $resultado->admission->idOperacion . ' / codigo: ' . $resultado->admission->codigo;
import com.ecuafact.sdk.EcuafactClient;
// client: cliente EcuafactClient - ver SDK Java
EmisionResultado resultado = client.emitir(comprobante);
System.out.println("Operacion " + resultado.admission().idOperacion() + " / codigo: " + resultado.admission().codigo());
Cuerpo de la Nota de debito#
{
"origenReferencia": "MiERP",
"referenciaExterna": "ND-2026-0002",
"infoTributaria": {
"ruc": "0123456789001",
"codDoc": "05",
"estab": "002",
"ptoEmi": "001",
"secuencial": "000000011"
},
"info": {
"fechaEmision": "07/09/2026",
"tipoIdentificacionComprador": "05",
"identificacionComprador": "0123456789",
"razonSocialComprador": "CONTRIBUYENTE DE EJEMPLO",
"codDocModificado": "01",
"numDocModificado": "002-001-000000123",
"fechaEmisionDocSustento": "01/09/2026",
"totalSinImpuestos": 30,
"valorTotal": 34.5,
"impuestos": [
{ "codigo": "2", "codigoPorcentaje": "4", "tarifa": 15, "baseImponible": 30, "valor": 4.5 }
],
"pagos": [
{ "formaPago": "01", "total": 34.5 }
]
},
"motivos": [
{ "razon": "INTERESES POR MORA", "valor": 34.5 }
]
}
Notas#
Usa impuestos de cabecera (no totalConImpuestos) y valorTotal (no
valorModificacion).
La nota recibe una tarifa de IVA.
Debe identificar al receptor (no consumidor final).
Respuesta#
La API responde 202 Accepted con la operacion creada:
{
"codigo": "200",
"mensaje": "Operacion exitosa.",
"idOperacion": "3f1c8c1e-6f2a-4b7e-9c3d-2a1b0c9d8e7f",
"urlEstado": "https://staging-api.mynexusapi.com/v1/operaciones/3f1c8c1e-6f2a-4b7e-9c3d-2a1b0c9d8e7f",
"uid": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
Campo
Significado
codigo
200 si es una emision nueva; 201 si es un reintento con la misma Idempotency-Key
mensaje
Descripcion del resultado
idOperacion
Identificador de seguimiento de la emision
urlEstado
Ruta para consultar el estado de esta operacion
uid
Identificador del documento
El 202 no es la autorizacion del SRI: el comprobante quedo recibido . Consulta urlEstado o espera el webhook .
Estados de este endpoint#
Codigo
HTTP
Cuando ocurre
Que hacer
200
202
Emision aceptada
Sigue el estado de la operacion
201
202
Reintento con la misma Idempotency-Key y el mismo contenido
Sigue la misma operacion
301
400
Falta Idempotency-Key o hay campos mal formados
Corrige la solicitud
302
422
El comprobante no cumple una regla fiscal o de estructura
Revisa errores
401
409
Numero o clave ya registrados (duplicado)
Consulta la operacion existente
403
409
Misma Idempotency-Key con otro contenido
Usa la misma intencion
501
429
Cupo agotado
Amplia tu cupo
101
401
API Key invalida
Revisa la API Key
103
403
Contribuyente o tipo no habilitado
Habilita el contribuyente
El catalogo completo esta en Errores .
Siguientes pasos#