---
title: "Crea tu primera integración"
description: "Configura una API key de prueba, haz tu primera solicitud y sigue los flujos REST y MCP."
language: es-MX
canonical_url: "https://exac.mx/docs/quickstart"
md_url: "https://exac.mx/docs/quickstart.md"
---

# Crea tu primera integración

Configura una API key de prueba, haz tu primera solicitud y sigue los flujos REST y MCP.

## Producción y entorno de prueba

Las API keys de organización pertenecen a un solo entorno. Las claves de prueba usan las operaciones marcadas “Producción y prueba” en la referencia de API contra datos de prueba aislados. Las operaciones exclusivas de producción y MCP no están disponibles en prueba. Las credenciales se rechazan fuera del entorno asignado.

## Haz tu primera solicitud autenticada

Comienza con una organización de prueba aislada y una API key de prueba.

### 1. Abre la consola para desarrolladores

Abre /consola desde Exac, selecciona Prueba y entra a Claves API para tu workspace actual.

### 2. Crea una API key de prueba

Crea una clave para Prueba y cópiala una sola vez. Exac prepara el entorno aislado automáticamente.

### 3. Verifica la organización de prueba

Llama GET /v1/organization con la clave de prueba contra el servidor de prueba mostrado en OpenAPI.

### 4. Ejecuta un flujo Test

Crea un contacto y un borrador CFDI; luego crea, consulta y cancela un timbrado de prueba. Los artefactos de sandbox no se envían al SAT y no tienen validez fiscal.

```bash
curl "https://grateful-squid-667.convex.site/v1/organization" \
  --header "Authorization: Bearer <EXAC_API_KEY>"
```

## Convenciones de solicitudes, respuestas y reintentos

### Autenticación y JSON

Envía Authorization: Bearer <credencial> en cada solicitud de API y Content-Type: application/json cuando envíes un cuerpo JSON. Los éxitos JSON usan { data }; las respuestas paginadas también incluyen pagination. Las fallas usan { error: { code, message, status, details? } }. Decide con error.code, no con el mensaje humano, y conserva el encabezado Request-Id para diagnóstico. Las descargas devuelven bytes en lugar de un sobre JSON.

### Reintentos seguros

Cada escritura requiere Idempotency-Key, incluso el primer intento. Genera una clave única por operación deseada y consérvala con la solicitud.

Tras un timeout, reintenta con la misma credencial, clave, ruta y carga. Cambiar la operación o la carga con una clave retenida devuelve idempotency_conflict.

Las claves se limitan a la organización e identidad que llama, compartidas entre REST y MCP; cambiar de credencial puede cambiar ese alcance. Una operación exitosa repite su resultado original, que puede diferir del estado actual del recurso.

### Límites de reintento y recuperación

Los registros de idempotencia se conservan 7 días; los secretos de creación de API keys se pueden recuperar durante 15 minutos. No dependas de la deduplicación después de ese periodo: verifica el recurso antes de enviar otra escritura.

Espera Retry-After cuando esté presente.

Nunca reintentes automáticamente recovery_required o details.retryable = false, ni cambies de clave para evadir un resultado incierto.

Usa details.document.documentRef para consultar el documento afectado cuando exista.

### Paginación e identificadores

Empieza sin cursor y después envía pagination.nextCursor sin cambios con los mismos filtros hasta que pagination.hasMore sea false. Una página corta o vacía no termina la consulta si hasMore es true.

Los IDs y documentRef son opacos y pertenecen a una organización: conserva el valor completo, incluido el prefijo de documentRef, y codifícalo como segmento de URL. No sustituyas documentRef por un UUID del SAT.

### Fechas, montos y campos ausentes

Los instantes usan RFC 3339 con desplazamiento, por ejemplo 2026-07-15T18:00:00.000Z.

Las fechas usan YYYY-MM-DD y los meses YYYY-MM.

