docs

Browser API

Sessões de navegador headless com stealth garantido, prontas para connectOverCDP, com o SDK @onveloz/browser ou pela API REST.

A Browser API entrega sessões de navegador headless (Chromium) rodando na infraestrutura da Veloz, com stealth garantido em toda sessão, prontas para você controlar via Playwright com chromium.connectOverCDP(...). Use para automação, scraping, testes end-to-end, geração de PDFs/screenshots ou qualquer fluxo que precise de um navegador real e isolado, sem manter Chromium na sua própria infraestrutura.

Você cria uma sessão, recebe uma connectUrl (um endpoint CDP sobre WebSocket) e conecta com o seu próprio playwright/playwright-core. A Veloz cuida do provisionamento, do isolamento e do encerramento.

Nota: a Browser API está em early access (acesso antecipado) e é liberada por organização. Se a seção Sessões de navegador ainda não aparece no seu dashboard, peça acesso ao suporte: abra um chamado em Suporte no dashboard ou rode veloz support create --subject "Acesso à Browser API" --message "Quero testar a Browser API na minha organização.".

Comece em 2 minutos

O caminho mais curto até um navegador rodando na Veloz: sem escolher engine e sem opção nenhuma.

1. Crie uma chave

No dashboard, abra Sessões de navegador → Chaves de API, crie uma chave e copie (ela aparece uma única vez). No terminal:

export VELOZ_BROWSER_TOKEN=bk_live_sua_chave

2. Rode o primeiro navegador

npm install @onveloz/browser playwright-core

Salve como inicio.mjs:

import { Onveloz } from "@onveloz/browser";
import { chromium } from "playwright-core";
 
const ov = new Onveloz(); // lê VELOZ_BROWSER_TOKEN do ambiente
 
const browser = await chromium.connectOverCDP(await ov.connect());
const page = await browser.contexts()[0].newPage();
await page.goto("https://example.com");
console.log(await page.title());
 
await page.waitForTimeout(30_000); // 30 s para assistir no dashboard
await browser.close(); // ao desconectar, a sessão é encerrada
node inicio.mjs
# Example Domain

3. Assista ao vivo

Enquanto o script espera, abra Sessões de navegador no dashboard. A sessão aparece como Ativa: clique em Ao vivo para ver a tela do navegador em tempo real. Quando o script fecha o navegador, a sessão é encerrada.

Pronto. As seções abaixo detalham o SDK, a API REST, a CLI, a escolha do navegador e as opções de cada sessão.

Chaves de API

Toda chamada usa uma chave bk_live_* no cabeçalho Authorization:

Authorization: Bearer bk_live_sua_chave

Gere e revogue chaves na seção Sessões de navegador → Chaves de API do dashboard. A chave é vinculada à sua organização e concede acesso para criar e controlar sessões.

Segurança: a chave é exibida uma única vez na criação. Copie nesse momento, trate como senha, defina em variável de ambiente (VELOZ_BROWSER_TOKEN) e nunca commite no Git.

SDK @onveloz/browser

A forma recomendada de integrar a partir de Node. O SDK não embute o Playwright: ele entrega a connectUrl e você conecta com o seu próprio cliente.

npm install @onveloz/browser playwright-core

Defina o token no ambiente:

VELOZ_BROWSER_TOKEN=bk_live_sua_chave

Conectar para acordar (uma linha)

Nenhuma sessão é criada de antemão: um navegador quente é provisionado quando você abre o socket CDP e encerrado quando você desconecta. O limite de simultaneidade é checado no momento da conexão.

import { Onveloz } from "@onveloz/browser";
import { chromium } from "playwright-core";
 
const ov = new Onveloz(); // lê VELOZ_BROWSER_TOKEN do ambiente
 
const browser = await chromium.connectOverCDP(await ov.connect());
const page = await browser.contexts()[0].newPage();
await page.goto("https://exemplo.com");
console.log(await page.title());
await browser.close(); // ao desconectar, o navegador é encerrado

Sessão explícita

Quando você precisa do ciclo de vida na mão (criar agora, conectar depois, listar, encerrar):

import { Onveloz } from "@onveloz/browser";
import { chromium } from "playwright-core";
 
const ov = new Onveloz();
 
// O provisionamento roda fora da requisição, então a sessão nasce PENDING.
const session = await ov.sessions.create();
 
