Ir al contenido

addDraftItem()

Agrega un concepto al borrador y devuelve el documento completo con los totales actualizados.

Permiso: invoice:write

addDraftItem(
id: string,
input: DraftAddItemInput,
options?: RequestOptions
): Promise<DraftRecord>

Referencia HTTP: POST /invoice-drafts/{id}/items

  • No requiere dar de alta un producto previamente. unitPrice es el precio unitario antes de impuestos.
  • El tipo TypeScript requiere quantity, aunque el validador HTTP pueda completarla con 1. Guarda el ID del concepto desde items; la respuesta no es solo el concepto agregado.
ArgumentoTipoObligatorioUso
idstringSíID de FactuCat del borrador, en formato UUID. No es el UUID fiscal.
inputDraftAddItemInputSíObjeto con los campos indicados abajo.
optionsRequestOptionsNosignal e idempotencyKey; consulta las opciones por solicitud.

Opciones por solicitud: signal e idempotencyKey.

Los campos siguientes corresponden a input en TypeScript. Un campo opcional se puede omitir; null solo se admite cuando aparece en su tipo. Las validaciones de negocio se ejecutan en el servidor.

CampoTipoObligatorioDescripción
positionnumber (entero)NoPosición del concepto; comienza en 0.Mínimo: 0. Máximo: 9007199254740991
productCodestringNoClave del producto o servicio del catálogo SAT.
unitCodestringNoClave de unidad del catálogo SAT.
descriptionstringSíDescripción del bien o servicio.Mínimo 1 carácter
quantitynumberSíCantidad del concepto.Mayor que 0. Valor del validador: 1
unitPricenumberSíPrecio unitario antes de impuestos.Mínimo: 0
vatTreatment"iva_16" | "iva_8" | "tasa_0" | "exento" | "no_objeto"NoTratamiento de IVA opcional: iva_16, iva_8, tasa_0, exento o no_objeto. Omitirlo conserva la inferencia fiscal; un tratamiento explícito se guarda como manual. Si también envías vatRate, deben coincidir; de lo contrario, la API responde HTTP 400 con invalid_input. Se devuelve en los conceptos de borradores y facturas; no representa la tasa histórica de 10%.
vatRate0 | 0.08 | 0.1 | 0.16NoTasa de IVA como fracción decimal, por ejemplo 0.16; no envíes 16. vatRate: 0 por sí solo significa Tasa 0%.
vatSource"manual" | "inferred" | "default"NoOrigen de la tasa de IVA seleccionada.
isrWithholdingRate0 | 0.0125 | 0.1NoTasa de retención de ISR como fracción decimal.
isrWithholdingSource"manual" | "inferred" | "default"NoOrigen de la retención de ISR seleccionada.
suggestedProductCodestringNoClave de producto o servicio sugerida.
suggestionConfidencenumberNoConfianza de la sugerencia.Mínimo: 0. Máximo: 1
suggestionSource"ai" | "memory" | "manual" | "review"NoOrigen de la sugerencia.

Usa el cliente factucat de Instala y conecta. Los IDs y datos fiscales de este ejemplo son ilustrativos: reemplázalos por los registros de tu cuenta y ambiente.

const resultado = await factucat.addDraftItem(
"00112233-4455-4677-8899-aabbccddeeff",
{
"productCode": "81111500",
"unitCode": "E48",
"description": "Desarrollo de aplicaciones",
"quantity": 1,
"unitPrice": 1000,
"vatRate": 0.16,
"isrWithholdingRate": 0
},
{
"idempotencyKey": "pedido-1001-concepto-1"
},
)
console.log(resultado)

Resuelve una Promise<DraftRecord>. El valor recibido es directamente data, sin el envoltorio HTTP ni sus metadatos.

