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

# Configuración y errores

> Autenticación, acceso al espacio, dominios, control de solicitudes y solución de problemas

## Configurar un cliente

```typescript theme={null}
import { Famulor } from 'famulor-sdk';

const client = new Famulor({
  apiKey: process.env.FAMULOR_API_KEY,
  baseUrl: 'https://app.famulor.io/api/v1',
  timeoutMs: 90_000,
  maxRetries: 2,
});
```

| Opción | Valor por defecto | Función |
| - | - | - |
| `apiKey` | — | Clave API del espacio de trabajo. Usa esta opción o `accessToken`, exactamente una. |
| `accessToken` | — | Token OAuth o función que lo devuelva de forma síncrona o asíncrona. |
| `baseUrl` | `https://app.famulor.io/api/v1` | URL base completa, con `/api/v1`. Usa HTTPS para tu aplicación alojada. |
| `timeoutMs` | `90000` | Plazo de la solicitud completa, con autenticación, reintentos, pausas y lectura de la respuesta, en milisegundos. |
| `maxRetries` | `2` | Máximo de intentos adicionales para lecturas compatibles. `0` desactiva los reintentos. |
| `fetch` | `fetch` del entorno | Implementación Fetch compatible opcional para integraciones de servidor o pruebas. |

El SDK no lee las variables de entorno por sí mismo. En estos ejemplos, tu aplicación pasa la credencial desde `process.env`.

## Tokens de acceso OAuth

Para una aplicación que actúe en nombre de un usuario, proporciona `accessToken` en lugar de `apiKey`. Una función puede recuperar el token actual antes de una solicitud:

```typescript theme={null}
import { Famulor } from 'famulor-sdk';

const client = new Famulor({
  accessToken: async () => {
    const token = process.env.FAMULOR_ACCESS_TOKEN;
    if (!token) throw new Error('An OAuth access token is required.');
    return token;
  },
});

const { data } = await client.assistants.list({ limit: 10 });
console.log(data.length);
```

Este ejemplo lee un token ya proporcionado al servidor. Para una integración de producción, sustituye esa lectura por tu almacenamiento de tokens y lógica de renovación del servidor. El SDK no ejecuta el consentimiento OAuth ni renueva los tokens. Consulta [Requisitos de clientes OAuth](/es/api-reference/introduction).

Las solicitudes OAuth respetan la pertenencia actual del usuario al espacio, su rol y los permisos aprobados. Las claves API siguen su propio espacio, estado y permisos. Acceso a la API es necesario en ambos casos. No proporciones ambas opciones de autenticación.

## Tiempos de espera y cancelación