// Aguarda ficar RUNNING com connectUrl disponível (polling interno).
const ready = await ov.sessions.waitUntilReady(session.id);
 
const browser = await chromium.connectOverCDP(ready.connectUrl!);
const page = await browser.contexts()[0].newPage();
await page.goto("https://exemplo.com");
 
await browser.close();
await ov.sessions.close(session.id);

Métodos disponíveis no namespace ov.sessions:

Método Descrição
create(config?, opts?) Cria uma sessão (nasce PENDING, connectUrl: null). opts.idempotencyKey evita duplicar
get(id) Busca uma sessão e seu connectUrl quando RUNNING
list({ activeOnly? }) Lista as sessões da organização
close(id) Encerra uma sessão
liveView(id) Gera a URL de visualização ao vivo (sob demanda)
waitUntilReady(id, opts?) Faz polling até RUNNING ou lança em estado terminal/timeout

No namespace ov.engines:

Método Descrição
list() Lista os engines e se cada um já inicia sessões (available)
options(id) Configurações que um engine aceita em settings e suas listas

E no cliente ov:

Método Descrição
connect(config?) Gera uma connectUrl de conectar-para-acordar (sem criar sessão)
token(config?) Alias de connect()

Para apontar a um ambiente alternativo, passe { apiUrl } ou defina VELOZ_BROWSER_API.

API REST

Para linguagens fora de Node, fale direto com a API. Base: https://platform.onveloz.com/api/browser. Todas as chamadas exigem o cabeçalho Authorization: Bearer bk_live_*.

Método e rota Descrição
POST /v1/sessions Cria uma sessão (provisionamento roda em segundo plano)
GET /v1/sessions Lista as sessões da organização (?activeOnly=true)
GET /v1/sessions/:id Busca uma sessão e seu connectUrl
GET /v1/sessions/:id/live-view Gera a URL de visualização ao vivo (sob demanda)
DELETE /v1/sessions/:id Encerra uma sessão
POST /v1/connect-token Gera uma connectUrl de conectar-para-acordar
GET /v1/engines Lista os engines e se cada um já inicia sessões
GET /v1/engines/:id/options Configurações que um engine aceita em settings e suas listas

Criar e conectar

# 1) Cria a sessão: ela nasce PENDING.
curl -X POST https://platform.onveloz.com/api/browser/v1/sessions \
  -H "Authorization: Bearer bk_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{ "timeoutSec": 300 }'
# → { "id": "...", "status": "PENDING", "connectUrl": null, "expiresAt": "..." }
 
# 2) Faça polling até connectUrl aparecer (sessão RUNNING).
curl https://platform.onveloz.com/api/browser/v1/sessions/SESSION_ID \
  -H "Authorization: Bearer bk_live_sua_chave"
# → { ..., "status": "RUNNING", "connectUrl": "wss://.../v1/connect?token=...",
#     "liveViewPath": "/v1/sessions/SESSION_ID/live-view" }

Depois, conecte ao connectUrl com qualquer cliente CDP (Playwright, Puppeteer, ou o protocolo cru).

Estados da sessão

Status Descrição
PENDING Provisionando, ainda sem connectUrl
RUNNING Pronta, com connectUrl disponível para conectar
RELEASED Encerrada (por você ou por inatividade)
EXPIRED Atingiu o TTL e foi encerrada
FAILED Falhou ao provisionar

Pelo terminal e por agentes de IA

A CLI da Veloz cobre o mesmo fluxo. Os comandos usam o login da CLI (veloz login), sem chave bk_live_*:

Comando O que faz
veloz browser engines Lista os engines e se cada um já inicia sessões
veloz browser options <engine> Mostra as configurações que o engine aceita
veloz browser create Cria uma sessão (--proxy-id usa um proxy salvo)
veloz browser list Lista as sessões da organização
veloz browser stop <id> Encerra uma sessão
veloz browser connect-url Gera uma URL de conexão para o seu cliente CDP
veloz browser proxies Lista, mostra, salva, altera e exclui proxies salvos (list, get, create, update, delete)

Rode veloz browser <comando> --help para ver as flags de cada comando.