CampoTipoObligatorioDescripción
idstringSíID de FactuCat del recurso. No es el UUID fiscal.Formato: uuid
userIdstringSíID de la cuenta propietaria del recurso.Mínimo 1 carácter
customerIdstringNoID de FactuCat del cliente vinculado. Consulta las notas del método sobre la copia de datos fiscales.Formato: uuid
receiverRfcstringSíRFC del receptor guardado en el documento.
receiverLegalNamestringSíNombre fiscal del receptor guardado en el documento.
receiverPostalCodestringSíCódigo postal fiscal del receptor, como cadena de cinco dígitos.
receiverTaxRegimestringSíClave del régimen fiscal del receptor.
receiverFiscalResidencestringNoClave del país de residencia fiscal del receptor, cuando aplica.
receiverTaxIdstringNoIdentificación tributaria extranjera del receptor, cuando aplica.
receiverEmailstringNoCorreo del receptor guardado en el documento.Formato: email
receiverInvoiceLanguage"es" | "en"SíIdioma del receptor para este documento.
seriestringNoSerie asignada por la cuenta emisora.
foliostringNoFolio del documento.
satUuidstringNoUUID fiscal del CFDI timbrado. Es distinto del ID de FactuCat.
status"draft" | "issued" | "error" | "cancelled"SíEstado del recurso o resultado de la cancelación; consulta las notas del método.
cfdiTypestringSíTipo de comprobante.
cfdiUsestringSíClave del uso de CFDI solicitado por el receptor.
exportacion"01" | "02" | "03" | "04"SíClave del catálogo SAT c_Exportacion.
paymentMethodstringNoClave del método de pago del comprobante.
paymentFormstringNoClave de la forma de pago; conserva los ceros iniciales.
currency"MXN" | "USD" | "EUR"SíMoneda del cliente o del comprobante.
exchangeRatenumberSíTipo de cambio aplicado a la moneda del comprobante.
exchangeRateDatestringNoFecha de referencia del tipo de cambio en formato ISO 8601.Formato: date-time
subtotalnumberSíSubtotal del documento antes de impuestos.
vatRate0 | 0.08 | 0.1 | 0.16SíTasa de IVA como fracción decimal, por ejemplo 0.16; no envíes 16. vatRate: 0 por sí solo significa Tasa 0%.
taxTotalnumberSíTotal de impuestos del documento.
totalnumberSíImporte total del documento. En cancelaciones externas se envía como string.
customerNotesstringNoNotas visibles en el documento.
pdfLanguage"es" | "en"SíIdioma de la representación PDF.
errorMessagestringNoMensaje asociado a un error del documento, cuando está disponible.
issueDatestringNoFecha de emisión seleccionada, en formato ISO 8601.Formato: date-time
issuedAtstringNoFecha y hora de emisión, cuando está disponible.Formato: date-time
cancelledAtstringNoFecha y hora de cancelación, cuando está disponible.Formato: date-time
createdAtstringSíFecha y hora de creación en formato ISO 8601; se devuelve como string.Formato: date-time
updatedAtstringSíFecha y hora de última actualización en formato ISO 8601.Formato: date-time
itemsArray<object>SíConceptos del documento; cada concepto tiene su propio ID.
Campos de items[]
CampoTipoObligatorioDescripción
idstringSíID de FactuCat del recurso. No es el UUID fiscal.Formato: uuid
invoiceIdstringSíID de FactuCat del documento al que pertenece el concepto.Formato: uuid
positionnumber (entero)SíPosición del concepto; comienza en 0.Mínimo: 0. Máximo: 9007199254740991
productCodestringNoClave del producto o servicio del catálogo SAT.
unitCodestringSíClave de unidad del catálogo SAT.
descriptionstringSíDescripción del bien o servicio.
quantitynumberSíCantidad del concepto.
unitPricenumberSíPrecio unitario antes de impuestos.
amountnumberSíImporte del concepto antes de impuestos.
objetoImp"01" | "02" | "03" | "04" | "05" | "06" | "07" | "08"NoObjeto de impuesto del concepto, devuelto en borradores y facturas; 01 indica No objeto de impuesto.
vatKind"none" | "tasa" | "exento"NoTipo de IVA del concepto, devuelto en borradores y facturas: tasa, exento o none (No objeto de impuesto).
vatTreatment"iva_16" | "iva_8" | "tasa_0" | "exento" | "no_objeto"NoTratamiento de IVA opcional: iva_16, iva_8, tasa_0, exento o no_objeto. Omitirlo conserva la inferencia fiscal; un tratamiento explícito se guarda como manual. Si también envías vatRate, deben coincidir; de lo contrario, la API responde HTTP 400 con invalid_input. Se devuelve en los conceptos de borradores y facturas; no representa la tasa histórica de 10%.
vatRate0 | 0.08 | 0.1 | 0.16SíTasa de IVA como fracción decimal, por ejemplo 0.16; no envíes 16. vatRate: 0 por sí solo significa Tasa 0%.
vatSource"manual" | "inferred" | "default"NoOrigen de la tasa de IVA seleccionada.
vatReasonstringNoExplicación de la tasa de IVA, cuando está disponible.
isrWithholdingRate0 | 0.0125 | 0.1SíTasa de retención de ISR como fracción decimal.
isrWithholdingSource"manual" | "inferred" | "default"NoOrigen de la retención de ISR seleccionada.
isrWithholdingReasonstringNoExplicación de la retención de ISR, cuando está disponible.
suggestedProductCodestringNoClave de producto o servicio sugerida.
suggestionConfidencenumberNoConfianza de la sugerencia.
suggestionSource"ai" | "memory" | "manual" | "review"NoOrigen de la sugerencia.

Ejemplo de respuesta

{
"id": "00112233-4455-4677-8899-aabbccddeeff",
"userId": "usuario_ejemplo",
"customerId": "10112233-4455-4677-8899-aabbccddeeff",
"receiverRfc": "AAA010101AAA",
"receiverLegalName": "EMPRESA DE EJEMPLO",
"receiverPostalCode": "06000",
"receiverTaxRegime": "601",
"receiverInvoiceLanguage": "es",
"status": "draft",
"cfdiType": "I",
"cfdiUse": "G03",
"exportacion": "01",
"paymentMethod": "PUE",
"paymentForm": "03",
"currency": "MXN",
"exchangeRate": 1,
"subtotal": 1000,
"vatRate": 0.16,
"taxTotal": 160,
"total": 1160,
"pdfLanguage": "es",
"createdAt": "2026-09-08T12:00:00Z",
"updatedAt": "2026-09-08T12:00:00Z",
"items": [
{
"id": "20112233-4455-4677-8899-aabbccddeeff",
"invoiceId": "00112233-4455-4677-8899-aabbccddeeff",
"position": 0,
"productCode": "81111500",
"unitCode": "E48",
"description": "Desarrollo de aplicaciones",
"quantity": 1,
"unitPrice": 1000,
"amount": 1000,
"vatRate": 0.16,
"isrWithholdingRate": 0
}
]
}

Las fechas se entregan como cadenas ISO 8601. Un campo opcional puede estar ausente. Tipos, paginación y archivos.

La promesa se rechaza si la API devuelve un error, falla la conexión o los datos no cumplen el contrato. Cómo manejar los errores.