API reference
The /api/v1/skim endpoint takes a URL and returns
an article in the format you ask for. Authenticate with a
personal access token you create on the
keys page.
Authentication
Every call to /api/v1/skim needs a key. Pass it
any of three ways:
X-Api-Key: db_...(header)Authorization: Bearer db_...(header)?api_key=db_...(query string — handy for browser-address-bar GETs; keep in mind URLs land in server logs, so prefer headers for production)
Keys are SHA-256 hashed on the server — only the 7-char
prefix is recoverable after creation. Revoke a key from the
admin UI at any time; the next call using it returns
401 Unauthorized.
POST /api/v1/skim
Request body (JSON):
{
"url": "https://en.wikipedia.org/wiki/JavaScript",
"format": "json" | "md" | "markdown" | "html",
"scripting": true
}
curl (Markdown out):
curl -X POST https://broski.daisi.ai/api/v1/skim \
-H "Content-Type: application/json" \
-H "Authorization: Bearer db_YOUR_KEY_HERE" \
-d '{"url":"https://en.wikipedia.org/wiki/JavaScript","format":"md"}'
GET /api/v1/skim
Same service, query-string arguments. Every field of the
POST body maps to a query param of the same name. Pass the
API key as api_key or via the usual headers.
GET https://broski.daisi.ai/api/v1/skim?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FJavaScript
&format=md&scripting=true&api_key=db_YOUR_KEY_HERE
curl:
curl "https://broski.daisi.ai/api/v1/skim?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FJavaScript&format=md" \
-H "Authorization: Bearer db_YOUR_KEY_HERE"
Response (200, text/markdown):
# JavaScript - Wikipedia
on _en.wikipedia.org_ • [source](https://en.wikipedia.org/wiki/JavaScript)
JavaScript (/ˈdʒɑːvəskrɪpt/), often abbreviated as JS, is a
programming language and core technology of the Web...
Response format
Pick your output with the format field:
json(default) — structuredArticleContentwithtitle,byline,publishedAt,lang,siteName,description,heroImage,plainText,images[],links[],navLinks[].md/markdown— CommonMark with inline links, tables, and hero-image reference.html— reader-mode HTML, just the article subtree.
The scripting flag
When scripting is true (the default),
the engine executes the page's inline + external scripts before
extraction. This is required for SPAs (Next.js, Nuxt, Remix)
where the interesting content is client-rendered. Set it to
false for static-HTML pages — it's both faster and
more deterministic.
Error responses
400 Bad Request- Missing or malformed
url. Body is{ "error": "..." }. 401 Unauthorized- No credentials, or a revoked / expired key.
502 Bad Gateway- Upstream fetch failed — DNS, TLS, the site refused, or the
content stream was malformed. Details in the
application/problem+jsonbody. 499 Client Closed Request- The HTTP client disconnected mid-skim; the skim was cancelled and nothing was billed.
GET /api/v1/health
Unauthenticated heartbeat. Returns 200 with
{ "status": "ok" }. Use for uptime probes.
Limits
Request body capped at 50 KiB; response streaming capped at
50 MiB per skim. PDFs that require features outside our
shipped scope (non-empty passwords, CID fonts without
/ToUnicode, image-only scans) return a short
article explaining the fallback — they don't 500.