> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dialtu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errores

> Las dos formas de error y todos los códigos por endpoint

La API usa los códigos de estado HTTP habituales. El éxito es `200` (o `201` cuando se creó
algo). Cualquier otro estado viene con un cuerpo JSON en una de dos formas.

## Errores de aplicación: el sobre con `error_code`

Los errores que genera la lógica del propio endpoint — una regla de validación, un registro
inexistente, una operación rechazada — siempre tienen esta forma:

```json theme={null}
{
  "status": "error",
  "error_code": "UNKNOWN_SERVICE",
  "message": "No bookable service named 'Consultation'.",
  "details": { "valid_service_names": ["Consulta Médica", "Control"] }
}
```

<Note>
  **Decide por `error_code`, nunca por `message`.** Los mensajes están escritos para personas
  y pueden cambiar de redacción; los códigos son el contrato y no cambian. Los mensajes están
  en inglés.
</Note>

`details` es opcional y depende del endpoint: los de calendario lo usan para listar los valores
que *sí* se habrían aceptado (`valid_service_names`, `valid_professional_names`,
`matching_professional_ids`) o para nombrar el `field` problemático.

## Errores de plataforma: el cuerpo `detail`

Dos fallos ocurren antes de que se ejecute el endpoint y usan un cuerpo más simple:

<AccordionGroup>
  <Accordion title="401 — autenticación">
    ```json theme={null}
    { "detail": "Invalid or expired API key. Please check your credentials." }
    ```

    Clave ausente, mal formada, desconocida o eliminada. Ver [Autenticación](/es/api-reference/autenticacion).
  </Accordion>

  <Accordion title="422 — la solicitud no coincide con el esquema">
    ```json theme={null}
    {
      "detail": [
        { "type": "missing", "loc": ["body", "payload", "phone_number"], "msg": "Field required" },
        { "type": "int_parsing", "loc": ["query", "limit"], "msg": "Input should be a valid integer" }
      ]
    }
    ```

    Falta un campo obligatorio, un valor tiene el tipo equivocado o un número está fuera de su
    rango documentado (por ejemplo `limit` por encima del máximo). `loc` empieza por `body`,
    `query` o `path` y luego nombra el campo. Corrige los campos listados y reintenta.
  </Accordion>

  <Accordion title="404 — ruta o registro desconocido (algunos endpoints)">
    ```json theme={null}
    { "detail": "WhatsApp conversation 999999 not found" }
    ```

    Se devuelve para una URL que no existe, y en *List messages in a WhatsApp conversation*
    cuando tu clave no puede ver esa conversación.
  </Accordion>
</AccordionGroup>

## `500` — `INTERNAL_ERROR`

Algo falló de nuestro lado. La operación **no** se aplicó (no se encoló la llamada, no se creó
el contacto, no se agendó la cita), así que reintentar es seguro. Si persiste, contacta a
soporte con la solicitud que enviaste.

## Códigos de error por endpoint

### Llamadas (Calls)

| Estado | `error_code`           | Significado                                                                 |
| ------ | ---------------------- | --------------------------------------------------------------------------- |
| `400`  | `AGENT_NOT_FOUND`      | No hay un agente de voz con ese `agent_id` en tu cuenta.                    |
| `400`  | `INVALID_PHONE_NUMBER` | `phone_number` no es un número marcable. Envíalo en E.164 (`+15551234567`). |
| `400`  | `VALIDATION_ERROR`     | Otro campo fue rechazado; `message` indica cuál.                            |

### Contactos (Clients)

| Estado | `error_code`       | Significado                                                         |
| ------ | ------------------ | ------------------------------------------------------------------- |
| `400`  | `VALIDATION_ERROR` | No se envió ni `phone_number` ni `email`, o un valor fue rechazado. |
| `400`  | `DUPLICATE_CLIENT` | Ya existe un contacto con ese teléfono o correo.                    |

### Salesflow — ingreso (ingest)

