Browser WebSocket
Conéctate a la API WebSocket de finlight.me directamente desde un navegador web usando la API WebSocket nativa. Esto es ideal para paneles, terminales de trading y cualquier aplicación frontend que necesite actualizaciones de artículos en tiempo real sin un proxy del lado del servidor.
La API WebSocket del navegador no admite encabezados personalizados. La autenticación se gestiona mediante parámetros de consulta en lugar del encabezado x-api-key. Tu clave de API será visible en la URL del WebSocket: usa este enfoque solo en entornos donde eso sea aceptable (p. ej., paneles autenticados). Nunca expongas tu clave de API en código del lado del cliente accesible públicamente.
Cómo funciona
- Conéctate a
wss://wss.finlight.me(enriquecido) owss://wss.finlight.me/raw(raw) con tu clave de API como parámetro de consulta - Suscríbete enviando un mensaje JSON con tus criterios de filtro y un
clientNonce - Recibe un mensaje
admitque confirma tu conexión, seguido de mensajessendArticlea medida que llegan los artículos - Mantén viva la conexión enviando mensajes
pingcada 25 segundos - Desconéctate llamando a
ws.close()
URLs de conexión
- Name
Enriquecido- Type
- wss://wss.finlight.me
- Description
Artículos con enriquecimiento completo: análisis de sentimiento, extracción de entidades, categorías y contenido completo (según tu nivel de suscripción).
- Name
Raw- Type
- wss://wss.finlight.me/raw
- Description
Artículos raw de baja latencia sin enriquecimiento. Mejor para casos de uso donde la velocidad es lo primero y necesitas los artículos lo más rápido posible.
Parámetros de consulta
- Name
apiKey- Type
- string
- Description
Tu clave de API de finlight. Se usa para la autenticación, ya que el WebSocket del navegador no puede establecer encabezados personalizados.
- Name
takeover- Type
- string
- Description
Establece en
"true"para reemplazar automáticamente la conexión más antigua cuando se alcanza tu límite de conexiones simultáneas.
- Name
clientVersion- Type
- string
- Description
Identificador opcional para tu aplicación cliente. P. ej.
"my-dashboard/1.0"
Mensaje de suscripción
Después de que se abra la conexión, envía un mensaje JSON para suscribirte a los artículos. El servidor responderá con un mensaje admit y luego comenzará a enviar los artículos coincidentes.
- Name
clientNonce- Type
- string
- Description
Un identificador único (p. ej., UUID) para esta solicitud de suscripción. El servidor lo devuelve en la respuesta
admit.
- Name
query- Type
- string
- Description
Consulta de búsqueda para encontrar artículos relevantes. Admite consultas avanzadas.
- Name
sources- Type
- string[]
- Description
Filtra por dominios de fuente. P. ej.
["www.reuters.com", "www.cnbc.com"]
- Name
excludeSources- Type
- string[]
- Description
Excluye dominios de fuente específicos.
- Name
tickers- Type
- string[]
- Description
Filtra por símbolos de ticker. P. ej.
["AAPL", "NVDA"](solo enriquecido)
- Name
countries- Type
- string[]
- Description
Filtra por códigos de país en ISO 3166-1 alpha-2. P. ej.
["US", "DE"](solo enriquecido)
- Name
language- Type
- string
- Description
Filtra por idioma (ISO 639-1). Por defecto es
en, que devuelve solo inglés y excluye otros idiomas — consulta Idioma y cobertura.
Mensajes del servidor
El servidor envía mensajes JSON con un campo action que indica el tipo de mensaje:
- Name
admit- Type
- object
- Description
Se envía tras un handshake exitoso. Contiene
leaseId,serverNow(marca de tiempo) y tuclientNonce.
- Name
sendArticle- Type
- object
- Description
Un nuevo artículo que coincide con tu suscripción. Los datos del artículo están en el campo
data.
- Name
pong- Type
- object
- Description
Respuesta a tu latido
ping.
- Name
preempted- Type
- object
- Description
Tu conexión fue reemplazada por otra sesión (cuando otro cliente se conectó con
takeover: true).
- Name
error- Type
- object
- Description
Ocurrió un error. Revisa el campo
dataoerrorpara los detalles.
Ejemplo completo
Un cliente WebSocket de navegador mínimo e independiente de framework, con reconexión automática y latido:
- Se autentica mediante parámetros de consulta
- Envía un mensaje de suscripción al conectarse
- Mantiene un intervalo de latido de 25 segundos
- Se reconecta con retroceso exponencial (de 500 ms a 10 s)
- Gestiona todos los tipos de mensajes del servidor
Browser Client
const API_KEY = 'YOUR_API_KEY'
const WSS_URL = 'wss://wss.finlight.me' // Use '/raw' path for raw articles
let ws = null
let pingInterval = null
let reconnectTimeout = null
let reconnectAttempt = 0
function connect(filters = {}) {
const params = new URLSearchParams({
apiKey: API_KEY,
takeover: 'true',
clientVersion: 'my-app/1.0',
})
const url = `${WSS_URL}?${params}`
ws = new WebSocket(url)
ws.onopen = () => {
console.log('Connected')
reconnectAttempt = 0
// Send subscription with filters
ws.send(JSON.stringify({
clientNonce: crypto.randomUUID(),
query: filters.query || '',
language: filters.language || 'en',
sources: filters.sources || [],
tickers: filters.tickers || [],
countries: filters.countries || [],
}))
// Start heartbeat
pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({
action: 'ping',
t: Date.now(),
}))
}
}, 25000)
}
ws.onmessage = (event) => {
const msg = JSON.parse(event.data)
switch (msg.action) {
case 'admit':
console.log('Admitted, lease:', msg.leaseId)
break
case 'sendArticle':
console.log('Article:', msg.data.title)
// Handle the article here
break
case 'pong':
break // Heartbeat OK
case 'preempted':
console.warn('Connection replaced')
break
case 'error':
console.error('Server error:', msg.data || msg.error)
break
}
}
ws.onclose = (event) => {
clearInterval(pingInterval)
// Don't reconnect on policy violations
if (event.code === 1008 || event.code === 4002) {
console.error('Connection blocked')
return
}
// Exponential backoff reconnect
const delay = Math.min(500 * 2 ** reconnectAttempt, 10000)
reconnectAttempt++
console.log(`Reconnecting in ${delay}ms...`)
reconnectTimeout = setTimeout(() => connect(filters), delay)
}
ws.onerror = () => console.error('WebSocket error')
}
function disconnect() {
clearInterval(pingInterval)
clearTimeout(reconnectTimeout)
if (ws) ws.close(1000)
}
// Usage
connect({ query: 'Nvidia', language: 'en', countries: ['US'] })
admit Response
{
"action": "admit",
"leaseId": "a1b2c3d4-e5f6-4789-abcd-ef0123456789",
"serverNow": 1708185600000,
"clientNonce": "your-uuid-here"
}
sendArticle Response
{
"action": "sendArticle",
"data": {
"link": "https://www.reuters.com/technology/nvidia-2026-02-17",
"source": "www.reuters.com",
"title": "Nvidia Reports Record Revenue",
"summary": "Nvidia announced record quarterly revenue...",
"publishDate": "2026-02-17T10:30:00Z",
"language": "en",
"sentiment": "positive",
"confidence": 0.92,
"countries": ["US"],
"categories": ["markets", "technology"],
"companies": [
{
"name": "NVIDIA Corporation",
"ticker": "NVDA",
"country": "US"
}
]
}
}
Enriquecido vs Raw
| Función | Enriquecido (/) | Raw (/raw) |
|---|---|---|
| Análisis de sentimiento | Sí | No |
| Extracción de entidades (empresas) | Sí (según el nivel) | No |
| Categorías | Sí | No |
| Contenido completo | Sí (según el nivel) | No |
| Latencia | Estándar | La más baja |
Filtro: tickers | Sí | No |
Filtro: countries | Sí | No |
Filtro: query, sources, language | Sí | Sí |
Las suscripciones de Raw WebSocket solo admiten los filtros query, sources, excludeSources y language. Los filtros de ticker y país se ignoran silenciosamente en el endpoint raw.
¿Qué sigue?
- Revisa la página de Suscripción enriquecida para el modelo de artículo completo y todos los campos disponibles
- Consulta Suscripción raw para detalles específicos de raw
- Aprende sobre Creación de consultas avanzadas para refinar tus filtros
- Usa la API REST para búsquedas de artículos históricos junto con tu flujo en tiempo real