Scrnr

Tire capturas de tela de sites com Scrnr.io

Documentação

Documentação

rev. 2026-05-19

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 requisição.

shell

Copiar

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 requisiçã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 armazenamento do scrnr. O arquivo é hospedado em storage.scrnr.io junto com as capturas de tela, conta como 1 crédito de captura de tela 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.

Requisiçã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.

shell

Copiar

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

Resposta

201 Created, mesmo formato 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 upload; formatos permitidos png, jpeg, webp. Arquivos maiores que o limite retornam 413; bytes que não são 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 que a captura de tela seja feita.

Copiar

{ "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 Requisiçã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.

Copiar

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

Limites:

  • Até 20 cabeçalhos por requisiçã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 Arquivo Personalizada Pro

Substitua por quanto tempo o arquivo capturado é retido em uma única requisição. Útil para pré-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".

Copiar

{ "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 seriam mantidas indefinidamente sob o armazenamento incluído no seu plano. Para retenção indefinida sem uma substituição por requisição, o plano Pro inclui 5 GB de armazenamento permanente; o complemento de armazenamento de +25 GB é adicionado em cima.

Entrega por 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 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 assincronamente pelo 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 requisição inclui um cabeçalho X-Scrnr-Signature no formato t=<ts>,v1=<hex>. Recalcule o HMAC-SHA256 de <ts>.<raw-body> usando seu segredo de endpoint e compare com v1 usando uma verificação de tempo constante. Rejeite requisições em que o timestamp esteja com mais de 5 minutos de diferença.

Copiar

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-Signaturet=<unix-seconds>,v1=<hex-hmac>
  • User-Agentscrnr-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 incluem adicionalmente um objeto details do Zod.

StatusSignificado
400Corpo de requisição inválido, viewport/delay acima do limite do plano, ou uma opção exclusiva do Pro (cabeçalhos personalizados, retenção de arquivo 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 de 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 requisiçã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 de tela (timeout do site de destino, falha do navegador, etc.). A requisiçã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 o 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

Copiar

https://mcp.scrnr.io/mcp

Cursor / Windsurf — OAuth, recomendado

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

Copiar

{ "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

Copiar

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

Cursor / Windsurf — transporte HTTP nativo

Copiar

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

Limites

Os limites são aplicados por requisiçã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 requisição30s45s60s
Retenção de arquivo1 dia3 dias7 dias
Armazenamento incluído5 GB permanentes

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

Início Rápido

Obtenha uma captura de tela em menos de um minuto:

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