Scrnr

Tire capturas de tela de sites com Scrnr.io

Documentação

Documentação

Tudo o que você precisa para começar a tirar capturas de tela.

Autenticação

Envie sua chave de API no cabeçalho X-Api-Key em cada solicitação.

curl https://api.scrnr.io/v1/screenshot \
  -H "X-Api-Key: sk_live_xxxx"

Endpoints

POST /v1/screenshot

Tire uma captura de tela de qualquer URL pública.

Corpo da solicitação

{
  "url": "https://example.com",        // required
  "delivery": "inline" | "url",        // default: inline
  "options": {  
    "width": 1280,                      // default: 1280, max varies by plan
    "height": 800,                       // default: 800, max varies by plan
    "fullPage": false,                   // default: false
    "format": "png" | "jpeg" | "webp", // default: png
    "waitFor": "load" | "networkidle", // default: load
    "delay": 0,                         // ms, max varies by plan
    "blockCookieBanners": false,        // default: false
    "headers": {"X-Custom": "value"},   // Pro plan only
    "retentionHours": 168              // Pro plan only, 1–720
  }
}

POST /v1/upload

Envie um arquivo de imagem existente (PNG, JPEG ou WebP) para o seu armazenamento scrnr. O arquivo é hospedado em storage.scrnr.io junto com as capturas de tela, conta como 1 crédito de captura contra sua cota mensal e obedece às mesmas regras de retenção e armazenamento do plano. Útil para enviar capturas do lado do cliente (extensões de navegador, canvas.toBlob, etc.) para o mesmo namespace de URL das capturas geradas pelo scrnr.

Solicitação

multipart/form-data com um único campo file. O formato é detectado a partir dos bytes do arquivo — o Content-Type fornecido pelo cliente é ignorado.

curl https://api.scrnr.io/v1/upload \
  -H "X-Api-Key: sk_live_xxxx" \
  -F "file=@./screenshot.png"

Resposta

201 Created, mesma forma que /v1/screenshot com delivery: "url":

{
  "url": "https://storage.scrnr.io/screenshots/...",
  "expiresAt": "2026-05-20T12:00:00.000Z"  // null if covered by storage allowance
}

Limites: 25 MB por envio; formatos permitidos png, jpeg, webp. Arquivos maiores que o limite retornam 413; bytes que não são de imagem ou formatos não suportados retornam 400.

GET /v1/usage

Retorna o uso do mês atual e a cota restante para a chave de API autenticada.

Bypass de Banner de Cookies

Defina options.blockCookieBanners: true para suprimir sobreposições de GDPR/consentimento antes da captura de tela ser tirada.

{
  "url": "https://example.com",
  "options": {
    "blockCookieBanners": true
  }
}

Nenhuma técnica cobre 100% dos sites. Para melhores resultados, combine com waitFor: "networkidle" e um pequeno delay.

Cabeçalhos de Solicitação Personalizados Pro

Envie cabeçalhos HTTP extras para a página de destino — útil para capturar páginas autenticadas, variantes de teste A/B ou conteúdo específico por região. Disponível no plano Pro.

{
  "url": "https://example.com/dashboard",
  "options": {
    "headers": {
      "X-Tenant-Id": "acme",
      "Referer": "https://app.example.com"
    }
  }
}

Limites:

  • Até 20 cabeçalhos por solicitação
  • 1 KB por valor, 4 KB no total entre todos os cabeçalhos
  • Os seguintes cabeçalhos são bloqueados: Host, Cookie, Authorization, Content-Length, cabeçalhos hop-by-hop (Connection, Transfer-Encoding, etc.) e qualquer cabeçalho que comece com Proxy-

Retenção de Arquivos Personalizada Pro

Substitua por quanto tempo o arquivo capturado é retido em uma única solicitação. Útil para visualizações efêmeras (defina um valor menor) ou arquivamento de curto prazo (defina um valor maior). Disponível no plano Pro; ignorado quando delivery: "inline".

{
  "url": "https://example.com",
  "delivery": "url",
  "options": {
    "retentionHours": 1 // file deleted after 1 hour
  }
}

Faixa: 1–720 horas (até 30 dias). Definir retentionHours sempre vence — mesmo em capturas que, de outra forma, seriam mantidas indefinidamente sob o armazenamento incluído no seu plano. Para retenção indefinida sem substituição por solicitação, o plano Pro inclui 5 GB de armazenamento permanente; o add-on de armazenamento +25 GB é adicionado em cima.

Entrega de Webhook Pro

Defina delivery: "webhook" para que a URL do arquivo capturado seja enviada ao seu servidor após a captura de tela ser concluída. Configure um endpoint HTTPS por conta em /dashboard/webhooks — ele é acionado para cada captura da sua conta, seja via chave de API ou OAuth. Mostraremos o segredo HMAC apenas uma vez na criação; salve-o.

A resposta HTTP retorna imediatamente com 202 Accepted e o ID da captura de tela; o webhook é acionado de forma assíncrona a partir do worker. POSTs com falha são repetidos com backoff exponencial em 30s, 5m, 30m, 2h, 12h (5 tentativas, ~14,5 horas). Após o número máximo de tentativas ou qualquer 4xx não repetível, a entrega é marcada como DEAD e exibida para reprodução manual no painel.

Payload

