Developer Guide
Everything you need to integrate Klovr into your AI workflow.
Quick Start
Get started with Klovr in under 60 seconds. First, create an API key in your dashboard, then make your first request.
All requests require authentication. Create your free API key in the dashboard to get started.
curl "https://klovr.ai/api/convert?url=https://example.com" \ -H "Authorization: Bearer YOUR_API_KEY"
API Reference
Authentication
All API requests require authentication using Bearer token authentication. Include your API key in the Authorization header.
curl "https://klovr.ai/api/convert?url=https://example.com" \ -H "Authorization: Bearer YOUR_API_KEY"
Get your API key from the dashboard. Keep it secure and never expose it in client-side code.
/api/convertConvert any URL to clean, agent-ready Markdown with metadata and statistics.
Headers
AuthorizationrequiredBearer token authentication. Format: Bearer YOUR_API_KEY
Acceptoptionalconst response = await fetch('https://klovr.ai/api/convert?url=...', {
headers: {
'Authorization': 'Bearer YOUR_KEY',
'Accept': 'text/markdown' // Optional
}
});text/markdown - Returns raw markdown (no JSON wrapper)application/json - Returns full JSON response (default)Query Parameters
urlrequiredThe URL of the webpage to convert. Must be a valid HTTP/HTTPS URL.
cleanOutputoptionalRemove extra whitespace and normalize formatting. Default: true
includeFrontmatteroptionalInclude YAML frontmatter with metadata. Default: true
includeMetadataoptionalInclude metadata object in JSON response. Default: true
dynamiccoming soonUse headless browser to capture dynamic content (e.g. "Read More"). Slower response. Default: false
noCacheoptionalBypass cache and force fresh conversion. Default: false
💡 Tip: Klovr caches results for 7 days for 10-100x faster responses. Use noCache=true to get fresh content.
Response Headers
X-CacheCache status: HIT (served from cache) or MISS (fresh conversion)
Content-SignalAI agent compliance headers (Cloudflare-compatible):
ai-train=yes - Content can be used for AI trainingsearch=yes - Content can be indexed for searchai-input=yes - Content can be used as AI inputX-Markdown-TokensToken count of the markdown output (GPT-4 tokenizer)
X-Token-SavingsTokens saved compared to raw HTML (absolute number)
X-Token-Savings-PercentPercentage of tokens saved (typically 60-95%)
X-Processing-Time-MsProcessing time in milliseconds (excludes network latency)
X-RateLimit-*Rate limiting information:
X-RateLimit-Limit - Monthly request limitX-RateLimit-Remaining - Requests remaining this monthX-RateLimit-Reset - When the limit resets (ISO 8601)VaryValue: Accept - Indicates response varies based on Accept header
Cloudflare Compatibility
Klovr is 100% compatible with Cloudflare's "Markdown for Agents" standard, but works on 100% of websites - not just the 5% that enable Cloudflare's feature.
Use the same Accept header as Cloudflare:
curl -H "Accept: text/markdown" \
-H "Authorization: Bearer YOUR_API_KEY" \
"https://klovr.ai/api/convert?url=https://example.com"💡 Why Klovr? Cloudflare only serves markdown for sites that opt-in (~5% of the web). Klovr converts any website to markdown, bridging the 95% gap until universal adoption.
Response Format
All API responses are returned as JSON with the following structure:
{
"success": true,
"data": {
"markdown": "# Example Title\n\nContent...",
"metadata": {
"title": "Example Title",
"description": "..."
}
},
"usage": {
"total_tokens": 150,
"cost_saved": 0.002
}
}{
"success": false,
"error": "Invalid URL provided",
"code": "INVALID_URL"
}Response Headers
X-Markdown-TokensTotal tokens in the Markdown outputX-Token-Savings-PercentPercentage of tokens saved vs original HTMLCode Examples
JavaScript / Node.js
const url = 'https://example.com';
const apiKey = 'YOUR_API_KEY'; // Get from dashboard
const response = await fetch(
`https://klovr.ai/api/convert?url=${encodeURIComponent(url)}`,
{
headers: {
'Authorization': `Bearer ${apiKey}`
}
}
);
const data = await response.json();
if (data.success) {
console.log('Markdown:', data.markdown);
console.log('Tokens:', data.stats.tokens);
console.log('Savings:', data.stats.tokenSavingsPercent + '%');
} else {
console.error('Error:', data.error);
}Python
import requests
from urllib.parse import quote
url = "https://example.com"
api_key = "YOUR_API_KEY" # Get from dashboard
headers = {
"Authorization": f"Bearer {api_key}"
}
response = requests.get(
f"https://klovr.ai/api/convert?url={quote(url)}",
headers=headers
)
data = response.json()
if data['success']:
print('Markdown:', data['markdown'])
print('Tokens:', data['stats']['tokens'])
print('Savings:', data['stats']['tokenSavingsPercent'], '%')
else:
print('Error:', data['error'])Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
targetURL := "https://example.com"
apiKey := "YOUR_API_KEY" // Get from dashboard
apiURL := fmt.Sprintf(
"https://klovr.ai/api/convert?url=%s",
url.QueryEscape(targetURL),
)
req, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data map[string]interface{}
json.NewDecoder(resp.Body).Decode(&data)
if data["success"].(bool) {
fmt.Println("Markdown:", data["markdown"])
fmt.Println("Tokens:", data["stats"].(map[string]interface{})["tokens"])
}
}Dynamic Content (Headless Browser)
To capture content from Single Page Applications (SPAs) or sites with "Read More" buttons, add the dynamic=true parameter. This launches a headless browser to render the page.
curl "https://klovr.ai/api/convert?url=https://example.com&dynamic=true" \ -H "Authorization: Bearer YOUR_API_KEY"
Error Handling
Klovr uses standard HTTP status codes and returns detailed error messages.
| Status Code | Error Code | Description |
|---|---|---|
| 400 | INVALID_URL | The provided URL is invalid or malformed |
| 404 | NOT_FOUND | The URL could not be fetched (404 error) |
| 429 | RATE_LIMIT | Too many requests. Upgrade your plan or wait. |
| 500 | CONVERSION_FAILED | Failed to convert the page content |
| 503 | SERVICE_UNAVAILABLE | Service temporarily unavailable. Retry later. |
Best Practices
Cache Results
Klovr automatically caches conversions for 1 hour. If you need the same URL multiple times, store the result on your end to save requests.
Handle Rate Limits Gracefully
Implement exponential backoff when you receive a 429 response. Start with a 1-second delay and double it with each retry.
Validate URLs Before Sending
Check that URLs are valid and accessible before making API requests to avoid unnecessary errors and usage.
Monitor Token Usage
Use the stats object to track token savings and optimize your AI pipeline costs. Most pages see 40-60% reduction.