Para agentes de IA, veloz mcp add registra a CLI como servidor MCP no Claude Code, no Cursor e em outros editores. As mesmas operações viram ferramentas: browser_engines, browser_options, browser_create, browser_list, browser_stop, browser_connect_url e, para os proxies salvos, browser_proxies_list, browser_proxies_get, browser_proxies_create, browser_proxies_update e browser_proxies_delete. A senha de um proxy nunca é argumento de ferramenta: ela vem de VELOZ_BROWSER_PROXY_PASSWORD no ambiente do servidor MCP ou do prompt da CLI. Veja MCP & Agentes IA.

Stealth

Toda sessão já roda com as proteções anti-detecção ativas: fingerprint coerente (locale e timezone alinhados com a geo de saída), WebGL funcional via a stack GL nativa do Linux (Mesa/llvmpipe) e supressão de vazamentos do protocolo. O stealth é garantido e não configurável: não há nada para ligar, e não é possível desligar.

Sobre o WebGL: as sessões rodam em máquinas sem GPU dedicada, então a renderização é por software. Isso é proposital. O UNMASKED_RENDERER reportado é o mesmo de qualquer servidor Linux sem GPU, que é justamente o que somos, em vez do SwiftShader que denuncia um Chrome headless. Desligar o WebGL seria pior: getContext("webgl") retornaria null, um sinal muito mais chamativo.

Use o seu próprio proxy

Por padrão o egresso é direto. Para sair por um proxy, traga o seu: informe o gateway em proxyServer (e credenciais, se houver). O proxyCountry mantém o fingerprint de stealth coerente com a geo de saída do seu proxy.

const session = await ov.sessions.create({
  proxyServer: "http://gateway.seu-proxy.com:8080", // http, https ou socks5
  proxyUsername: "usuario", // opcional (omita para proxy autorizado por IP)
  proxyPassword: "senha", // opcional
  proxyCountry: "US", // opcional: país de saída do seu proxy
});

As credenciais são criptografadas em repouso e nunca retornadas nas respostas da API. O proxy próprio vale em create() e em connect(). Em connect(), as credenciais ficam guardadas no servidor até a URL expirar, e a URL só leva uma referência a elas.

Proxies salvos

Salve um proxy uma vez, com um nome, e use pelo id em proxyId. O id vale em create() e em connect(), sem mandar as credenciais em cada requisição.

const proxy = await ov.proxies.create({
  name: "residencial-us", // único na organização
  server: "http://gateway.seu-proxy.com:8080", // http, https ou socks5, sem usuário e senha
  username: "usuario", // opcional
  password: "senha", // opcional
  country: "US", // opcional: país de saída do proxy
});
 
const session = await ov.sessions.create({ proxyId: proxy.id });
const browser = await chromium.connectOverCDP(await ov.connect({ proxyId: proxy.id }));

No SDK, ov.proxies tem list(), get(id), create(input), update(id, patch) e delete(id). Na API REST:

Método Rota O que faz
GET /v1/proxies Lista os proxies salvos da organização ({ "proxies": [ ... ] })
POST /v1/proxies Salva um proxy
GET /v1/proxies/:id Lê um proxy salvo
PATCH /v1/proxies/:id Altera só os campos enviados; null em username, password ou country limpa
DELETE /v1/proxies/:id Exclui o proxy salvo
curl -X POST https://platform.onveloz.com/api/browser/v1/proxies \
  -H "Authorization: Bearer bk_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{ "name": "residencial-us", "server": "http://gateway.seu-proxy.com:8080", "username": "usuario", "password": "senha", "country": "US" }'
# → { "id": "...", "name": "residencial-us", "server": "http://gateway.seu-proxy.com:8080",
#     "username": "usuario", "hasPassword": true, "country": "US", "lastCheck": null, ... }
  • A senha nunca volta. As credenciais são criptografadas em repouso. As respostas trazem server sem credenciais, username e hasPassword, nunca a senha.
  • Um ou outro. proxyId não vai junto com proxyServer, proxyUsername, proxyPassword ou proxyCountry: a requisição volta 400. O país da sessão vem do proxy salvo.
  • Só a sua organização. Um id de outra organização volta 404, igual a um id que não existe. Um nome repetido volta 409, assim como passar de 100 proxies salvos.
  • Último teste. Cada sessão aberta por um proxy salvo guarda em lastCheck o que o navegador viu na saída (IP, país, cidade, latência) e a hora em lastCheckedAt. Quando o proxy falha, lastCheck traz { "ok": false, "cause": "proxy_failed" }. Trocar servidor, usuário ou senha apaga o último teste.
  • Alterar e excluir. Uma URL de connect() usa o proxy como ele estiver na hora de conectar. Excluir o proxy faz essas URLs pararem de funcionar; sessões já criadas com ele seguem até o fim.

