Mode d’emploi
- Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
- Consultez le document original pour les outils, identifiants et environnements requis.
- Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/octen-team/octen-skills --skill octen-extractAvant de commencer
- L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
- Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
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.



