Saltar al contenido principal

Anular DTE

El API ofrece dos endpoints de anulación, según el tipo de documento:

  • POST /invalidate/{id_or_ref} — para Factura (01), CCF (03), Exportación (11), y Nota de Crédito (05).
  • POST /invalidate/suex/{id_or_ref} — específico para Sujeto Excluido (14).

Son rutas distintas porque SUEX vive en un modelo diferente (PurchaseHeader) y requiere endpoints dedicados.

Ventanas de anulación del MH

El MH permite invalidación directa solo dentro de ciertas ventanas temporales:

TipoVentana de invalidación directaQué pasa fuera de ventana
Factura (01)24 horas desde emisiónMH rechaza la invalidación.
CCF (03)3 meses desde emisiónEl API genera automáticamente una Nota de Crédito para anular el CCF.
Exportación (11)Variable según normativa MHDepende del caso; MH puede rechazar.
Nota de Crédito (05)Se puede anular la NC en 24 hFuera de ventana: no recuperable.
SUEX (14)24 horasMH rechaza.
CCF fuera de ventana: transparente para ti

Si llamas /invalidate/{ccf_id} y el CCF tiene más de 3 meses, el API no falla. Detecta la situación, crea una NC que ajusta el CCF completo, y te devuelve en el response created_credit_memo: true con el UUID y control number de la NC generada. Desde tu lado la única acción fue un POST a /invalidate — el API maneja el resto.

Anular Factura, CCF, Exportación o NC

Detalles técnicos

MétodoPOST
URLhttps://ocote.io/api/connect/invalidate/{id_or_ref}
BodyNo lleva body.
AutenticaciónHeader Authorization: Bearer odt_...

El {id_or_ref} en la URL puede ser el UUID del documento o tu external_ref.

Request

No requiere body. Todo está en la URL:

curl
curl -X POST https://ocote.io/api/connect/invalidate/VENTA-2026-0042 \
-H "Authorization: Bearer odt_xxx"
Node.js (axios)
const { data } = await axios.post(
'https://ocote.io/api/connect/invalidate/VENTA-2026-0042',
null,
{ headers: { Authorization: `Bearer ${process.env.OCOTE_API_KEY}` } }
);
Python (requests)
r = requests.post(
f"https://ocote.io/api/connect/invalidate/VENTA-2026-0042",
headers={"Authorization": f"Bearer {API_KEY}"},
)

Response

CampoTipoDescripción
successbooltrue si la operación se registró en Ocote (incluye contingencia).
messagestringMensaje descriptivo del estado.
document_idstring (UUID)ID del documento afectado.
invalidatedbooltrue si el API intentó invalidar. Combinado con dte_success dice si quedó firmado.
created_credit_memobooltrue si se generó una NC automática (caso CCF fuera de ventana).
credit_memo_idstringUUID de la NC generada (vacío si no se generó).
credit_memo_control_numberstringCorrelativo de la NC (DTE-05-...).
dte_successboolMH aceptó la invalidación.
contingencyboolMH no respondió; la invalidación se revalidará.
rejectedboolMH rechazó la invalidación.
dte_state, dte_message, observaciones, codigo_msgDiagnóstico si hubo rechazo. Ver Respuestas y estados.

Ejemplos de response

CCF dentro de ventana, anulación directa exitosa:

{
"success": true,
"message": "Documento invalidado",
"document_id": "a1b2c3d4-...",
"invalidated": true,
"created_credit_memo": false,
"credit_memo_id": "",
"credit_memo_control_number": "",
"dte_success": true,
"contingency": false,
"rejected": false
}

CCF fuera de ventana, NC generada automáticamente:

{
"success": true,
"message": "CCF fuera de ventana. Nota de Credito generada automaticamente.",
"document_id": "a1b2c3d4-...",
"invalidated": true,
"created_credit_memo": true,
"credit_memo_id": "b2c3d4e5-...",
"credit_memo_control_number": "DTE-05-M001P002-000000000000007",
"dte_success": true,
"contingency": false,
"rejected": false
}

Ya estaba invalidado (idempotencia):

{
"success": true,
"message": "Documento ya invalidado",
"document_id": "a1b2c3d4-...",
"invalidated": true,
"created_credit_memo": false,
"dte_success": true,
"contingency": false,
"rejected": false
}

Llamar /invalidate sobre un documento ya invalidado es seguro: devuelve el estado actual sin efectos secundarios. Ver Retry e idempotencia > Invalidación.

Anular Sujeto Excluido

Detalles técnicos

MétodoPOST
URLhttps://ocote.io/api/connect/invalidate/suex/{id_or_ref}
BodyNo lleva body.
AutenticaciónHeader Authorization: Bearer odt_...
curl
curl -X POST https://ocote.io/api/connect/invalidate/suex/SUEX-2026-0015 \
-H "Authorization: Bearer odt_xxx"

El response tiene la misma estructura pero nunca se genera NC automática — el mecanismo de NC es exclusivo de CCF. Si el SUEX está fuera de ventana, el MH rechaza y recibes rejected: true.

Errores de validación

HTTPMensajeCausa
404Documento no encontradoEl id_or_ref no existe en tu empresa.
400Documento no puede ser invalidadoEl documento está en un estado incompatible (no procesado, ya fue NC, etc.).
400Mensaje específico del MHVer observaciones en el response para el detalle.

Ver también