import { Aside, CardGrid, LinkCard } from "@astrojs/starlight/components";

El payload de emisión (`POST /ecf`) tiene decenas de campos anidados.
En lugar de reconstruirlo a mano, puedes usar los modelos ya escritos en tu
lenguaje: se generan automáticamente desde el mismo documento OpenAPI que
alimenta la [Referencia de API](/referencia-api/), así que siempre coinciden
con lo que la API acepta y devuelve.

<CardGrid>
  <LinkCard
    title="TypeScript"
    href="/sdk-modelos/typescript/"
    description="Interfaces para Node, Bun o el navegador."
  />
  <LinkCard
    title="Python"
    href="/sdk-modelos/python/"
    description="Dataclasses sin dependencias externas."
  />
  <LinkCard
    title="C#"
    href="/sdk-modelos/csharp/"
    description="Records con System.Text.Json."
  />
  <LinkCard
    title="PHP"
    href="/sdk-modelos/php/"
    description="Clases 8.1 con propiedades readonly."
  />
</CardGrid>

## Descargas

| Recurso                  | Descarga                                                                                 |
| ------------------------ | ---------------------------------------------------------------------------------------- |
| Documento OpenAPI (JSON) | <a href="/openapi/novafe-public.json" download>novafe-public.json</a>                    |
| Modelos TypeScript (zip) | <a href="/models/novafe-models-typescript.zip" download>novafe-models-typescript.zip</a> |
| Modelos Python (zip)     | <a href="/models/novafe-models-python.zip" download>novafe-models-python.zip</a>         |
| Modelos C# (zip)         | <a href="/models/novafe-models-csharp.zip" download>novafe-models-csharp.zip</a>         |
| Modelos PHP (zip)        | <a href="/models/novafe-models-php.zip" download>novafe-models-php.zip</a>               |

Cada zip trae un archivo por área de la API (`ecf`, `sequences`, `webhooks`,
`received-ecf`, `organizations`, entre otros) más `common`, con los tipos que
comparten varias áreas.

## Qué incluyen y qué no

Los modelos describen la **forma** de cada request y respuesta. Antes de usarlos
conviene tener presente:

- **La obligatoriedad de los campos depende del tipo de e-CF.** Los modelos
  marcan como requeridos solo los campos que lo son siempre (`type` y `lines` en
  la emisión). El resto es opcional en el modelo aunque un tipo concreto lo
  exija: consulta la
  [matriz de obligatoriedad por tipo](/emision/tipos-soportados/) y usa
  [validar sin emitir](/emision/validar-sin-emitir/) para comprobar tu payload.
- **Las fechas son texto.** El payload usa `dd-MM-yyyy` (por ejemplo
  `15-03-2026`) y las respuestas traen fecha y hora con la zona horaria de
  República Dominicana. Los modelos las dejan como `string` a propósito.
- **Los montos aceptan número o texto.** La API acepta `2360.5` y `"2360.5"`.
  Los modelos usan el tipo decimal de cada lenguaje cuando existe (Python
  serializa `Decimal` como texto para no perder precisión).
- **Los códigos van como texto o entero, no como enumeración.** Los valores
  permitidos (por ejemplo el `kind` de una línea o el tipo de pago) están en el
  comentario de cada campo y en la [Referencia de API](/referencia-api/).

## Genera un cliente completo con herramientas oficiales

Si prefieres un SDK con cliente HTTP y no solo modelos, alimenta cualquiera de
estas herramientas con el documento OpenAPI descargable:

```bash
# TypeScript (tipos)
npx openapi-typescript novafe-public.json -o novafe.d.ts

# Python (modelos Pydantic)
datamodel-codegen --input novafe-public.json --output novafe_models.py

# C# (cliente completo)
dotnet tool install -g NSwag.ConsoleCore
nswag openapi2csclient /input:novafe-public.json /output:NovaFEClient.cs

# PHP (u otro lenguaje) con OpenAPI Generator
openapi-generator-cli generate -i novafe-public.json -g php -o novafe-php
```

<Aside type="note" title="El servidor de ejemplo">
  El documento declara `https://api.novafe.example` como servidor. Reemplázalo
  por la URL real de tu ambiente al configurar el cliente.
</Aside>

## Cómo se mantienen actualizados

Los archivos de esta sección se regeneran en cada publicación del manual a
partir del documento OpenAPI vigente, por lo que no requieren mantenimiento
manual. Si algo de la API cambia, cambia aquí en la misma publicación.