Escolher o navegador

Cada sessão roda um engine: o navegador e a camada de automação que o controla. Sem engine, a sessão usa o engine padrão (patchright), como no Comece em 2 minutos.

A lista de engines cresce com o tempo. Só iniciam sessões os engines que GET /v1/engines marca com available: true. Os marcados com available: false aparecem no catálogo, mas ainda não podem ser criados: o pedido volta 400 com o código unavailable.

Descobrir engines

curl https://platform.onveloz.com/api/browser/v1/engines \
  -H "Authorization: Bearer bk_live_sua_chave"
# → { "engines": [ { "id": "...", "label": "...", "available": true, ... } ] }
const engines = await ov.engines.list();
const prontos = engines.filter((engine) => engine.available).map((engine) => engine.id);

Cada engine traz:

Campo Descrição
id O valor de engine ao criar a sessão
label Nome de exibição
available true quando o engine já inicia sessões (sem opções)
experimental Engine em fase experimental
limitations O que o engine não faz que os outros fazem, em uma frase; null quando não há limite. Aparece também no dashboard, ao escolher o engine
protocol Como o cliente controla a sessão: cdp (Chrome DevTools Protocol, use connectOverCDP) ou playwright (protocolo do Playwright)
capabilities Um booleano por recurso que o engine aceita, como headful, headless, locale, timezoneId, userAgent, flags, extensions, initScripts, geolocation e proxy
headlessDefault O modo do navegador quando você omite options.headless
os Valores aceitos em options.os
proxySchemes Esquemas de proxy aceitos (http, https, socks5); vazio quando o engine não aceita proxy
browser Navegador padrão e versão (version pode ser null)
executables Builds que options.executable escolhe, o padrão primeiro; vazio quando o engine tem um só
license Licença do engine

Engines experimentais

Os engines com experimental: true iniciam sessões, mas têm limites que os outros não têm. O campo limitations de cada um resume esses limites:

  • cloakbrowser é controlado por CDP (connectOverCDP) e não repassa ao cliente as mensagens do console da página, por decisão do fabricante do navegador. Por isso page.setContent não termina e os eventos page.on('console') e page.on('pageerror') não disparam. Navegar, ler e preencher elementos, executar scripts e capturar a tela funcionam. Os substitutos estão logo abaixo da lista.
  • camofox roda o Camoufox, um Firefox, pelo protocolo do Playwright (protocol: "playwright"). Conecte com firefox.connect() do Playwright 1.59.x. Com outra versão, a conexão é recusada na hora com uma mensagem que diz qual versão usar. A visualização ao vivo não está disponível para ele.
  • obscura só roda em headless e é controlado por CDP (connectOverCDP). Navegar (page.goto), executar scripts (page.evaluate) e capturar a tela (Page.captureScreenshot) funcionam. page.setContent e a visualização ao vivo não estão disponíveis.

No cloakbrowser, troque page.setContent por document.write e leia o console por um script que roda antes da página:

// Registre antes de navegar: guarda o console de cada página em window.__logs
await page.addInitScript(() => {
  window.__logs = [];
  for (const level of ["log", "error"]) {
    const original = console[level];
    console[level] = (...args) => {
      window.__logs.push(`${level}: ${args.join(" ")}`);
      return original.apply(console, args);
    };
  }
});
 
await page.goto("https://example.com");
console.log(await page.evaluate(() => window.__logs));
 
// No lugar de page.setContent(html)
const html = "<h1>Olá</h1>";
await page.evaluate((content) => {
  document.open();
  document.write(content);
  document.close();
}, html);
await page.waitForLoadState("load");
console.log(await page.locator("h1").textContent()); // Olá

Criar com engine e opções

O exemplo usa o engine padrão com locale e timezoneId:

curl -X POST https://platform.onveloz.com/api/browser/v1/sessions \
  -H "Authorization: Bearer bk_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "engine": "patchright",
    "options": { "locale": "pt-BR", "timezoneId": "America/Sao_Paulo" },
    "timeoutSec": 300
  }'
