Página web para Markdown
Baixe uma página web e receba o conteúdo principal em Markdown, com opção de gravar na base de conhecimento.
Informe uma URL e receba o texto principal da página em Markdown limpo, com título e autor. Passando `collection_id`, o conteúdo também é gravado numa base de conhecimento. Lê apenas HTML estático (sem executar JavaScript) e recusa endereços internos e privados.
- Base path
/v1/tools/web- Escopos
tools:web:readtools:readtools:manage
Visão geral
Informe uma URL e receba o texto principal da página em Markdown, com título, autor e contagem de palavras. Com collection_id, o conteúdo também é gravado numa base de conhecimento. Também está disponível no MCP como web_to_markdown.
| Operação | Rota |
|---|---|
| Converter página em Markdown | POST/markdown |
Custos
A conversão é uma leitura medida: entra na franquia diária e, depois dela, debita o valor indicado no endpoint. Ao gravar numa base, a gravação é cobrada como uma ingestão da base de conhecimento.
Endpoints
Converter página em Markdown
/v1/tools/web/markdown- Custo
- Franquia diária, depois 0,01 crédito/leitura via API
- Dry-run
- Suportado (
X-Dry-Run: true) - Autenticação
- qualquer um de
tools:web:readtools:readtools:manage
url (obrigatório) é o endereço http ou https da página. collection_id (opcional) grava o conteúdo nessa base e exige também o escopo tools:rag:manage.
A resposta traz url, final_url (depois de redirecionamentos), title, byline, markdown e word_count. Com collection_id, vêm também document (document_id, status e duplicate) e, em dry-run, estimate.
Só HTML estático
A página é lida como o servidor a entrega, sem executar JavaScript: páginas que montam o conteúdo no navegador respondem tools.web.no_content. Endereços internos e privados são recusados (tools.web.blocked_url).
curl -sS -X POST 'https://api.respawntech.dev/v1/tools/web/markdown' \
-H "X-API-Token: $RESPAWN_API_TOKEN" \
-H 'Content-Type: application/json' \
-d '{ "url": "https://example.com/blog/post" }'const response = await fetch('https://api.respawntech.dev/v1/tools/web/markdown', {
method: 'POST',
headers: {
'X-API-Token': process.env.RESPAWN_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify({ "url": "https://example.com/blog/post" }),
});
if (!response.ok) throw new Error((await response.json()).error.code);
console.log(await response.json());import os
import requests
response = requests.post(
"https://api.respawntech.dev/v1/tools/web/markdown",
headers={
"X-API-Token": os.environ["RESPAWN_API_TOKEN"],
},
json={ "url": "https://example.com/blog/post" },
timeout=30,
)
if not response.ok:
raise RuntimeError(response.json()["error"]["code"])
print(response.json())<?php
$ch = curl_init('https://api.respawntech.dev/v1/tools/web/markdown');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'X-API-Token: ' . getenv('RESPAWN_API_TOKEN'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => <<<'JSON'
{ "url": "https://example.com/blog/post" }
JSON,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException(json_decode($body, true)['error']['code']);
}
print_r(json_decode($body, true));package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
req, err := http.NewRequest("POST", "https://api.respawntech.dev/v1/tools/web/markdown", strings.NewReader(`{ "url": "https://example.com/blog/post" }`))
if err != nil {
panic(err)
}
req.Header.Set("X-API-Token", os.Getenv("RESPAWN_API_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(string(data))
}
fmt.Println(string(data))
}Resposta 200
{
"success": true,
"trace_id": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"url": "https://example.com/blog/post",
"final_url": "https://example.com/blog/post",
"title": "Como funciona o nosso blog",
"byline": "Equipe Exemplo",
"markdown": "# Como funciona o nosso blog\n\nTexto da página…",
"word_count": 412
}
}Erros
| Código | HTTP | Quando |
|---|---|---|
tools.web.invalid_url | 400 | Campo url ausente ou inválido (só http e https). |
tools.web.blocked_url | 400 | URL recusada: aponta para um endereço interno ou privado. |
tools.web.fetch_failed | 502 | Não foi possível baixar a página. |
tools.web.not_html | 422 | O endereço não devolveu uma página HTML. |
tools.web.too_large | 413 | Página acima do tamanho máximo aceito. |
tools.web.no_content | 422 | Nenhum conteúdo de texto encontrado na página (por exemplo, página que depende de JavaScript). |
Atualizado em