POST /v1/read
Fetch any public URL and return clean Markdown plus extraction stats.
Cached for 1 hour per (URL, engine version). Set
"fresh": true to bypass.Endpoint
http
POST https://api.buildonto.dev/v1/read
Authorization: Bearer onto_sk_...
Content-Type: application/jsonRequest body
urlstringrequiredThe public URL to fetch and clean. Must be http:// or https://.
freshbooleanoptionalIf true, bypass the 1-hour cache and force a fresh fetch + extraction. Default: false.
Response
Success (200): JSON by default. Add Accept: text/markdown to get raw Markdown back instead.
json
{
"status": "success",
"url": "https://stripe.com",
"markdown": "# Stripe — Online payments…\n\n…",
"metadata": {
"title": "Stripe | Financial Infrastructure...",
"description": "Stripe powers online and...",
"language": "en"
},
"stats": {
"raw_html_size_kb": 605.0,
"markdown_size_kb": 14.8,
"reduction_percent": 97.6,
"extraction_time_ms": 412
},
"cache": { "hit": false, "ttl_seconds": 3600 }
}Errors: see error codes. Common ones for this endpoint: INVALID_URL (400), UNAUTHORIZED (401), ROBOTS_BLOCKED (403), WAF_BLOCKED (403), URL_NOT_FOUND (404), RATE_LIMITED (429), PAYMENT_REQUIRED (402), CONCURRENT_LIMIT (429), TIMEOUT (504).
Response headers
X-RateLimit-RemainingintoptionalPlan quota remaining for the current month.
X-RateLimit-ResetISO dateoptionalWhen the monthly counter resets (end of UTC month).
X-Onto-Billed'plan' | 'credit'optionalWhether this request hit your plan counter or debited a credit (overage).
X-Credits-RemainingintoptionalCredit balance after this request (only present when source='credit').
X-Concurrent-RemainingintoptionalHow many more in-flight requests you have headroom for at this moment.
X-Onto-Cache'HIT' | 'MISS'optionalWhether the response came from cache or a fresh fetch + extraction.
Examples
cURL — JSON response:
bash
curl -X POST https://api.buildonto.dev/v1/read \
-H "Authorization: Bearer $ONTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com"}'cURL — Markdown response (no JSON wrapper):
bash
curl -X POST https://api.buildonto.dev/v1/read \
-H "Authorization: Bearer $ONTO_API_KEY" \
-H "Accept: text/markdown" \
-H "Content-Type: application/json" \
-d '{"url": "https://stripe.com"}'Node (fetch):
ts
const res = await fetch('https://api.buildonto.dev/v1/read', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ONTO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url: 'https://stripe.com' }),
});
const data = await res.json();
console.log(data.markdown);Python (httpx):
python
import os, httpx
r = httpx.post(
"https://api.buildonto.dev/v1/read",
headers={"Authorization": f"Bearer {os.environ['ONTO_API_KEY']}"},
json={"url": "https://stripe.com"},
)
print(r.json()["markdown"])