Mapa
Pegue todas as URLs que um site lista com uma chamada só, sem abrir as páginas. A lista sai do robots.txt do site, dos sitemaps dele e dos links da página que você passar.
Uma chamada
curl -X POST https://api.scrapa.app/v1/map \
-H "authorization: Bearer sc_live_your_key" \
-H "content-type: application/json" \
-d '{"url": "https://example.com"}'{
"data": {
"urls": [
{ "url": "https://example.com", "lastmod": "2026-10-01" },
{ "url": "https://example.com/pricing", "lastmod": "2026-09-12" },
{ "url": "https://example.com/blog/hello" }
],
"source": "both",
"truncated": false,
"pool": "residential",
"bytes": 48211
},
"meta": { "cost": 2, "creditsRemaining": 985, "requestId": "0f3c…" }
}Você manda o endereço do site e a gente devolve as URLs dele, cada uma uma vez só, com a data da última alteração quando o sitemap informa.
De onde vêm as URLs
Primeiro o robots.txt do site, que aponta os sitemaps. Depois os três lugares onde os sites costumam guardar um: /sitemap.xml, /sitemap_index.xml e /sitemap.txt. Quando um sitemap lista outros sitemaps, a gente segue, e quando vem compactado em gzip, a gente descompacta. Ao mesmo tempo, a gente lê a página que você passou e guarda os links dela.
O sitemap escolhe as fontes. include, o padrão, lê as duas. only lê só os sitemaps. skip lê só os links da página, para um site sem sitemap.
Só as URLs que você quer
{
"url": "https://example.com",
"search": "blog",
"includeSubdomains": true,
"limit": 500
}Só voltam URLs do host que você passou, com ou sem www. Ligue o includeSubdomains para manter também o blog.example.com. O search deixa só as URLs que contêm uma palavra, sem diferenciar maiúsculas de minúsculas. O limit corta a lista: 5.000 se você não disser, 30.000 no máximo.
Cada página aparece uma vez
Um site lista a mesma página de vários jeitos. A gente tira o que vem depois do #, os parâmetros de rastreamento utm_ e a barra no final, e ordena o resto da query. Assim cada página volta uma vez só.
truncated: true quer dizer que o site pode listar mais do que veio. Ou o limit cortou a lista, ou faltou ler o robots.txt ou um dos sitemaps até o fim. Isso acontece quando o site bloqueou a leitura, o arquivo era grande demais, veio depois dos 25 primeiros sitemaps, o tempo do mapa acabou ou o nosso proxy falhou. Quando a falha é nossa, você recebe as URLs encontradas até ali, e o mapa não custa nada.
Da URL para a página
import { Scrapa } from "@scrapa/sdk";
const scrapa = new Scrapa(process.env.SCRAPA_API_KEY!);
const { urls } = await scrapa.map({ url: "https://example.com", search: "blog" });
const pages = await Promise.all(
urls.slice(0, 3).map(({ url }) => scrapa.scrape({ url })),
);Um mapa entrega endereços, não conteúdo. Leia as páginas que você precisa com o scrape, ou mande a lista inteira para um lote.
Quanto custa
2 créditos por mapa, ache o que achar. O tráfego pelo pool gerenciado é cobrado a partir do segundo megabyte, somando todos os arquivos que o mapa leu.
Site que não lista nada é cobrado, porque respondeu. Site que bloqueou todos os arquivos não custa nada, e nem qualquer falha nossa. Para ver o preço sem fazer a chamada, use POST /v1/map/quote.
A forma para o terminal
curl "https://api.scrapa.app/v1/map?url=https://example.com&search=blog&sitemap=only" \
-H "authorization: Bearer sc_live_your_key"A mesma operação em GET, para quando o corpo JSON atrapalha. O bloco de proxy se abre em parâmetros de query. No SDK o método é map(), e no MCP a ferramenta é map_site.