Los campos CFDI que terminan en LocalDateTime representan hora civil sin desplazamiento: no agregues Z ni supongas UTC.

Los objetos monetarios estándar { amount, currency } usan unidades mayores numéricas (116 significa 116 pesos en MXN); los campos que terminan en Minor usan unidades menores, como centavos.

Algunos montos fiscales, bases de impuestos y campos rateOrFee usan cadenas decimales exactas: conserva el tipo y la precisión del esquema sin convertirlos a punto flotante ni centavos.

Las tasas numéricas son fracciones, como 0.16 para 16%.

Los campos opcionales pueden omitirse; envía null solo cuando el esquema lo permita explícitamente.

## Flujos canónicos

Usa la misma intención de dominio mediante REST o MCP. Estos ejemplos se validan contra los contratos de ejecución; reemplaza los identificadores y credenciales de ejemplo con valores de tu organización.

### Prueba el ciclo de un CFDI en sandbox

Crea, timbra, descarga y cancela un CFDI de prueba sin validez fiscal usando únicamente operaciones REST de sandbox.

#### Verifica la organización

Confirma que la clave de sandbox resuelva a la organización aislada esperada.

Guía de reintentos: Esta lectura se puede repetir de forma segura.

#### Crea un cliente de prueba

Crea el cliente con su identidad fiscal. Usa el contactId devuelto como customerId en la siguiente solicitud.

Guía de reintentos: Reutiliza la misma clave solo para una solicitud idéntica.

#### Crea un borrador CFDI

Crea un borrador que puedas revisar antes del timbrado de prueba explícito.

Guía de reintentos: Reutiliza la misma clave solo para la carga idéntica del borrador.

#### Crea un timbrado de prueba

Sandbox crea un artefacto de prueba. No se envía al SAT y no tiene validez fiscal.

Guía de reintentos: Reintenta solo con la misma clave y documentRef.

#### Descarga el PDF de prueba

Descarga el documento de prueba generado desde el servidor de sandbox.

Guía de reintentos: Esta lectura de archivo se puede repetir de forma segura.

#### Cancela el CFDI de prueba

Ejercita la transición de cancelación contra datos de prueba aislados.

Guía de reintentos: Reutiliza la misma clave solo para la misma solicitud de cancelación.

```json
{
  "steps": [
    {
      "id": "verify-sandbox-organization",
      "rest": {
        "operationId": "getOrganization",
        "method": "GET",
        "path": "/v1/organization",
        "environments": [
          "production",
          "sandbox"
        ]
      }
    },
    {
      "id": "create-sandbox-contact",
      "rest": {
        "operationId": "createContact",
        "method": "POST",
        "path": "/v1/contacts",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "sandbox-create-contact"
        },
        "body": {
          "kind": "customer",
          "legalName": "Estudio Jacaranda",
          "email": "administracion@jacaranda.example",
          "rfc": "AAA010101AAA",
          "taxSystem": "601",
          "cfdiUse": "G03",
          "address": {
            "postalCode": "82110",
            "country": "MEX"
          }
        }
      }
    },
    {
      "id": "create-sandbox-cfdi",
      "rest": {
        "operationId": "createInvoiceDraft",
        "method": "POST",
        "path": "/v1/invoices",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "sandbox-create-cfdi"
        },
        "body": {
          "customerId": "customer-example",
          "items": [
            {
              "kind": "custom",
              "description": "Consultoría administrativa · julio 2026",
              "quantity": 1,
              "unitPrice": 10000,
              "satProductCode": "84111506",
              "satUnitCode": "E48",
              "taxRate": 0.16,
              "taxability": "standard"
            }
          ],
          "kind": "income",
          "cfdiUse": "G03",
          "payment": {
            "timing": "deferred_or_installments",
            "formCode": "99",
            "conditions": "Crédito a 30 días"
          }
        }
      }
    },
    {
      "id": "stamp-sandbox-cfdi",
      "rest": {
        "operationId": "stampInvoice",
        "method": "POST",
        "path": "/v1/invoices/invoice:invoice-example/stamp",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "sandbox-stamp-cfdi"
        },
        "body": {}
      }
    },
    {
      "id": "download-sandbox-pdf",
      "rest": {
        "operationId": "downloadDocumentFile",
        "method": "GET",
        "path": "/v1/documents/invoice:invoice-example/files/pdf",
        "environments": [
          "production",
          "sandbox"
        ]
      }
    },
    {
      "id": "cancel-sandbox-cfdi",
      "rest": {
        "operationId": "cancelInvoice",
        "method": "POST",
        "path": "/v1/invoices/invoice:invoice-example/cancel",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "sandbox-cancel-cfdi"
        },
        "body": {
          "reason": "02"
        }
      }
    }
  ]
}
```