Los valores del cliente se aplican a todas las operaciones. Pasa `timeoutMs`, `maxRetries` o `signal` en el último argumento, después de las entradas del método, para ajustar una solicitud. En los métodos generados de `client.api`, es el segundo argumento; los métodos abreviados pueden colocarlo en primera, segunda o tercera posición. Consulta [Ejemplos de opciones](/es/sdk/usage#ajustar-una-solicitud). El plazo cubre toda la solicitud, incluida la obtención del token, los reintentos, las pausas y la lectura de la respuesta. Un `AbortSignal` permite cancelarla antes.

```typescript theme={null}
const controller = new AbortController();

const pending = client.calls.list(
  { limit: 10 },
  { signal: controller.signal, timeoutMs: 10_000, maxRetries: 0 },
);

controller.abort();

try {
  await pending;
} catch (error) {
  if (!controller.signal.aborted) throw error;
}
```

Cancelar detiene la espera de la respuesta. No deshace una acción que el servidor ya haya aceptado.

## Comportamiento de los reintentos

Las solicitudes **GET y HEAD** compatibles pueden repetirse tras un fallo de red o HTTP `429`, `502`, `503` o `504`. El SDK respeta `Retry-After` cuando está presente y, en caso contrario, usa pausas crecientes limitadas.

**Las escrituras nunca se repiten automáticamente**, incluso tras una limitación de solicitudes. Aumentar `maxRetries` no habilita los reintentos de escritura. Esto evita duplicar accidentalmente llamadas, mensajes y compras de recursos.

<Warning>
  Un tiempo de espera agotado o una conexión perdida después de una escritura puede dejar su resultado desconocido. Comprueba el recurso, el historial de llamadas o el webhook antes de repetir la acción. Una cabecera de idempotencia arbitraria no hace que todas las operaciones puedan repetirse de forma segura.
</Warning>

## Gestionar errores

```typescript theme={null}
import {
  Famulor,
  FamulorApiError,
  FamulorNetworkError,
  FamulorTimeoutError,
} from 'famulor-sdk';

const client = new Famulor({ apiKey: process.env.FAMULOR_API_KEY });

try {
  const { data } = await client.assistants.list({ limit: 10 });
  console.log(data.length);
} catch (error) {
  if (error instanceof FamulorApiError) {
    console.error({
      status: error.status,
      code: error.code,
      message: error.message,
      requestId: error.requestId,
      retryAfter: error.retryAfter,
    });
  } else if (error instanceof FamulorTimeoutError) {
    console.error('Request timed out.', error.mayHaveExecuted);
  } else if (error instanceof FamulorNetworkError) {
    console.error('Network request failed.', error.mayHaveExecuted);
  } else {
    throw error;
  }
}
```

| Error | Significado |
| - | - |
| `FamulorApiError` | La API devolvió un error. Consulta `status`, `code`, `message`, `requestId` y, si existe, `retryAfter` en segundos. |
| `FamulorNetworkError` | No se pudo obtener una respuesta. `mayHaveExecuted` indica que una escritura podría haber llegado al servidor. |
| `FamulorTimeoutError` | Se agotó el tiempo de espera del SDK. Extiende `FamulorNetworkError`; compruébalo primero si gestionas los tiempos de espera por separado. |
| `FamulorAbortError` | Tu `AbortSignal` canceló la solicitud. Una escritura ya aceptada puede ejecutarse igualmente. |
| `FamulorResponseError` | La respuesta no se puede descodificar o no tiene la estructura de paginación esperada. Comprueba `mayHaveExecuted` antes de repetir una escritura. |
| `FamulorError` | Error base del SDK, también usado para configuración local o parámetros inválidos. |

No registres credenciales ni cuerpos completos de solicitudes sensibles. Un ID de solicitud, si está disponible, ayuda al soporte a encontrar el fallo.

## Solución de problemas

| Síntoma | Qué comprobar |
| - | - |
| `401` | Comprueba que se proporciona la clave correcta o un token OAuth actual, sin revocación ni caducidad. |
| `403 api_access_required` | Activa Acceso a la API mediante el plan del espacio o un complemento. |
| Otro `403` | Comprueba los permisos necesarios, el rol y el acceso a funciones del espacio. El SDK no elude estos controles. |
| `404` | Confirma que el ID existe en el espacio de la credencial. Los recursos de otros espacios no son accesibles. |
| `429` | Respeta `retryAfter`, reduce la concurrencia y evita consultas frecuentes. Más claves no aumentan el presupuesto compartido. |
| Falla la creación de una llamada | Comprueba que el asistente está activo, tiene un número para llamadas salientes, dispone de créditos y puede llamar al destino. |
| Error de red o de tiempo de espera después de escribir | Comprueba si la acción ocurrió antes de repetirla. |
| Se rechaza la importación en el navegador | Lleva el SDK al backend. Para conversaciones web, usa el [Widget web](/es/web-widget). |

Comprueba las mismas credenciales de forma independiente con la [CLI](/es/cli/overview):

```bash theme={null}
famulor doctor
famulor list-assistants --limit 10
```

Consulta la [Referencia de la API REST](/es/api-reference/introduction) para el comportamiento HTTP y los permisos. Para conexiones de herramientas de IA, usa la [Guía MCP](/es/mcp/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.