Verwendung
- Installationsbefehl kopieren und das Quellpaket vor der Installation in der eigenen Agentenumgebung prüfen.
- Benötigte Werkzeuge, Zugangsdaten und Hosts im Original prüfen.
- Eingabe und gewünschtes Ergebnis beschreiben und die Ausgabe mit den Quellen abgleichen.
npx skills add https://github.com/octen-team/octen-skills --skill octen-extractVor dem Start
- Die Installation umfasst weder Modellabo noch API-Kontingent oder Dateizugriffsrechte.
- Sterne und Installationen zeigen Aktivität, keine unabhängige Qualitäts- oder Sicherheitsprüfung.
Aus dem Quell-Repository gerendert; Überschriften, Beispiele, Code, Tabellen, Links und Bilder bleiben erhalten.
Octen Extract
Turn one or more URLs into clean, LLM-ready content. Beyond the page body, each result also carries a category, a page-structure label, and — when you pass a query — query-relevant highlights instead of the full page.
Requires API Key: Get one at https://octen.ai · Set it: export OCTEN_API_KEY=your-api-keyAPI Key Setup
Before extracting, ensure `OCTEN_API_KEY` is set. On `401`, stop and tell the user a key is required (https://octen.ai), help them configure it, then continue. Configure the key for the relevant agent (same as other Octen skills):
- Claude Code — add
{ "env": { "OCTEN_API_KEY": "your-key" } }to~/.claude/settings.json - Cursor / generic shell —
export OCTEN_API_KEY="your-key"in~/.zshrcor~/.bashrc - Codex —
~/.codex/config.toml→[shell_environment_policy],set = { OCTEN_API_KEY = "your-key" } - OpenClaw — add
OCTEN_API_KEY=your-keyto~/.openclaw/.env
Endpoint
POST https://api.octen.ai/extractAuthentication: X-Api-Key: <API_KEY> header · Content-Type: application/json
Quick Start (cURL)
Batch extract (full content)
curl -s -X POST "https://api.octen.ai/extract" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${OCTEN_API_KEY}" \
-d '{
"urls": ["https://example.com", "https://octen.ai"],
"format": "markdown"
}'Query-driven highlights (instead of full content)
curl -s -X POST "https://api.octen.ai/extract" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${OCTEN_API_KEY}" \
-d '{
"urls": ["https://en.wikipedia.org/wiki/Python_(programming_language)"],
"query": "async programming"
}'Hard site (advanced mode)
curl -s -X POST "https://api.octen.ai/extract" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${OCTEN_API_KEY}" \
-d '{
"urls": ["https://www.reddit.com/r/LocalLLaMA/"],
"mode": "advanced",
"timeout": 60
}'Mixed batch, difficulty unknown (auto mode)
curl -s -X POST "https://api.octen.ai/extract" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${OCTEN_API_KEY}" \
-d '{
"urls": ["https://example.com", "https://octen.ai", "https://news.ycombinator.com/item?id=1"],
"mode": "auto",
"timeout": 60
}'Page links (outbound references first)
curl -s -X POST "https://api.octen.ai/extract" \
-H "Content-Type: application/json" \
-H "X-Api-Key: ${OCTEN_API_KEY}" \
-d '{
"urls": ["https://octen.ai"],
"include_links": {"scope": "prefer_external", "max_links": 50}
}'Parameters
| Parameter | Type | Required | Default | Description | |--|--|--|--|--| | urls | string[] | Yes | - | 1–20 URLs to fetch in one batch | | mode | string | No | standard (when omitted) | standard, advanced, or auto — see Choosing a mode | | query | string | No | - | When set, each result returns query-relevant highlights and OMITS full_content (max 500 chars) | | max_age_seconds | integer | No | 86400 | Accept cached results within this age (min 300); older cached versions are re-fetched | | format | string | No | markdown | Content format: markdown or text | | timeout | integer | No | 30 | Per-URL fetch budget in seconds (1–60) | | include_images | boolean | No | false | Include image resources found on the page (also returns cover_image when the page has one) | | include_videos | boolean | No | false | Include video URLs found on the page | | include_audio | boolean | No | false | Include audio URLs found on the page | | include_links | object | No | - | Use it to discover a site's pages or follow outbound references. Returns the page's links: {scope, max_links}. scope: prefer_internal (default; same-site links first) or prefer_external (other registered domains first); page order is kept within each group. max_links: 1–1000 (default 200; out of range → 400, not clamped). {} uses both defaults |
Choosing a mode
You pick the mode; omitting it means standard.
- `standard` (default): fastest and cheapest. Right for ordinary, well-structured pages without anti-bot protection — news, blogs, docs, product pages, static sites. On login-walled, JS-heavy, or anti-bot sites it can return empty content or just a page skeleton while still reporting `status: "success"`.
- `advanced`: highest success rate — renders in a real browser with stronger anti-bot handling; slower and 2.5x the price. Use it for known hard sites: anti-bot/WAF-protected sites, JS-heavy SPAs, social sites (Reddit, X, LinkedIn), academic sites (ResearchGate), dynamically loaded content.
- `auto`: decides per URL — standard where it suffices, advanced only for hard URLs; each URL is billed at the mode it actually used. Use it for a mixed batch when you can't tell which URLs are hard. If most URLs are hard, its cost approaches all-advanced.
| Scenario | mode | |--|--| | News / blogs / docs / product pages (ordinary sites) | standard (or omit) | | Known hard sites (Reddit / X / LinkedIn / ResearchGate / anti-bot / SPA) | advanced | | Mixed batch, unsure which are hard | auto | | Cost-sensitive, mostly ordinary sites | standard | | Quality first, mostly hard sites | advanced |
Rule of thumb: all ordinary sites → standard (or omit); known hard sites → advanced; mixed or unsure → auto.
Recovery: if a standard result failed, or came back empty/skeletal (page_structure.primary is "No Main Content", or very short content on a page that should have a body), retry just those URLs with "mode": "advanced".
Timeout: advanced and auto are slower — raise timeout (e.g. 60).
Response Format
| Field | Type | Description | |--|--|--| | request_id | string | Unique request identifier | | data.results[] | array | One result per URL | | data.results[].url | string | The URL | | data.results[].status | string | success or failed | | data.results[].resolved_mode | string? | standard or advanced — the mode actually used for this URL. Present on success, absent on failure. May differ from the requested mode (auto picks per URL; advanced can resolve to standard) | | data.results[].error_message | string? | Why it failed (when status = failed) | | data.results[].title | string? | Page title | | data.results[].full_content | string? | Cleaned page content (when no query) | | data.results[].highlights | string[]? | Query-relevant snippets (when query is set) | | data.results[].category | object? | {primary, secondary} — what the page is about | | data.results[].page_structure | object? | {primary, secondary} — what kind of page it is | | data.results[].time_published | string? | Publish time, ISO 8601 | | data.results[].time_last_crawled | string? | Last crawl time, ISO 8601 | | data.results[].favicon | string? | Page favicon URL — returned by default when available | | data.results[].cover_image | object? | {url} — page cover image (when include_images is true and the page has one) | | data.results[].images / videos / audio | object[]? | [{url}] — media found on the page (when the matching include_* is true) | | data.results[].links | object[]? | [{url, anchor_text, is_external}] — page links (on success, when include_links is set and links were found) | | meta.usage.total_urls | integer | URLs requested | | meta.usage.successful_urls | integer | URLs successfully fetched | | meta.usage.successful_by_mode | object | {standard_urls, advanced_urls} — successful URLs per mode. Actual billing is authoritative from these counts, not from summing resolved_mode | | meta.warning | string | e.g. "1 URL(s) failed and were not billed"; empty string when there is nothing to report |
meta is top-level (a sibling of data), not data.meta.
Error Codes
| HTTP Status | Description | |--|--| | 400 | Missing or invalid parameter | | 401 | Invalid or missing API key | | 403 | Insufficient balance | | 429 | Rate limited | | 500 | Internal server error |
Notes
- Partial success is first-class: a failed URL is returned with
status: "failed"+ anerror_message; sibling URLs in the same batch still succeed. Always check per-resultstatus. - Pass
queryonly when you want focusedhighlightsfor RAG/grounding; omit it to get the full cleaned page. - Pricing:
standard$1 / 1K successful URLs,advanced$2.5 / 1K. Failed URLs are not billed. categoryandpage_structurelet you route or filter pages (e.g., skip an index/operation page, keep a content page) without reading the whole body.