# → { "id": "...", "status": "PENDING", "connectUrl": null, "expiresAt": "..." }
const session = await ov.sessions.create({
  engine: "patchright",
  options: { locale: "pt-BR", timezoneId: "America/Sao_Paulo" },
  timeoutSec: 300,
});

Um locale ou timezoneId informado em options vale sobre o que o stealth derivaria de proxyCountry.

Opções aceitas em options:

Opção Tipo Regras
headless boolean Roda sem janela. Omitida, vale headlessDefault. O engine precisa aceitar o modo pedido
locale string Locale BCP 47 da lista locales (ex: "pt-BR"), até 64 caracteres
timezoneId string Fuso IANA da lista timezones (ex: "America/Sao_Paulo"), até 128 caracteres
userAgent string User agent da sessão, até 1024 caracteres
os string "windows", "macos" ou "linux", entre os que o engine lista em os
flags string[] Flags extras do Chromium: até 32, com até 256 caracteres cada. Cada engine aceita só a sua lista
settings object Configurações do engine por id (veja abaixo)
extensions object[] Até 5, cada uma { "webStoreId": "..." } (id de 32 letras da Chrome Web Store) ou { "url": "https://..." }
initScripts string[] Até 10 scripts não vazios, 256 KiB no total, que toda página roda antes do próprio código
executable string Id de um build em executables. Só em engines com mais de um build
geolocation object { "latitude": -23.55, "longitude": -46.63, "accuracy": 50 }: latitude de -90 a 90, longitude de -180 a 180, accuracy em metros (opcional, maior que zero)

Cada opção depende de uma capacidade do engine (capabilities). Textos não aceitam caracteres de controle, e uma chave fora desta tabela volta unknown_option. Com extensions e sem executable, roda o primeiro build que carrega extensões.

Uma opção que o engine descreve ainda pode ser recusada com o código unavailable enquanto não estiver liberada para ele. O issues da resposta diz qual opção foi recusada (veja Erros).

Configurações do engine (settings)

Além das opções da tabela, cada engine publica as próprias configurações. Os ids seguem o formato mecanismo:chave (por exemplo, context-option:viewport) e mudam de um engine para outro. Consulte os de cada engine:

curl https://platform.onveloz.com/api/browser/v1/engines/patchright/options \
  -H "Authorization: Bearer bk_live_sua_chave"
# → { "engine": { ... }, "settings": [ ... ], "lists": { "locales": [ ... ], "timezones": [ ... ], ... } }
const { settings, lists } = await ov.engines.options("patchright");

Um id de engine que não existe responde 404 (no SDK, BrowserAccessError com status: 404). Cada item de settings traz:

Campo Descrição
id A chave em options.settings
label Nome de exibição
type boolean, number, string, enum, string[] ou object
category Grupo da configuração
choices Valores sugeridos (value, label, recommended). value: null significa deixar a configuração de fora
choicesFrom Lista em lists cujos valores a configuração também aceita, ou null
custom true quando a configuração aceita valores fora de choices, desde que do tipo certo
deprecated Configuração obsoleta

lists traz as listas de valores: locales e timezones (para as opções locale e timezoneId) e as listas citadas em choicesFrom.

Para usar, passe o id e o valor em options.settings:

{
  "engine": "patchright",
  "options": {
    "settings": { "context-option:viewport": { "width": 1366, "height": 768 } }
  }
}

Limites de settings: até 256 configurações e até 65.536 caracteres de JSON no total. O valor não pode ser null. Fora de choices, textos e enum têm de 1 a 2048 caracteres, listas até 128 itens e objetos até 16.384 caracteres de JSON. Algumas configurações são controladas pela Veloz e voltam fixed ou controlled_switch. A opção geolocation e uma configuração de geolocalização não podem ir juntas.

Opções em conectar-para-acordar

ov.connect() e POST /v1/connect-token aceitam engine, options, region e timeoutSec, como uma criação:

const browser = await chromium.connectOverCDP(
  await ov.connect({
    engine: "patchright",
    options: { locale: "pt-BR", timezoneId: "America/Sao_Paulo" },
  }),
);
curl -X POST https://platform.onveloz.com/api/browser/v1/connect-token \
  -H "Authorization: Bearer bk_live_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{ "engine": "patchright", "options": { "locale": "pt-BR" } }'