| Estado | `error_code`           | Significado                                                                                                 |
| ------ | ---------------------- | ----------------------------------------------------------------------------------------------------------- |
| `404`  | `INPUT_NODE_NOT_FOUND` | No hay un nodo de entrada API activo con ese UUID. Comprueba que el nodo sea de tipo **API** y esté activo. |
| `404`  | `CLIENT_NOT_FOUND`     | `client_id` no existe en tu cuenta.                                                                         |
| `400`  | `VALIDATION_ERROR`     | No se envió ni `client_id` ni `phone_number`, o un valor fue rechazado.                                     |
| `400`  | `UNKNOWN_ERROR`        | El pipeline rechazó la entrada por otro motivo; lee `message`.                                              |

### Salesflow — ingreso por lotes (batch ingest)

El endpoint por lotes reporta la mayoría de los problemas **por fila** en `results[].errors[].code` (`required`, `invalid_format`, `too_long`, `duplicate_in_batch`, `not_found`, `exists`, `conflict`) con una respuesta `200`; los códigos de abajo aplican a la solicitud completa.

| Estado | `error_code`           | Significado                                                                                                                                                                                      |
| ------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `404`  | `INPUT_NODE_NOT_FOUND` | No hay un nodo de entrada API activo con ese UUID. Comprueba que el nodo sea de tipo **API** y esté activo.                                                                                      |
| `400`  | `VALIDATION_ERROR`     | El nodo de entrada no tiene etapa destino, o su pipeline no está activo.                                                                                                                         |
| `404`  | `STAGE_NOT_FOUND`      | `stage_id` no pertenece al pipeline del nodo de entrada.                                                                                                                                         |
| `400`  | `INGEST_ROLLED_BACK`   | Se envió `all_or_none` y al menos una fila falló; no se escribió nada. `details.summary` y `details.results` traen el resultado por fila (se omiten los ids de las filas que se habrían creado). |

### Salesflow — pipelines

| Estado | `error_code`         | Significado                                                                         |
| ------ | -------------------- | ----------------------------------------------------------------------------------- |
| `404`  | `PIPELINE_NOT_FOUND` | Esta clave no ve ningún pipeline con ese ID (*List API input nodes of a pipeline*). |
| `400`  | `CLIENTS_NOT_FOUND`  | Ninguno de los `client_ids` está activo en este pipeline.                           |
| `404`  | `CLIENT_NOT_FOUND`   | El cliente a mover no está activo en este pipeline.                                 |
| `400`  | `MOVE_NOT_ALLOWED`   | Las reglas de etapa del pipeline no permiten esa transición.                        |
| `404`  | `NOT_FOUND`          | La etapa destino no pertenece a este pipeline.                                      |

### Calendario — disponibilidad

| Estado | `error_code`    | Significado                                                                                              |
| ------ | --------------- | -------------------------------------------------------------------------------------------------------- |
| `400`  | `INVALID_PARAM` | `start_date` no es `YYYY-MM-DD`, `days` está fuera de 1–31, o una lista de IDs está mal formada o vacía. |

### Calendario — reservas

