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

# Línea de comandos (ryvo)

> Instala la CLI de Ryvo, entra con una llave de API, maneja agentes, llamadas y campañas desde la terminal, y conecta el servidor MCP de Ryvo a Claude Code, Cursor, VS Code o Windsurf.

`ryvo` es la línea de comandos oficial de la [API de Ryvo](/es/api-reference). Cada comando es una capa fina y tipada sobre un endpoint público, así que puede hacer exactamente lo que tu llave permite y nada más.

## Instalar

Node.js 20 o superior.

<CodeGroup>
  ```bash npm theme={null}
  npm install -g @ryvo-so/cli
  ryvo --help
  ```

  ```bash npx (sin instalar) theme={null}
  npx @ryvo-so/cli --help
  ```
</CodeGroup>

## Entrar

La CLI usa una llave de API normal. **No puede crear llaves**: la API no lo permite a propósito, para que una llave filtrada nunca pueda fabricar otra. Crea la llave en el portal, en **Configuración → API keys** ([app.ryvo.so/configuracion/api-keys](https://app.ryvo.so/configuracion/api-keys)), con los mínimos scopes que necesites, y luego:

```bash theme={null}
ryvo login                    # pega la llave (no se ve al escribir)
ryvo whoami                   # cuenta, plan y scopes de la llave
```

`ryvo login` comprueba la llave con `GET /v1/me` antes de guardarla. Se guarda en `~/.config/ryvo/config.json` (`%APPDATA%\ryvo\config.json` en Windows) con permisos `0600` donde el sistema los respeta. Nunca se imprime entera: sólo su prefijo (`ryvo_live_abc123...`).

En CI, en contenedores o con un gestor de secretos, sáltate el archivo y pon la llave en el entorno. **`RYVO_API_KEY` siempre gana sobre la llave guardada**:

```bash theme={null}
export RYVO_API_KEY=ryvo_live_...
echo "$RYVO_API_KEY" | ryvo login --with-token   # o guárdala desde stdin
```

`ryvo logout` borra la llave guardada en esta máquina. No la revoca; eso se hace en el portal.

## Comandos

| Grupo | Qué cubre |
| - | - |
| `ryvo agents` | `list`, `get`, `create`, `update`, `publish`, `archive`, `versions`, `version` |
| `ryvo calls` | `list`, `get`, `transcript`, `audio`, `create` |
| `ryvo conversations` | `list`, `get`, `messages` |
| `ryvo campaigns` | `list`, `get`, `create`, `cancel` (llamadas en lote) |
| `ryvo webhooks` | `list`, `get`, `create`, `update`, `delete`, `rotate-secret`, `deliveries`, `delivery`, `retry`, `events` |
| `ryvo knowledge` | `list`, `get`, `add-url`, `upload`, `update`, `delete`, `usage`, `folders ...` |
| `ryvo phone-numbers` | `list`, `get`, `import`, `update`, `delete` |
| `ryvo billing` | `plan`, `credits`, `transactions`, `invoices`, `usage`, `price` |
| `ryvo voices`, `ryvo models` | la biblioteca de voces y el catálogo de modelos (`models` no pide llave) |
| `ryvo integrations`, `ryvo team`, `ryvo logs` | vistas de sólo lectura |
| `ryvo api` | cualquier endpoint, en crudo (ver abajo) |
| `ryvo mcp install` | conecta el servidor MCP a tu cliente de IA |

`ryvo <grupo> --help` lista las opciones de cada comando. Algunos ejemplos:

```bash theme={null}
ryvo agents list --runtime engine
ryvo calls list --from 2026-09-01 --status failed --all
ryvo calls transcript 0f1e2d3c-4b5a-4968-8776-655443322110
ryvo knowledge upload ./precios-2026.pdf --title "Lista de precios 2026"
ryvo billing price --tts elevenlabs:eleven_flash_v2_5 --llm anthropic:claude-haiku-4-5
```

### Comandos que gastan créditos

`ryvo calls create` hace una llamada telefónica real y `ryvo campaigns create` lanza una llamada por destinatario. Los dos:

* **piden confirmación** antes de mandar nada. En scripts pasa `--yes`; sin terminal y sin `--yes` se niegan en vez de adivinar.
* **siempre mandan una `Idempotency-Key`** (un uuid nuevo salvo que pases `--idempotency-key`) y la imprimen, para que un reintento tras un timeout la reutilice y nunca marque dos veces. Mira [Idempotencia](/es/idempotency).

```bash theme={null}
ryvo calls create --agent 4d0f3c2a-6b7e-4a1c-9f2d-1e2b3c4d5e6f --to +5215555550100 --var lead_name=Juan
ryvo campaigns create --name "Seguimiento de septiembre" --agent <agent_id> --recipients numeros.csv
```

`--recipients` acepta un arreglo JSON de destinatarios o un archivo de texto o CSV con un número E.164 por línea. La protección de verdad es el tope de créditos de la llave, que se pone en el portal.

### Paginación

Toda lista acepta `--limit` (1 a 100) y `--cursor`. `--all` sigue `next_cursor` hasta la última página, de 100 en 100. Sin `--all`, la CLI imprime el siguiente cursor cuando hay más.

### La salida de emergencia: `ryvo api`

Como `gh api`: cualquier método y ruta, con tu llave, los reintentos y los códigos de salida, imprimiendo el JSON tal cual.

```bash theme={null}
ryvo api GET /v1/models
ryvo api GET /v1/calls -q status=failed -q limit=5
ryvo api PATCH /v1/agents/<id> --data '{"name":"Recepción"}'
ryvo api POST /v1/batch-calls --data @campana.json -H Idempotency-Key:campana-0929
```

Sólo acepta rutas, nunca URLs completas, así que la llave sólo viaja a la API de Ryvo. En Git Bash escribe `v1/models` sin la barra inicial (Git Bash reescribe las rutas que empiezan con `/`).

## Salida JSON y códigos de salida

Por omisión salen tablas para leer, que pueden cambiar entre versiones. Para scripts, añade `--json`: imprime la respuesta de la API exactamente como la documenta la [referencia](/es/api-reference). Con `--json`, los errores salen por stderr como `{ "error", "message", "request_id", "exit_code" }`.

Todo error imprime el `request_id` de la API: cítalo cuando nos escribas. Las respuestas `429` y `503` se reintentan hasta 3 veces, respetando `Retry-After` (o `X-RateLimit-Reset`), y nunca esperando más de un minuto. Mira [Límites de uso](/es/rate-limits).

El código de salida sale del `error` de la API, para que un script pueda ramificar sin leer texto:

| Código | Significa | `error` de la API |
| - | - | - |
| `0` | Éxito | |
| `1` | Error sin clasificar, o contestaste que no a una confirmación | |
| `2` | Uso incorrecto: falta una opción, JSON inválido, hace falta `--yes` | |
| `3` | Sin llave, o la llave es inválida, caducó o se revocó | `unauthorized` |
| `4` | La llave o el plan no lo permiten | `forbidden`, `insufficient_scope`, `plan_limit` |
| `5` | No existe | `not_found`, `agent_not_found` |
| `6` | La petición no pasó la validación | `invalid_json`, `invalid_body`, `invalid_query`, `invalid_idempotency_key` |
| `7` | Choca con el estado actual | `conflict`, `unsupported_runtime`, `idempotency_conflict`, `idempotency_in_progress`, `agent_not_published`, `no_phone_number`, `agent_disabled` |
| `8` | Hace falta pagar | `payment_required`, `key_budget_exhausted` |
| `9` | Límite de uso, todavía excedido después de reintentar | `rate_limit_exceeded` |
| `10` | Error del servidor o del proveedor | `internal_error`, `upstream_error`, `rate_limit_unavailable`, ... (5xx) |
| `11` | No se pudo llegar a la API (red, DNS, TLS) | |

Un código que la CLI todavía no conoce cae por su status HTTP (por ejemplo, cualquier `402` es `8`).

## Conectar el servidor MCP

`ryvo mcp install` añade el servidor MCP de Ryvo (`https://mcp.ryvo.so`) a tu cliente de IA, para que el asistente pueda leer tus agentes, llamadas y campañas.

```bash theme={null}
ryvo mcp install --client claude     # Claude Code, ~/.claude.json
ryvo mcp install --client cursor     # ~/.cursor/mcp.json
ryvo mcp install --client vscode     # el mcp.json de tu perfil de VS Code
ryvo mcp install --client windsurf   # Windsurf (Devin Desktop), mcp_config.json
```

Añade `--scope project` para escribir el archivo del proyecto (`.mcp.json`, `.cursor/mcp.json` o `.vscode/mcp.json`), `--config <ruta>` para elegir el archivo y `--dry-run` para ver el resultado sin escribir.

* **Mezcla**: los demás servidores y ajustes del archivo se conservan, y antes se escribe un respaldo con fecha (`<archivo>.bak-20260929T123456Z`). Un archivo con comentarios no se toca y se imprime la entrada para que la pegues.
* **La llave nunca se escribe en el archivo.** Claude Code, Cursor y Windsurf la leen de la variable de entorno `RYVO_API_KEY` del cliente; VS Code la pide una vez y la guarda cifrada.

<Warning>
  Usa una **llave de sólo lectura** para el MCP (`agents:read`, `calls:read`, `conversations:read` y los demás scopes `:read`), con tope de créditos. El asistente lee transcripciones de llamadas, que son texto escrito por terceros; una llave que las lee sin supervisión no debe llevar `calls:write` ni `campaigns:write`. `ryvo mcp install` te avisa cuando la llave actual los lleva.
</Warning>