# → { "connectUrl": "wss://.../v1/connect?token=..." }
  • A checagem acontece ao gerar a URL. Engine ou opção recusada volta 400 antes de você conectar.
  • A URL carrega as opções assinadas, mas não cifradas. Quem tem a URL consegue lê-las e abrir uma sessão na sua organização. Trate a URL como segredo e não coloque segredos em initScripts.
  • A URL tem no máximo 8 KiB. Acima disso, a resposta é 400 com option: "options" e code: "invalid". Reduza as opções (initScripts costuma ser o maior) ou crie a sessão antes de conectar.
  • O proxy fica no servidor. Um proxy próprio (proxyServer e credenciais) ou salvo (proxyId) é guardado ao gerar a URL, que só leva uma referência a ele. Envie um ou outro, não os dois.

Repetir com segurança (Idempotency-Key)

POST /v1/sessions aceita o cabeçalho Idempotency-Key. Com ele, repetir a mesma criação (por exemplo, depois de um timeout de rede) devolve a sessão que já existe em vez de abrir outra.

curl -X POST https://platform.onveloz.com/api/browser/v1/sessions \
  -H "Authorization: Bearer bk_live_sua_chave" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-123" \
  -d '{ "timeoutSec": 300 }'
const session = await ov.sessions.create({ timeoutSec: 300 }, { idempotencyKey: "pedido-123" });
  • A chave tem de 1 a 255 caracteres ASCII visíveis (sem espaço). Outro valor volta 400 com "error": "O cabeçalho Idempotency-Key deve ter de 1 a 255 caracteres ASCII visíveis.".
  • A chave vale dentro da organização. Use uma chave nova para cada sessão nova.
  • Mesma chave, mesmo pedido: a resposta traz a sessão original (id, status atual e connectUrl: null). Busque o connectUrl com GET /v1/sessions/:id. A repetição não conta de novo no limite de sessões simultâneas.
  • Mesma chave, pedido diferente: 409 com "error": "Esta chave de idempotência já foi usada com uma requisição diferente.". No SDK, BrowserError com code: "browser/idempotency-conflict".

O Idempotency-Key vale só na criação de sessões, não em POST /v1/connect-token.

Erros

Engine ou opções recusadas respondem 400 com error (o texto completo) e issues (um item por problema):

{
  "error": "O valor da opção locale não está entre os permitidos. O valor da opção timezoneId não está entre os permitidos.",
  "issues": [
    {
      "option": "locale",
      "code": "not_allowed",
      "message": "O valor da opção locale não está entre os permitidos."
    },
    {
      "option": "timezoneId",
      "code": "not_allowed",
      "message": "O valor da opção timezoneId não está entre os permitidos."
    }
  ]
}

option é o nome da opção (locale), o id da configuração (context-option:viewport), engine, proxy ou options (a URL de conexão inteira). Os códigos:

Código Quando
unknown_engine O engine não existe no catálogo
unknown_option Opção ou configuração que o engine não conhece
invalid Valor fora do formato ou dos limites
not_allowed Valor fora da lista permitida (por exemplo, locale fora de locales)
unsupported O engine não tem a capacidade (por exemplo, headless: true sem modo headless)
fixed Configuração controlada pela Veloz
controlled_switch Configuração que usa uma flag do Chromium controlada pela Veloz
unavailable Engine ou opção ainda não liberada para iniciar sessões

No SDK, esse 400 vira BrowserOptionsError (code: "browser/invalid-options"), com a mesma lista em error.issues. Um 400 sem issues vem de outro campo, como o proxy ou o Idempotency-Key, e vira BrowserError.

Configuração da sessão

Os campos abaixo valem em ov.sessions.create() e ov.connect(), e no corpo JSON de POST /v1/sessions e POST /v1/connect-token. O stealth é sempre garantido (não é um campo).