| Estado | `error_code`               | Significado                                                                                                             |
| ------ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `400`  | `SERVICE_REQUIRED`         | No se envió ni `service_id` ni `service_name`. `details.valid_service_names` lista tus opciones.                        |
| `400`  | `UNKNOWN_SERVICE`          | No hay un servicio reservable con ese ID o nombre.                                                                      |
| `400`  | `AMBIGUOUS_SERVICE`        | Varios servicios comparten ese nombre: envía `service_id`.                                                              |
| `400`  | `PROFESSIONAL_REQUIRED`    | No se envió ni `professional_id` ni `professional_name`.                                                                |
| `400`  | `UNKNOWN_PROFESSIONAL`     | Nadie con ese nombre está activo en el servicio.                                                                        |
| `400`  | `AMBIGUOUS_PROFESSIONAL`   | Varios miembros activos responden a ese nombre: envía `professional_id`; `details.matching_professional_ids` los lista. |
| `400`  | `PROFILE_NOT_IN_SERVICE`   | Ese `professional_id` no es miembro activo del servicio.                                                                |
| `400`  | `EVENT_TYPE_REQUIRED`      | No se envió ni `event_type_id` ni `event_type_name`.                                                                    |
| `400`  | `UNKNOWN_EVENT_TYPE`       | No hay un tipo de cita activo con ese ID o nombre.                                                                      |
| `400`  | `AMBIGUOUS_EVENT_TYPE`     | Varios tipos de cita coinciden con ese nombre: envía `event_type_id`.                                                   |
| `400`  | `INVALID_EVENT_TYPE`       | El servicio no ofrece ese tipo de cita.                                                                                 |
| `400`  | `SERVICE_UNAVAILABLE`      | El servicio no tiene miembros activos. Añade un profesional en Dialtu.                                                  |
| `400`  | `MISSING_FIELD`            | Falta `start_at`, `end_at` o `timezone`; `details.field` lo nombra.                                                     |
| `400`  | `INVALID_TIMEZONE`         | `timezone` no es una zona IANA.                                                                                         |
| `400`  | `INVALID_PHONE_NUMBER`     | `client.phone` falta o no es un número internacional posible.                                                           |
| `400`  | `CLIENT_NAME_REQUIRED`     | El teléfono es nuevo en tu cuenta y no se envió nombre.                                                                 |
| `400`  | `CLIENT_IDENTITY_CONFLICT` | Ese teléfono o correo pertenece a un contacto que esta clave no puede ver. Contacta a soporte.                          |
| `400`  | `DATA_MISSING`             | Al contacto encontrado le falta algo que la cita necesita; `details` lo nombra.                                         |
| `400`  | `VALIDATION_ERROR`         | `end_at` no es posterior a `start_at`, u otra regla fue rechazada.                                                      |
| `400`  | `FORBIDDEN_CALENDAR`       | La clave no puede reservar en ese calendario.                                                                           |
| `409`  | `SLOT_CONFLICT`            | Documentado por completitud: las reservas por API nunca se rechazan por conflicto.                                      |
| `422`  | `OUTSIDE_AVAILABILITY`     | Documentado por completitud: las reservas por API nunca se rechazan por disponibilidad.                                 |

### Calendario — listas de espera

| Estado | `error_code`                            | Significado                                                                                |
| ------ | --------------------------------------- | ------------------------------------------------------------------------------------------ |
| `400`  | `CLIENT_IDENTITY_REQUIRED`              | No se envió ni `client_id` ni `phone`.                                                     |
| `400`  | `SERVICES_REQUIRED`                     | No se envió ni `service_ids` ni `service_names`.                                           |
| `400`  | `UNKNOWN_SERVICE` / `SERVICE_NOT_FOUND` | Un servicio por nombre o ID no existe.                                                     |
| `400`  | `SERVICE_NOT_ON_WAITLIST`               | El `waitlist_id` indicado no cubre ese servicio.                                           |
| `400`  | `PROFESSIONAL_NOT_FOUND`                | `preferred_professional_id` no existe.                                                     |
| `400`  | `INVALID_PARAM`                         | Una fecha no es `YYYY-MM-DD`, un valor de filtro es desconocido o un rango está invertido. |
| `404`  | `CLIENT_NOT_FOUND`                      | `client_id` no existe en tu cuenta.                                                        |
| `404`  | `WAITLIST_NOT_FOUND`                    | `waitlist_id` no existe.                                                                   |
| `404`  | `ENTRY_NOT_FOUND`                       | No hay una entrada de lista de espera con ese ID.                                          |
| `409`  | `ENTRY_NOT_OPEN`                        | La entrada ya está reservada, eliminada o vencida.                                         |

### WhatsApp

| Estado | `error_code`               | Significado                                                                          |
| ------ | -------------------------- | ------------------------------------------------------------------------------------ |
| `400`  | `VALIDATION_ERROR`         | Valor inválido de `status`, `direction` o `sort_by`; `message` lista los permitidos. |
| `404`  | *(cuerpo `detail` simple)* | La conversación no existe en tu sub-cuenta.                                          |