### Configurar acceso fiscal

Configura la identidad fiscal, carga el CSD y verifica la disponibilidad antes de crear CFDI.

#### Configura la identidad fiscal

Usa la identidad del emisor de tus datos fiscales, con el RFC que corresponda al CSD que cargarás. Actualiza una sección de configuración de la organización a la vez.

Guía de reintentos: Reutiliza el mismo Idempotency-Key únicamente para la misma carga de sección.

#### Carga el par CSD

Carga el certificado y la clave privada en base64; el material secreto nunca se devuelve.

Guía de reintentos: Reintenta con la misma clave y la carga de certificado sin cambios.

#### Verifica la disponibilidad

Lee la proyección de la organización y confirma la disponibilidad fiscal antes de emitir.

Guía de reintentos: Las lecturas se pueden repetir; no agregues un idempotency key.

```json
{
  "steps": [
    {
      "id": "update-fiscal-settings",
      "rest": {
        "operationId": "updateOrganization",
        "method": "PATCH",
        "path": "/v1/organization",
        "environments": [
          "production"
        ],
        "headers": {
          "Idempotency-Key": "workflow-fiscal-settings"
        },
        "body": {
          "section": "fiscal",
          "legalName": "Consultoría Bruma SA de CV",
          "rfc": "EKU9003173C9",
          "taxSystem": "601",
          "address": {
            "postalCode": "82110"
          }
        }
      },
      "mcp": {
        "tool": "update_organization",
        "arguments": {
          "idempotencyKey": "workflow-fiscal-settings",
          "input": {
            "section": "fiscal",
            "legalName": "Consultoría Bruma SA de CV",
            "rfc": "EKU9003173C9",
            "taxSystem": "601",
            "address": {
              "postalCode": "82110"
            }
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "upload-csd",
      "rest": {
        "operationId": "uploadCertificate",
        "method": "PUT",
        "path": "/v1/organization/certificates/csd",
        "environments": [
          "production"
        ],
        "headers": {
          "Idempotency-Key": "workflow-upload-csd"
        },
        "body": {
          "certificateBase64": "BASE64_CER",
          "privateKeyBase64": "BASE64_KEY",
          "password": "certificate-password",
          "certificateFileName": "certificate.cer",
          "privateKeyFileName": "private.key"
        }
      }
    },
    {
      "id": "verify-organization",
      "rest": {
        "operationId": "getOrganization",
        "method": "GET",
        "path": "/v1/organization",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_organization",
        "arguments": {},
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Emitir y enviar un CFDI en producción

Flujo de producción: configura la identidad fiscal y el CSD de la organización, agrega saldo a la cartera API/MCP y crea un cliente con RFC, razón social, régimen fiscal y domicilio postal. Usa ese contactId como customerId. Después crea un borrador, revísalo, timbra explícitamente ante el SAT y envía el documento.

#### Crea el borrador

La creación solo produce un borrador. No timbra ni envía el CFDI; revisa el borrador devuelto antes de cualquier transición explícita.

Guía de reintentos: Usa la misma clave para un reintento exacto; una carga modificada es una nueva solicitud.

#### Revisa el borrador

Usa el documentRef devuelto para revisar la proyección canónica del documento.

Guía de reintentos: Esta lectura se puede repetir y no lleva idempotency key.

#### Previsualiza el PDF del borrador (opcional)

Usa preview_pdf para revisar el documento renderizado antes de timbrar. La vista previa no tiene validez fiscal.

Guía de reintentos: Esta lectura de archivo se puede repetir y no lleva idempotency key.

#### Timbra ante el SAT

El timbrado es una transición irreversible separada. Revisa primero el borrador.

Guía de reintentos: Reintenta únicamente con la misma clave y documentRef; las fallas del proveedor pueden requerir recuperación.

#### Envía el CFDI

Envía por correo el CFDI timbrado y sus archivos fiscales a un destinatario explícito.

Guía de reintentos: Reutiliza la clave para el mismo destinatario y documento; el envío sigue siendo un efecto externo.

```json
{
  "steps": [
    {
      "id": "create-cfdi-draft",
      "rest": {
        "operationId": "createInvoiceDraft",
        "method": "POST",
        "path": "/v1/invoices",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-create-cfdi"
        },
        "body": {
          "customerId": "customer-example",
          "items": [
            {
              "kind": "custom",
              "description": "Consultoría administrativa · julio 2026",
              "quantity": 1,
              "unitPrice": 10000,
              "satProductCode": "84111506",
              "satUnitCode": "E48",
              "taxRate": 0.16,
              "taxability": "standard"
            }
          ],
          "kind": "income",
          "cfdiUse": "G03",
          "payment": {
            "timing": "deferred_or_installments",
            "formCode": "99",
            "conditions": "Crédito a 30 días"
          }
        }
      },
      "mcp": {
        "tool": "create_invoice_draft",
        "arguments": {
          "idempotencyKey": "workflow-create-cfdi",
          "input": {
            "customerId": "customer-example",
            "items": [
              {
                "kind": "custom",
                "description": "Consultoría administrativa · julio 2026",
                "quantity": 1,
                "unitPrice": 10000,
                "satProductCode": "84111506",
                "satUnitCode": "E48",
                "taxRate": 0.16,
                "taxability": "standard"
              }
            ],
            "kind": "income",
            "cfdiUse": "G03",
            "payment": {
              "timing": "deferred_or_installments",
              "formCode": "99",
              "conditions": "Crédito a 30 días"
            }
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "inspect-cfdi-draft",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:invoice-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:invoice-example"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "preview-cfdi-draft-pdf",
      "rest": {
        "operationId": "downloadDocumentFile",
        "method": "GET",
        "path": "/v1/documents/invoice:invoice-example/files/preview_pdf",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document_file",
        "arguments": {
          "documentRef": "invoice:invoice-example",
          "file": "preview_pdf"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "stamp-cfdi",
      "rest": {
        "operationId": "stampInvoice",
        "method": "POST",
        "path": "/v1/invoices/invoice:invoice-example/stamp",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-stamp-cfdi"
        },
        "body": {}
      },
      "mcp": {
        "tool": "stamp_invoice",
        "arguments": {
          "documentRef": "invoice:invoice-example",
          "idempotencyKey": "workflow-stamp-cfdi"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "send-cfdi",
      "rest": {
        "operationId": "sendDocument",
        "method": "POST",
        "path": "/v1/documents/invoice:invoice-example/send",
        "environments": [
          "production"
        ],
        "headers": {
          "Idempotency-Key": "workflow-send-cfdi"
        },
        "body": {
          "recipient": "administracion@jacaranda.example"
        }
      },
      "mcp": {
        "tool": "send_document",
        "arguments": {
          "idempotencyKey": "workflow-send-cfdi",
          "input": {
            "documentRef": "invoice:invoice-example",
            "recipient": "administracion@jacaranda.example"
          }
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Crear un complemento de pago

Registra uno o más pagos de una factura PPD. Exac distribuye los impuestos conocidos de la factura en cada pago parcial.

#### Revisa el CFDI relacionado

Usa taxes: "auto" cuando Exac tenga la factura timbrada. Para una factura externa desconocida, envía su taxObject SAT y los impuestos del pago; no se requiere importar XML.

Guía de reintentos: Esta lectura se puede repetir de forma segura.

#### Crea el borrador del complemento

En el primer pago usa installment 1 y el total de la factura como previousBalance. En pagos posteriores, incrementa installment y usa el saldo insoluto anterior. Exac resuelve los impuestos automáticos antes de crear el borrador.

Guía de reintentos: Reutiliza la misma clave solo para el mismo pago.

#### Revisa antes de timbrar

Confirma saldos, parcialidad e impuestos del pago en la proyección canónica del borrador.

Guía de reintentos: Esta lectura se puede repetir de forma segura.

#### Timbra el complemento

Timbra solo después de confirmar el UUID relacionado, la parcialidad, los saldos anterior, pagado e insoluto, y los impuestos proporcionales.

Guía de reintentos: Reutiliza la misma clave solo para el mismo borrador revisado y fecha de emisión.

```json
{
  "steps": [
    {
      "id": "inspect-related-cfdi",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:invoice-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:invoice-example"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "create-payment-complement-draft",
      "rest": {
        "operationId": "createInvoiceDraft",
        "method": "POST",
        "path": "/v1/invoices",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-create-payment-complement"
        },
        "body": {
          "kind": "payment_complement",
          "customerId": "customer-example",
          "payments": [
            {
              "formCode": "03",
              "paidLocalDateTime": "2026-07-15T12:00:00",
              "documents": [
                {
                  "uuid": "00000000-0000-4000-8000-000000000001",
                  "amount": 11600,
                  "installment": 1,
                  "previousBalance": 11600,
                  "taxes": "auto"
                }
              ]
            }
          ]
        }
      },
      "mcp": {
        "tool": "create_invoice_draft",
        "arguments": {
          "idempotencyKey": "workflow-create-payment-complement",
          "input": {
            "kind": "payment_complement",
            "customerId": "customer-example",
            "payments": [
              {
                "formCode": "03",
                "paidLocalDateTime": "2026-07-15T12:00:00",
                "documents": [
                  {
                    "uuid": "00000000-0000-4000-8000-000000000001",
                    "amount": 11600,
                    "installment": 1,
                    "previousBalance": 11600,
                    "taxes": "auto"
                  }
                ]
              }
            ]
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "inspect-payment-complement-draft",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:payment-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:payment-example"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "stamp-payment-complement",
      "rest": {
        "operationId": "stampInvoice",
        "method": "POST",
        "path": "/v1/invoices/invoice:payment-example/stamp",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-stamp-payment-complement"
        },
        "body": {}
      },
      "mcp": {
        "tool": "stamp_invoice",
        "arguments": {
          "documentRef": "invoice:payment-example",
          "idempotencyKey": "workflow-stamp-payment-complement"
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Convertir recibos en CFDI

Crea un borrador de CFDI a partir de ventas seleccionadas de recibos. El timbrado permanece como una operación explícita separada.

#### Crea el recibo

Usa un producto de catálogo con su identidad fiscal configurada. Sin productId, envía satProductCode y satUnitCode al crear este recibo pagado. Exac conserva los datos fiscales como se cobraron para facturar después.

Guía de reintentos: Reutiliza la misma clave solo para la venta idéntica.

#### Convierte los recibos

La operación valida la propiedad y conciliación de los recibos y devuelve un borrador de CFDI. No timbra ni envía el CFDI.

Guía de reintentos: Reintenta el mismo conjunto de recibos con la misma clave; nunca cambies el conjunto usando una clave existente.

#### Lee el CFDI resultante

Usa el documentRef de CFDI devuelto por la conversión para obtener el detalle canónico.

Guía de reintentos: Las lecturas se pueden repetir y no necesitan idempotency key.

```json
{
  "steps": [
    {
      "id": "create-invoiceable-receipt",
      "rest": {
        "operationId": "createSalesReceipt",
        "method": "POST",
        "path": "/v1/sales-receipts",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-create-invoiceable-receipt"
        },
        "body": {
          "saleType": "paid",
          "customer": {
            "kind": "stored",
            "customerId": "customer-example"
          },
          "items": [
            {
              "productId": "product-example",
              "description": "Servicio",
              "quantity": 1,
              "unitPrice": 1250
            }
          ],
          "paymentForm": "03"
        }
      },
      "mcp": {
        "tool": "create_sales_receipt",
        "arguments": {
          "idempotencyKey": "workflow-create-invoiceable-receipt",
          "input": {
            "saleType": "paid",
            "customer": {
              "kind": "stored",
              "customerId": "customer-example"
            },
            "items": [
              {
                "productId": "product-example",
                "description": "Servicio",
                "quantity": 1,
                "unitPrice": 1250
              }
            ],
            "paymentForm": "03"
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "create-cfdi-from-receipts",
      "rest": {
        "operationId": "createInvoiceDraftFromSalesReceipts",
        "method": "POST",
        "path": "/v1/invoices/from-sales-receipts",
        "environments": [
          "production",
          "sandbox"
        ],
        "headers": {
          "Idempotency-Key": "workflow-receipts-to-cfdi"
        },
        "body": {
          "salesReceiptRefs": [
            "sales_receipt:receipt-example"
          ],
          "customer": {
            "kind": "existing",
            "customerId": "customer-example"
          },
          "cfdiUse": "S01"
        }
      },
      "mcp": {
        "tool": "create_invoice_draft_from_sales_receipts",
        "arguments": {
          "idempotencyKey": "workflow-receipts-to-cfdi",
          "input": {
            "salesReceiptRefs": [
              "sales_receipt:receipt-example"
            ],
            "customer": {
              "kind": "existing",
              "customerId": "customer-example"
            },
            "cfdiUse": "S01"
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "read-converted-cfdi",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:invoice-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:invoice-example"
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Buscar y descargar un CFDI

Busca en la colección de CFDI con filtros fiscales, recupera un documento y descarga su PDF o XML.

#### Busca CFDI

Usa kind y paymentTiming en lugar de un filtro genérico de tipo de documento.

Guía de reintentos: Esta lectura se puede repetir y usa paginación por cursor para las páginas siguientes.

#### Recupera el CFDI

Usa la referencia opaca de CFDI devuelta por la colección.

Guía de reintentos: Las lecturas se pueden repetir y no necesitan idempotency key.

#### Descarga el PDF

La ruta REST devuelve un adjunto; la herramienta MCP devuelve un recurso binario.

Guía de reintentos: Las lecturas de archivos se pueden repetir y no necesitan idempotency key.

#### Descarga el XML

Usa el mismo documentRef para recuperar el XML fiscal cuando esté disponible.

Guía de reintentos: Las lecturas de archivos se pueden repetir y no necesitan idempotency key.

```json
{
  "steps": [
    {
      "id": "search-cfdis",
      "rest": {
        "operationId": "listInvoices",
        "method": "GET",
        "path": "/v1/invoices",
        "environments": [
          "production",
          "sandbox"
        ],
        "query": {
          "kind": "income",
          "status": "valid",
          "dateFrom": "2026-01-01",
          "dateTo": "2026-01-31",
          "limit": 20
        }
      },
      "mcp": {
        "tool": "search_documents",
        "arguments": {
          "input": {
            "category": "invoice",
            "kind": "income",
            "status": "valid",
            "dateFrom": "2026-01-01",
            "dateTo": "2026-01-31",
            "limit": 20
          }
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "get-cfdi",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:invoice-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:invoice-example"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "download-pdf",
      "rest": {
        "operationId": "downloadDocumentFile",
        "method": "GET",
        "path": "/v1/documents/invoice:invoice-example/files/pdf",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document_file",
        "arguments": {
          "documentRef": "invoice:invoice-example",
          "file": "pdf"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "download-xml",
      "rest": {
        "operationId": "downloadDocumentFile",
        "method": "GET",
        "path": "/v1/documents/invoice:invoice-example/files/xml",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document_file",
        "arguments": {
          "documentRef": "invoice:invoice-example",
          "file": "xml"
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Conciliar el estado CFDI con el SAT

Consulta al SAT el estado actual de un CFDI timbrado en producción después de una respuesta asíncrona o un resultado incierto. Este flujo no admite retenciones. Los documentos de prueba y simulados no se consultan ante el SAT; lee su estado almacenado.

#### Actualiza el estado ante el SAT

La actualización requiere datos de verificación capturados del XML fiscal y concilia el estado local.

Guía de reintentos: Reutiliza la misma clave para la misma observación del documento; es una lectura externa que cambia estado.

#### Lee el documento conciliado

Obtén el documento de nuevo para consumir el estado local canónico y la proyección de cancelación.

Guía de reintentos: Las lecturas se pueden repetir y no necesitan idempotency key.

```json
{
  "steps": [
    {
      "id": "refresh-cfdi-status",
      "rest": {
        "operationId": "refreshInvoiceStatus",
        "method": "POST",
        "path": "/v1/invoices/invoice:invoice-example/status/refresh",
        "environments": [
          "production"
        ],
        "headers": {
          "Idempotency-Key": "workflow-refresh-cfdi-status"
        },
        "body": {}
      },
      "mcp": {
        "tool": "refresh_invoice_status",
        "arguments": {
          "documentRef": "invoice:invoice-example",
          "idempotencyKey": "workflow-refresh-cfdi-status"
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "read-reconciled-cfdi",
      "rest": {
        "operationId": "getInvoice",
        "method": "GET",
        "path": "/v1/invoices/invoice:invoice-example",
        "environments": [
          "production",
          "sandbox"
        ]
      },
      "mcp": {
        "tool": "get_document",
        "arguments": {
          "documentRef": "invoice:invoice-example"
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

### Consultar reportes fiscales

Consulta por separado los agregados CFDI ya sincronizados y los totales autorizados de declaraciones.

#### Consulta los agregados CFDI

Los totales CFDI excluyen ventas de recibos/POS y son distintos de los totales fiscales declarados.

Guía de reintentos: Este reporte es de solo lectura y se puede repetir.

#### Consulta los totales declarados

Los totales fiscales provienen únicamente de declaraciones analizadas; si no están disponibles permanecen como null y no se estiman.

Guía de reintentos: Este reporte es de solo lectura y se puede repetir.

```json
{
  "steps": [
    {
      "id": "read-cfdi-summary",
      "rest": {
        "operationId": "getIncomeExpensesReport",
        "method": "GET",
        "path": "/v1/reports/income-expenses",
        "environments": [
          "production",
          "sandbox"
        ],
        "query": {
          "fiscalYear": 2026,
          "period": 1
        }
      },
      "mcp": {
        "tool": "get_income_expenses_summary",
        "arguments": {
          "fiscalYear": 2026,
          "period": 1
        },
        "environments": [
          "production"
        ]
      }
    },
    {
      "id": "read-tax-summary",
      "rest": {
        "operationId": "getTaxReport",
        "method": "GET",
        "path": "/v1/reports/taxes",
        "environments": [
          "production"
        ],
        "query": {
          "fiscalYear": 2026
        }
      },
      "mcp": {
        "tool": "get_tax_summary",
        "arguments": {
          "fiscalYear": 2026
        },
        "environments": [
          "production"
        ]
      }
    }
  ]
}
```

Documentación completa: https://exac.mx/docs.md
Índice para agentes: https://exac.mx/docs/llms.txt