{
  "id": "clx9z2...",              // event id; matches X-Scrnr-Event-Id header
  "type": "screenshot.completed",
  "createdAt": "2026-04-28T12:00:00.000Z",
  "data": {
    "id": "clx9z2...",            // request id
    "url": "https://example.com",
    "fileUrl": "https://storage.scrnr.io/...",
    "expiresAt": "2026-05-05T12:00:00.000Z",
    "format": "png",
    "fileSizeBytes": 123456,
    "durationMs": 1234
  }
}

Verificando a assinatura

Cada solicitação inclui um cabeçalho X-Scrnr-Signature no formato t=<ts>,v1=<hex>. Recalcule o HMAC-SHA256 de <ts>.<raw-body> usando o segredo do seu endpoint e compare com v1 usando uma verificação de tempo constante. Rejeite solicitações em que o timestamp esteja com mais de 5 minutos de diferença.

import crypto from "node:crypto";

function verify(secret, signatureHeader, timestamp, rawBody) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(\`${timestamp}.${rawBody}\`)
    .digest("hex");
  const provided = signatureHeader.match(/v1=([^,]+)/)?.[1] ?? "";
  return (
    expected.length === provided.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(provided)) &&
    Math.abs(Date.now() / 1000 - Number(timestamp)) < 300
  );
}

Cabeçalhos

  • X-Scrnr-Event-Id — estável entre tentativas; use como sua chave de idempotência
  • X-Scrnr-Signature — t=<unix-seconds>,v1=<hex-hmac>
  • User-Agent — scrnr-webhooks/1.0

Responda com 2xx para confirmar. Qualquer outra coisa é tratada como falha (4xx são terminais, exceto 408 / 425 / 429; 5xx e erros de rede são repetidos conforme o cronograma).

Erros

Todos os erros retornam JSON com um campo error. Falhas de validação também incluem um objeto details do Zod.

StatusSignificado
400Corpo da solicitação inválido, viewport/atraso acima do limite do plano ou uma opção exclusiva do Pro (cabeçalhos personalizados, retenção de arquivos personalizada) usada em um plano não Pro.
401Chave de API / token OAuth ausente, inválido ou revogado.
403URL bloqueada — aponta para um IP privado, domínio bloqueado ou falha nas verificações de segurança SSRF.
404ID da captura de tela não encontrado (apenas em DELETE /v1/screenshot/:id).
410Captura de tela já excluída.
413Arquivo enviado excede o limite de tamanho por solicitação (25 MB). Aplica-se apenas a POST /v1/upload.
429Cota mensal atingida. A resposta inclui o limite e o timestamp resetAt.
500Falha no pipeline de captura (timeout do site de destino, falha do navegador, etc.). A solicitação é registrada e contada como FAILED, não contra sua cota.

Capturas individuais com falha (5xx) não contam para sua cota mensal. Os contadores de cota só aumentam em capturas bem-sucedidas.

Integração MCP

Adicione scrnr como um servidor MCP para usar take_screenshot e get_usage diretamente dentro da sua ferramenta de IA.

Entre com sua conta scrnr

Clientes MCP que suportam OAuth (Claude Desktop, conectores Claude.ai, Cursor, Windsurf, etc.) podem se conectar sem chave de API — eles abrirão um navegador para você entrar e solicitar acesso. Basta colar a URL abaixo; nós cuidamos do resto. Se o seu cliente ainda não suporta OAuth, os exemplos com chave de API mais abaixo ainda funcionam.

Claude Desktop / Claude.ai — OAuth, recomendado

Configurações → Conectores → Adicionar conector personalizado

https://mcp.scrnr.io/mcp
{
  "mcpServers": {
    "scrnr": {
      "url": "https://mcp.scrnr.io/mcp"
    }
  }
}

Ou use uma chave de API

Claude Desktop — via mcp-remote (ponte stdio)

~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "scrnr": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.scrnr.io/mcp",
        "--header",
        "Authorization: Bearer sk_live_xxxx"
      ]
    }
  }
}

Cursor / Windsurf — transporte HTTP nativo

~/.cursor/mcp.json · ~/.codeium/windsurf/mcp_config.json

{
  "mcpServers": {
    "scrnr": {
      "url": "https://mcp.scrnr.io/mcp",
      "headers": {
        "Authorization": "Bearer sk_live_xxxx"
      }
    }
  }
}

Limites

Os limites são aplicados por solicitação e por mês calendário, com base no seu plano.

LimiteFreeBasicPro
Capturas de tela / mês1003.00015.000
Viewport máximo1920 × 10802560 × 14403840 × 2160
Chaves de API por conta2525
Atraso máximo5s15s30s
Tempo limite de solicitação30s45s60s
Retenção de arquivos1 dia3 dias7 dias
Armazenamento incluído——5 GB permanente

Limites maiores estão disponíveis em planos pagos. Gerencie sua assinatura e o opcional add-on de armazenamento +25 GB em /dashboard/billing. Arquivos capturados enquanto uma permissão de armazenamento está ativa são mantidos indefinidamente, em vez de expirarem na janela de retenção do plano.

Início Rápido

Obtenha uma captura de tela em menos de um minuto:

  1. 1Faça login — Vá para /dashboard e entre com seu e-mail.
  2. 2Crie uma chave de API — Clique em “Nova chave de API” — copie imediatamente, ela é mostrada apenas uma vez.
  3. 3Faça sua primeira solicitação — Use o endpoint POST /v1/screenshot com sua chave no cabeçalho X-Api-Key.