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

# Configurar el softphone de navegador (WebRTC)

> Dé a sus agentes una superficie de llamada completa dentro de su navegador — del softphone integrado del dashboard a un cliente SIP embebido en su propia app — con control de caller-ID, credenciales rotables y una ruta de push móvil para llamadas entrantes.

## Nota de idioma

Esta versión en español es una traducción abreviada: las secciones «1. Device registration & VoIP push tokens (mobile)» y «3. Choose how inbound calls reach the softphone» existen solo en inglés: [/en/guides/voice-softphone-browser-calling](https://docs.orbit.devotel.io/en/guides/voice-softphone-browser-calling). Los bloques de código, rutas de endpoints, nombres de campos de API y códigos de error permanecen en inglés.

# Configurar el softphone de navegador (WebRTC)

El softphone de navegador permite a un agente realizar y atender llamadas PSTN sin salir del navegador — sin teléfono de escritorio, sin app SIP de escritorio. Hay tres maneras de ponerlo delante de un agente, y las tres comparten las mismas credenciales y la misma infraestructura:

1. **El softphone integrado del dashboard** — Orbit entrega un softphone listo dentro del dashboard. Es el camino sin código y el punto de partida correcto para la mayoría de los equipos.
2. **Un softphone embebido basado en LiveKit** (`Softphone` en `@devotel-orbit/web`) — usted monta el softphone dentro de su propio espacio de agente (CRM, muro de contact centre, herramienta interna) con su propia UI.
3. **Un softphone SIP-over-WSS embebido** (la vía de registro SIP) — un cliente SIP clásico (p. ej. JsSIP) que se registra directamente contra la puerta de enlace WebRTC-a-SIP de Orbit.

## 2. Emitir credenciales de softphone

Un navegador de agente necesita una credencial de corta duración antes de poder conectarse. El endpoint de emisión depende del cliente elegido — dashboard, LiveKit embebido o SIP embebido.

### Softphone dashboard integrado / LiveKit embebido

`POST /voice/softphone/token` devuelve un token de acceso LiveKit de corta duración más la URL de media a la que conectar:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/softphone/token \
  -H "Authorization: Bearer YOUR_API_KEY"
```

El token queda acotado a una sala por usuario: dos agentes nunca comparten una sesión. Realizar una llamada tras conectar es `POST /voice/softphone/dial` con `{ "to": "+15550123", "from": "+15559876" }`.

### Softphone SIP/WSS embebido

Un cliente SIP se registra directamente por WebSocket. `POST /voice/softphone/register` cambia su petición API autenticada por una credencial SIP de corta duración:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/voice/softphone/register \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "callerIdNumber": "+15559876", "deviceLabel": "agent-desk-04" }'
```

Propiedades clave alrededor de las cuales diseñar:

* Las credenciales viven **60 minutos** — re-registre antes de `expiresAt` o la sesión cae.
* `callerIdNumber` debe ser un número que su organización posee (si no, 403) — así se bloquea el spoofing de CLI saliente.
* El nombre de usuario queda ligado a su organización: un nombre robado no puede rejugarse contra otro tenant.
* La emisión de tokens está acotada a **owner/admin/developer** — no es un endpoint público anónimo.

> [!NOTE]
>
> Revoque una credencial de inmediato con `DELETE /voice/softphone/credentials/:username` si un agente se va o un token se filtra.

## 4. Snippet JS completo — micro, push VoIP + fallback de navegador

Aquí tiene un softphone de navegador completo y copiable. Funciona con ambas opciones embebidas (LiveKit y SIP-over-WSS) y maneja la realidad del fallback de navegador:

```js theme={null}
import { OrbitSoftphone } from "@devotel-orbit/web";

const softphone = new OrbitSoftphone({
  apiBaseUrl: "https://api.orbit.devotel.io",
  apiKey: "YOUR_API_KEY", // serve from your backend — never commit it
  onCallStateChange: (s) => console.log("softphone state:", s),
  onError: (e) => handleSoftphoneFailure(e), // ← fallback lives here
});

// 1. Mic is gated on the browser's getUserMedia. Ask for it on a user
//    gesture (a click) — not page load.
async function armMicrophone() {
  await navigator.mediaDevices.getUserMedia({ audio: true });
  await softphone.connect(); // mints token + publishes mic
}

// 2. Place an outbound call.
async function callCustomer(e164) {
  return softphone.dial(e164); // returns call_id when ringing
}

// 3. Fallback: if the browser/media path can't connect, hand the call
//    to a click-to-call bridge.
function handleSoftphoneFailure(err) {
  console.warn("WebRTC unavailable, falling back:", err.message);
  // show "call me on my device" UI → POST /voice/click-to-call instead
}
```

> [!WARNING]
>
> WebRTC necesita permiso de `getUserMedia` y una página HTTPS. Un softphone que «no hace nada» casi siempre es una de tres cosas: una página HTTP (no segura), un prompt de micro denegado o una red corporativa que bloquea UDP 3478.

## 5. Verificación y solución de problemas

**Verifique el setup de principio a fin:**

1. Emita una credencial (sección 2), conecte el cliente (sección 4) y busque el evento `connect` o SIP `registered`.
2. Realice una llamada saliente a su propio móvil — debería oír timbre y luego audio bidireccional.
3. Haga enrutar una llamada entrante a su número y confirme que el softphone timbra y responde.

**Reglas de solución de problemas, en el orden en que las encontrará:**

| Síntoma | Comprobación |
| - | - |
| `403 Organisation does not own phone number …` en el register | `callerIdNumber` no es un número activo de su cuenta (es una puerta de propiedad, no un bug de formato). |
| `SERVICE_UNAVAILABLE` / "softphone is not configured" | El operador no fijó la configuración SIP WSS/HMAC en el servidor. |
| El prompt de micro no aparece nunca | La página no es HTTPS, o pide el permiso al cargar en vez de en un gesto del usuario. |
| Register/connect correcto, llamada muda | Red corporativa bloqueando UDP/TURN — verifique la ruta ICE. |
| La sesión muere tras \~60 min | La credencial no se re-emite en `expiresAt` — refrésquela. |
| La entrante no llega al softphone | El número no está enrutado a la cola o URI SIP donde reside el softphone — corríjalo en la sección 3, no en el cliente. |

## A dónde ir después

* [SDK demo test-call page](https://docs.orbit.devotel.io/guides/sdk-demo-browser-softphone.md) — realice una llamada saliente de prueba real desde el dashboard (Developer → SDK Live Demo).
* [SIP trunk setup](https://docs.orbit.devotel.io/guides/sip-trunk-setup.md) — si quiere traer su propio carrier/trunk junto al softphone de navegador.
* [Voice queues](https://docs.orbit.devotel.io/guides/voice-queues.md) — las colas ACD por las que pasan las llamadas entrantes antes de que responda un softphone.
* [Web SDK](https://docs.orbit.devotel.io/sdks/web.md) — el mapa completo de eventos de `Softphone` y las demás superficies SDK.


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