# Tipos y modelos

Los tipos de TypeScript y los modelos de Pydantic de los SDK para usuarios, tickets, archivos, errores, IA y paginación, con cada campo en los dos lenguajes.

Los dos SDK exportan los tipos de datos con los que trabajan: en JavaScript, interfaces y tipos de TypeScript; en Python, modelos de Pydantic. Esta página recoge los de los servicios básicos (usuarios, tickets, archivos, errores, IA y paginación). Los de facturación, cobros y suscripciones se describen en sus propias guías, con los campos que importan en cada paso.

## Cómo se importan

### JavaScript

```typescript
import type {
  CreateTicketInput,
  ExternalUser,
  PaginatedResponse,
  ReportErrorInput,
  TicketDetail,
  UtiliaSDKConfig,
} from '@utilia-os/sdk-js';
```

### Python

```python
from utilia_sdk import (
    CreateTicketInput,
    ExternalUser,
    PaginatedResponse,
    ReportErrorInput,
    TicketDetail,
)
```

En Python los campos van en `snake_case`, pero cada modelo conoce el nombre que usa la API (`external_id` viaja como `externalId`). Puedes construir un modelo con cualquiera de los dos nombres; al leerlo, usa el de Python. Las fechas llegan como cadenas ISO 8601 en los dos lenguajes, no como objetos de fecha.

## Usuarios

**`IdentifyUserInput`**: lo que mandas a `users.identify`.

| JavaScript | Python | Obligatorio | Qué es |
| - | - | - | - |
| `externalId` | `external_id` | Sí | Identificador en tu sistema, 255 caracteres como máximo. |
| `email` | `email` | No | Correo, con formato válido. |
| `name` | `name` | No | Nombre. |
| `avatarUrl` | `avatar_url` | No | Dirección de la imagen, 2048 caracteres como máximo. |
| `metadata` | `metadata` | No | Datos libres. |
| `taxId` | `tax_id` | No | NIF o CIF, 50 caracteres como máximo. |
| `billingAddress` | `billing_address` | No | `street`, `city`, `postalCode` (`postal_code`), `country` y `province` opcional. |
| `clientId` | `client_id` | No | Ficha de cliente que tu aplicación creó antes. |

**`ExternalUser`**: el usuario que devuelve el servicio. Campos: `id`, `appId` (`app_id`), `externalId`, `email`, `name`, `avatarUrl`, `metadata`, `clientId`, `lastSeenAt` (`last_seen_at`) y, cuando viene, el número de tickets en `_count.tickets` (en Python, `count.tickets`, del modelo `UserTicketCount`).

## Tickets

Enumerados:

| Tipo | Valores |
| - | - |
| `TicketStatus` | `OPEN`, `IN_REVIEW`, `CONVERTED`, `RESOLVED`, `CLOSED` |
| `TicketCategory` | `BUG`, `CONSULTA`, `SUGERENCIA` (se acepta `PROBLEMA` como alias de `BUG`) |
| `TicketPriority` | `BAJA`, `MEDIA`, `ALTA`, `CRITICA` |

En Python son `Enum` de texto (`TicketCategory.BUG`), y los modelos aceptan también la cadena (`"BUG"`).

**`CreateTicketInput`**:

| JavaScript | Python | Obligatorio | Qué es |
| - | - | - | - |
| `user` | `user` | Sí | `CreateTicketUser`: `externalId` obligatorio; `email`, `name` y `metadata` opcionales. |
| `title` | `title` | Sí | De 5 a 500 caracteres. |
| `description` | `description` | Sí | 10 caracteres como mínimo. |
| `category` | `category` | No | `TicketCategory`. |
| `priority` | `priority` | No | `TicketPriority`. |
| `context` | `context` | No | `TicketContext`: `url`, `appVersion` (`app_version`), `browserInfo` (`browser_info`) y `customData` (`custom_data`). |
| `attachmentIds` | `attachment_ids` | No | Archivos ya subidos. |

**Otros tipos de tickets:**

