Saltearse al contenido

Emite un CFE

POST
/v1/cfe/emitir

Emite un Comprobante Fiscal Electrónico (CFE) y lo envía a DGI.

Este es el endpoint recomendado para integraciones nuevas: el cuerpo es un JSON estructurado y Host Factura se encarga de armar el XML, firmarlo, asignar CAE, manejar la numeración y enviarlo a DGI.

Tipos de CFE soportados

Ver la sección “Tipos de Comprobante Fiscal Electrónico (CFE) soportados” en la introducción para la tabla completa con los 24 tipos (códigos 101 a 153).

Los más usados son:

CódigoDescripciónReceptor
101e-TicketOpcional (consumidor final)
102Nota de Crédito de e-TicketHeredado de la referencia
103Nota de Débito de e-TicketHeredado de la referencia
111e-FacturaObligatorio
112Nota de Crédito de e-FacturaHeredado de la referencia
113Nota de Débito de e-FacturaHeredado de la referencia
121-123e-Factura Exportación y sus NotasObligatorio + exportacionInfo
124e-Remito ExportaciónObligatorio + remitoInfo
181e-RemitoObligatorio + remitoInfo
182e-ResguardoObligatorio + códigos de retención

Ítems

Cada elemento de items[] puede ser:

  • De catálogo: solo { id, quantity }. Los datos del producto se toman del catálogo de la cuenta.
  • Ad-hoc: { name, quantity, price, billingIndex, description?, unit?, code? }. billingIndex es obligatorio: 1=Exento, 2=10%, 3=22%, 4=Otras.

Emisión de Notas de Crédito y Notas de Débito

Las Notas se usan para modificar el monto de un Comprobante Fiscal Electrónico previamente emitido. No hay que volver a enviar los datos del receptor ni la fecha original — todo eso se hereda automáticamente del CFE referenciado.

Notas de Crédito (102, 112, 122, 132, 142, 152): reducen el monto del comprobante original. Casos típicos:

  • Devolución de mercadería por parte del cliente.
  • Error de facturación (monto mal cargado, ítem facturado por error).
  • Descuento aplicado posteriormente.
  • Bonificación comercial.

Notas de Débito (103, 113, 123, 133, 143, 153): aumentan el monto del comprobante original. Casos típicos:

  • Intereses por mora.
  • Cargos adicionales no facturados originalmente (flete, envasado, etc.).
  • Ajustes de precio por diferencias detectadas posteriormente.

Reglas de correspondencia entre el tipo de la Nota y el del CFE referenciado:

Tipo de NotaPuede referenciar
102 (Nota de Crédito de e-Ticket) / 103 (Nota de Débito de e-Ticket)e-Ticket (101)
112 (Nota de Crédito de e-Factura) / 113 (Nota de Débito de e-Factura)e-Factura (111)
122 / 123 (Notas de e-Factura Exportación)e-Factura Exportación (121)
132 / 133 (Notas de e-Ticket por Cuenta Ajena)e-Ticket por Cuenta Ajena (131)
142 / 143 (Notas de e-Factura por Cuenta Ajena)e-Factura por Cuenta Ajena (141)
152 / 153 (Notas de e-Boleta de Entrada)e-Boleta de Entrada (151)

Cómo emitirla: enviá el tipo correspondiente y referenciaId con el UUID del CFE original. Los items[] representan las líneas que se están acreditando/debitando — no son los ítems originales.

Moneda extranjera

Cuando moneda != "UYU", cambio es obligatorio. Obtené el tipo de cambio vigente con GET /v1/cotizaciones (caché 24h, datos del BCU).

Pre-requisitos de la cuenta

Para que la emisión funcione, la cuenta debe tener: CVA (certificado digital) activo, CAE vigente para el tipo+serie+sucursal, y datos básicos de empresa cargados. Si falta algo, recibirás 409 NO_CAE_VIGENTE u otro error específico.

Datos del CFE a emitir

object
clienteId
string format: uuid
cliente
object
tipoDocumento
Any of:
number
documento
string
razonSocial
string
denominacion
string
direccion
string
ciudad
string
estado
string
pais
string
email
string
items
required
Array<object>
>= 1 items
object
id
string format: uuid
name
string
quantity
required
number
price
number
billingIndex
integer
unit
string
description
string
code
string
codeType
string
kind
string
tipo
required
integer
moneda
required
string
Allowed values: UYU USD ARS BRL EUR
cambio
number
adenda
string
formaPago
Any of:
number
Allowed values: 1
referenciaId
string format: uuid
exportacionInfo
object
clausulaVenta
required
string
modalidadVenta
required
integer
viaTransporte
required
integer
remitoInfo
object
tipoTraslado
required
integer
>= 1 <= 2
propiedadMercaderia
integer
clauVenta
string
modVenta
integer
viaTransp
integer
tipoTraslado
integer
>= 1 <= 2
propiedadMercaderia
integer
Ejemplos

e-Ticket a consumidor final (sin datos de receptor)

Caso típico de POS: venta de bajo monto a consumidor final, sin RUT ni datos del cliente. Para tipo 101 (e-Ticket), si el monto neto en UI no supera el tope (~10.000 UI), el receptor es opcional.

{
"tipo": 101,
"moneda": "UYU",
"formaPago": 1,
"items": [
{
"name": "Café americano",
"quantity": 2,
"price": 90,
"billingIndex": 3
},
{
"name": "Medialuna",
"quantity": 1,
"price": 60,
"billingIndex": 3
}
]
}

CFE emitido. Verificá el campo data.estado (aceptado/pendiente/rechazado/observado).