Campo Tipo Descrição
engine string Id do engine (veja GET /v1/engines). Omitido, usa o engine padrão
options object Opções do navegador, checadas contra o engine (veja Escolher o navegador)
proxyServer string Seu gateway de proxy (scheme://host:porta: http, https ou socks5)
proxyUsername string Usuário do seu proxy (opcional; omita para proxy autorizado por IP)
proxyPassword string Senha do seu proxy (opcional). Criptografada em repouso; nunca retornada
proxyCountry string País de saída do seu proxy (ISO de 2 letras, ex: "US"), alinha o fingerprint
proxyId string Id de um proxy salvo (veja Proxies salvos), no lugar dos outros campos de proxy
region string Região de provisionamento (servidor escolhe o padrão)
timeoutSec number TTL máximo da sessão em segundos (limitado ao teto do seu plano)

Um region, timeoutSec ou proxyCountry inválido é ignorado, e a sessão segue com o padrão. Já engine e options inválidos são recusados com 400 (veja Erros), assim como proxyId junto de qualquer outro campo de proxy, mesmo inválido.

Visualização ao vivo

No dashboard, abra uma sessão para ver o console Sessão ao vivo: a tela do navegador transmitida em tempo real enquanto a sessão roda, útil para acompanhar automações e depurar. A mesma transmissão é o screencast CDP padrão (Page.startScreencast), então você também pode consumi-la a partir do seu próprio cliente CDP.

Visualização ao vivo pela API

A liveView devolve a URL de uma página de live view hospedada pela Veloz: uma página HTML completa, com a marca Veloz, pronta para abrir numa aba (window.open) ou embutir num <iframe> no seu produto. Ela renderiza o console interativo (assistir e dirigir: clique, digitação, navegação) sem exigir login, porque o token na URL é a credencial. Não é o socket wss:// bruto: a página resolve o próprio socket no servidor.

const url = await ov.sessions.liveView(session.id);
// https://app.onveloz.com/live/SESSION_ID?token=...

Ou via REST:

curl -H "Authorization: Bearer $VELOZ_BROWSER_TOKEN" \
  https://platform.onveloz.com/api/browser/v1/sessions/SESSION_ID/live-view
# → { "liveViewUrl": "https://app.onveloz.com/live/SESSION_ID?token=..." }

Use isso para embutir a tela da sessão no seu próprio produto, mostrar ao usuário final o que a automação está fazendo, ou abrir uma janela de depuração sob demanda.

Quatro pontos importantes:

  • Nada é transmitido até você abrir a URL. O token em si é inerte: o screencast só começa quando o WebSocket conecta. Gerar a URL e nunca usá-la não consome recurso nenhum, e por isso ela fica numa rota própria em vez de vir em get, que é chamado em polling.
  • É interativo, não somente-leitura. Os quadros são transmitidos para você e cliques e teclas voltam como CDP Input.*, então quem estiver assistindo também pode assumir o controle.
  • É uma capacidade separada do connectUrl. Um token de visualização não abre o socket CDP bruto, então você pode entregá-lo a alguém sem dar controle total sobre a automação. Ainda assim, ele permite dirigir a sessão: trate-o como um segredo.
  • Expira junto com a sessão e só existe enquanto ela está RUNNING. Em qualquer outro estado a rota responde 404.

Limites

As cotas dependem do seu plano:

Plano Sessões simultâneas TTL padrão TTL máximo
Padrão 2 60s 300s (5min)
SCALE 10 300s 900s (15min)

Estourar o limite de sessões simultâneas retorna 429 (no SDK, BrowserQuotaError). Precisa de cotas maiores? Fale com o suporte.

Boas práticas

Importante: conecte assim que a connectUrl aparecer. Uma sessão RUNNING sem nenhum cliente CDP conectado é liberada por inatividade em poucos segundos. Crie e conecte no mesmo processo, em vez de buscar a connectUrl em um passo e conectar em outro muito depois.

  • Encerre o que você abre. Chame close() (ou DELETE) ao terminar para liberar a cota; não dependa só do TTL.
  • Use conectar-para-acordar para tarefas curtas. É o caminho mais simples: uma connectUrl, conecta, trabalha, desconecta.
  • Use timeoutSec para tarefas longas. Suba o TTL até o teto do seu plano quando a automação leva mais que o padrão.
  • Trate 429 com backoff. Ao bater no limite de simultaneidade, aguarde uma sessão liberar antes de tentar de novo.
  • Envie Idempotency-Key quando repetir criações. Um retry depois de timeout devolve a mesma sessão em vez de ocupar outra vaga.
  • Confira GET /v1/engines antes de fixar um engine. Só os marcados com available: true iniciam sessões.

Próximos passos