| Tipo | Campos |
| - | - |
| `TicketFilters` | `status`, `page`, `limit` (100 como máximo). |
| `AddMessageInput` | `content` (de 1 a 5000 caracteres) y `attachmentIds`. |
| `CreatedTicket` | `id`, `ticketKey`, `title`, `status`, `createdAt`. |
| `TicketListItem` | `id`, `ticketKey`, `title`, `category`, `priority`, `status`, `unreadByExternal`, `createdAt`, `lastActivityAt`. |
| `TicketDetail` | Lo anterior más `description`, `messages`, `attachments`, `context` y `reporter` (`name` y `email`). |
| `TicketMessage` | `id`, `content`, `author`, `attachments`, `createdAt`. |
| `MessageAuthor` | `type` (`EXTERNAL` si escribe la persona, `INTERNAL` si escribe el equipo), `id`, `name`. |
| `TicketAttachment` | `id`, `filename`, `mimeType`, `size` en bytes. |
| `CreatedMessage` | `id`, `content`, `createdAt`. |
| `UnreadCount` | `count`. |

## Archivos

| Tipo | Campos |
| - | - |
| `UploadFileOptions` (solo JavaScript; en Python son argumentos de `upload`) | `name` (255 caracteres como máximo), `metadata` y `onProgress`. |
| `UploadedFile` | `id`, `originalName`, `mimeType`, `size`, `downloadUrl`, `createdAt`. |
| `FileQuota` | `usedBytes`, `maxBytes`, `maxFileSizeBytes`, `usagePercent`. |

## Errores notificados