object
data
required
object
id
required
string format: uuid
tipo
required
integer
tipoDescripcion
required
string
serie
required
string
nullable
numero
required
integer
nullable
rutEmisor
required
string
nullable
moneda
required
string
tipoCambio
required
number
nullable
subtotal
required
number
iva
required
number
total
required
number
adenda
required
string
anulado
required
boolean
estado
required
string
Allowed values: pendiente aceptado rechazado observado
estadoDgi
required
string
nullable
fechaEstadoDgi
required
string
nullable
motivoRechazo
required
string
nullable
codigoRespuesta
required
string
codigoSucursalDgi
required
number
nullable
clienteId
required
string
nullable
cuentaId
required
string format: uuid
sucursalId
required
string format: uuid
nullable
puntoEmisionId
required
string format: uuid
nullable
referenciaId
required
string format: uuid
nullable
uuidReferencia
required
string format: uuid
sobreId
required
string format: uuid
nullable
reporteDiarioId
required
string format: uuid
nullable
cfeRecurrenteId
required
string format: uuid
nullable
fechaCreacion
required
string
fechaActualizacion
required
string
Ejemplos

CFE emitido y aceptado por DGI

{
"data": {
"id": "8a7b6c5d-4e3f-2a1b-9c8d-7e6f5a4b3c2d",
"tipo": 111,
"tipoDescripcion": "e-Factura",
"serie": "A",
"numero": 1234,
"rutEmisor": "210000000000",
"moneda": "UYU",
"tipoCambio": 1,
"subtotal": 12500,
"iva": 2750,
"total": 15250,
"adenda": "Forma de pago: transferencia BROU 001-1234567-89",
"anulado": false,
"estado": "aceptado",
"estadoDgi": "A",
"fechaEstadoDgi": "2026-05-17T13:42:11.000Z",
"motivoRechazo": null,
"codigoRespuesta": "00",
"codigoSucursalDgi": 1,
"clienteId": null,
"cuentaId": "1d2e3f4a-5b6c-7d8e-9f0a-1b2c3d4e5f6a",
"sucursalId": null,
"puntoEmisionId": null,
"referenciaId": null,
"uuidReferencia": "9b8a7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
"sobreId": "2a3b4c5d-6e7f-8a9b-0c1d-2e3f4a5b6c7d",
"reporteDiarioId": null,
"cfeRecurrenteId": null,
"fechaCreacion": "2026-05-17T13:42:10.000Z",
"fechaActualizacion": "2026-05-17T13:42:11.000Z"
}
}

Datos inválidos. Falla la validación Zod del body, o el CFE no es construible.

Códigos posibles:

  • CLIENT_CI_INVALID — Cédula uruguaya con dígito verificador incorrecto.
  • NOTA_REFERENCE_UNDEFINED — Es una Nota de Crédito o Nota de Débito y falta referenciaId.
  • EXPORTACION_INFO_REQUIRED — Es CFE de exportación y falta exportacionInfo.
  • REMITO_INFO_REQUIRED — Es e-Remito y falta remitoInfo.
  • ITEM_INVALIDO — Un ítem no tiene nombre o unidad.
  • PUNTO_EMISION_REQUERIDO — Sucursal con múltiples puntos sin x-point-id.
  • SUCURSAL_INVALIDAx-branch-id no pertenece a la cuenta.
object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

Cédula uruguaya con dígito verificador inválido

{
"error": {
"code": "CLIENT_CI_INVALID",
"message": "La cédula uruguaya del cliente no es válida (dígito verificador incorrecto)"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}

No autenticado. La API_KEY no fue enviada o no es válida.

Códigos posibles: API_AUTH_HEADER_MISSING, API_AUTH_HEADER_INVALID, API_ACCESS_INVALID.

object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

Falta header Authorization

{
"error": {
"code": "API_AUTH_HEADER_MISSING",
"message": "Se esperaba la cabecera Authorization con esquema Bearer"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}

Acceso prohibido. La credencial es válida pero el plan o el alcance de sucursal lo impiden.

Códigos posibles: API_FEATURE_DISABLED, API_ACCESS_BRANCH_MISMATCH.

object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

El plan no incluye API

{
"error": {
"code": "API_FEATURE_DISABLED",
"message": "El plan de esta cuenta no tiene habilitado el acceso a la API"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}

Recurso referenciado no existe.

  • CLIENTE_NO_ENCONTRADOclienteId no existe en la cuenta.
  • CFE_REFERENCIA_NO_EXISTEreferenciaId no existe (al emitir una Nota de Crédito o Nota de Débito).
object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

Cliente referenciado no existe

{
"error": {
"code": "CLIENTE_NO_ENCONTRADO",
"message": "Cliente no encontrado (uuid)"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}

Conflicto con el estado actual (típicamente CAE).

  • NO_CAE_VIGENTE — No hay CAE activo para el tipo solicitado.
  • CAE_RANGE_EXHAUSTED — Se agotó el rango de numeración del CAE.
  • SUCURSAL_INACTIVA — La sucursal resuelta está deshabilitada.
object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

No hay CAE vigente para el tipo solicitado

{
"error": {
"code": "NO_CAE_VIGENTE",
"message": "No hay CAE vigente para eTck"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}

Rate limit excedido. Esperá los segundos indicados en el header Retry-After.

object
error
required
object
code
required

Identificador estable del error en SCREAMING_SNAKE_CASE

string
message
required

Mensaje legible en español

string
details

Información adicional (puede ser objeto, array o string)

nullable
requestId

UUID de correlación; mismo valor que el header X-Request-ID

string format: uuid
Ejemplos

Excediste el rate limit

{
"error": {
"code": "API_RATE_LIMITED",
"message": "Se superó el límite de requests para esta API key"
},
"requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"
}
Retry-After
integer
Ejemplo
42

Segundos hasta que se libera la ventana de rate limit