| Tipo | Campos o valores |
| - | - |
| `ErrorSeverity` | `critical`, `high`, `medium`, `low`. |
| `ErrorHttpMethod` | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`. |
| `ReportErrorInput` | `message` y `module` obligatorios; `severity`, `stack`, `file`, `line`, `function`, `endpoint`, `method`, `userId`, `requestId`, `context` y, desde la 4.6.0, `release`, `environment`, `fingerprint` y `tags`. |
| `ReportedError` | `success`, `hash`, `deduplicated` y, desde la 4.6.0, `accepted`, `status`, `reason` y `count`, opcionales en el tipo. |
| `ReportErrorBatchResult` | `received`, `accepted` y `results`, cada uno un `ReportErrorBatchItemResult` con `index`, `accepted`, `status`, `reason` y `hash`. |
| `ErrorReportStatus` (solo JavaScript) | `created`, `updated`, `regressed`. |
| `ErrorReportRejection` y `ErrorBatchItemRejection` (solo JavaScript) | Los valores de `reason`: `rate_limited`, `quota_exhausted`, `overloaded` y `discarded_expected`; en un lote, además, `storage_failed`. |
| `ErrorTagValue` (solo JavaScript) | Valor de una etiqueta: texto, número o booleano. |
| `SystemError` (en Python, `SystemErrorEntry`) | `id`, `hash`, `message`, `module`, `severity`, `file`, `line`, `endpoint`, `count`, `firstOccurrence`, `lastOccurrence`, `resolved`, `resolvedAt` y, desde la 4.6.0 y opcionales, `status`, `silencedUntil`, `environment`, `firstRelease`, `lastRelease`, `regressionCount` y `lastRegressedAt`. |
| `SystemErrorStatus` (solo JavaScript) | `active`, `resolved`, `silenced`. |
| `SystemErrorDetail` | Lo de `SystemError` más `stack`, `function`, `method`, `context`, `resolutionNote`, `lastRequestId`, `linkedTicket` y `linkedIssue`, estos dos un `LinkedErrorReference` (`id` y `key`) o vacíos. |
| `ErrorFilters` | `severity` (una o una lista en JavaScript; una lista en Python), `status`, `firstRelease` (`first_release`), `module`, `resolved`, `limit`, `offset`, `from` y `to` (en Python, `from_date` y `to_date`). |
| `ErrorStats` | `total`, `unresolved`, `silenced` (opcional), `bySeverity`, `byModule` y `topErrors` (cada uno con `hash`, `message`, `count` y `severity`; en Python, modelo `TopError`). |
| `ResolveErrorResult`, `ReopenErrorResult` y `SilenceErrorResult` | `hash` y, respectivamente, `resolved` y `alreadyResolved`, `alreadyOpen`, o `silencedUntil`. |
| `ErrorCaptureResult` | Lo que resuelve `capture`: `accepted`, `status`, `reason` (también `storage_failed`) y `hash`. |
| `ErrorCaptureInstallOptions` (solo JavaScript; en Python son argumentos de `install`) | `release`, `environment`, `module`, `tags`, `captureUnhandled`, `beforeSend`, `sampleRate`, `maxQueue` y `flushIntervalMs`. |
| `ErrorCaptureOptions` (solo JavaScript; en Python son argumentos de `capture_exception`) | `module`, `severity`, `context`, `tags`, `fingerprint`, `userId`, `requestId`, `endpoint` y `method`. |
| `ErrorCaptureEvent` (solo JavaScript) | El error que recibe `beforeSend`: un `ReportErrorInput`. |

Qué hace cada uno está en [Capturar los errores de tu aplicación](https://os.utilia.ai/docs/developers/sdk/error-reporting).

## IA

| Tipo | Campos |
| - | - |
| `AiSuggestInput` | `userId` obligatorio; `text`, `audioBase64`, `audioFilename`, `existingFields` e `images` (hasta 5, cada una `ImageBase64` con `base64`, `filename` y `mimeType`). |
| `AiSuggestions` | `title`, `description`, `category`, `priority`; cualquiera puede venir vacío. |
| `AiJobStatus` | `status` (`pending`, `processing`, `completed`, `failed`, `not_found`), `progress`, `result` y `error`. |
| Resultado (en Python, `AiJobResult`) | `transcription`, `suggestions` y `analyticsEventId`. |
| `TranscriptionJobStatus` | `status` (`pending`, `processing`, `completed`, `failed`), `progress`, `transcription` y `error`. |
| `TrackAiActionInput` | `eventId` y `userAction` obligatorios; `fieldsAccepted`, `fieldsModified`, `fieldsRejected`, `timeToDecisionMs` y `source`. |
| `SseEvent` | `event` (`progress`, `completed`, `failed`, `heartbeat`), `progress`, `status`, `result` y `error`. |
| `GetSuggestionsOptions` | Intervalo y espera máxima: `pollInterval` y `maxWait` en milisegundos, más `onProgress` (JavaScript); `poll_interval` y `max_wait` en segundos (Python). |
| `StreamSuggestionsOptions` y `StreamTranscriptionOptions` | `onProgress`, `onError` y `timeout` (milisegundos en JavaScript; en Python son alias de `SseStreamOptions`, con el tiempo en segundos). |
| `StreamSuggestionsHandle` | `result` y `abort`. |
| `ReportClientErrorParams` (solo Python; en JavaScript es un objeto literal) | `message` obligatorio; `stack`, `code`, `component`, `context`, `endpoint`, `method`, `request_id`, `url`, `user_agent` y, desde la 4.6.0, `release` y `environment`. |

## Paginación y configuración

| Tipo | Campos |
| - | - |
| `PaginatedResponse<T>` (en Python, `PaginatedResponse[T]`) | `data` y `pagination`. |
| `PaginationMeta` | `page`, `limit`, `total`, `totalPages` y, si vienen, `hasNextPage` y `hasPreviousPage`. |
| `UtiliaSDKConfig` | Las opciones del cliente: ver [Configurar el cliente](https://os.utilia.ai/docs/developers/sdk/configuration). |
| `RequestConfig` (solo JavaScript) | Opciones de una petición concreta: `retryAttempts`, `headers`, `params`, `responseType` y `data`. |

No todas las respuestas paginadas usan esta forma: las facturas, las suscripciones, los cobros programados y las autorizaciones de cobro tienen la suya, descrita en cada guía.

## Errores del SDK

`UtiliaSDKError`, el enumerado `ErrorCode` y el contexto de plan (`PlanErrorContext`) se explican en [Gestionar errores](https://os.utilia.ai/docs/developers/sdk/error-handling) y [Errores de plan](https://os.utilia.ai/docs/developers/sdk/plan-errors). Las constantes `SDK_LIMITS`, en [Límites y validaciones](https://os.utilia.ai/docs/developers/sdk/limits).
