27 paid services across 17 plugins: AI content detection, web search, Chainlink oracle feeds, HuggingFace AI, YouTube, social-media downloads (TikTok, Rumble, BitChute, x.com and the rest of yt-dlp's ~1800 extractors), media, image gen, code sandbox, PDF, and more. Pay with Stripe or crypto. Auto-refund on failures.
All accessible via a single API key. Failed requests auto-refund. Dimmed = currently offline.
Detect AI-generated text, images, video, and audio
Tiered: basic 1, stealth 2, full 3, render 3. Metadata, text, links, HTML, screenshots
Cache lookup 1, full-text corpus search 2, snapshot timeline 1, cache-first scrape 2. Pulls from an existing archive instead of re-scraping.
Audio (MP3) 8 cr, Video (MP4) 10 cr
TikTok, Rumble, BitChute, x.com, SoundCloud, Streamable, Dailymotion, Bilibili, Twitch + the rest of yt-dlp's ~1800 extractors. MP3 8 cr, MP4 10 cr.
AI text-to-image from prompts
Convert, trim, compress, extract audio/video via FFmpeg
Text extraction from images and scans
Python, Node, Bash, Ruby, Go
Merge, split, compress, extract text
Real web search, stocks, crypto, weather, news
Sentiment, summarization, QA, translation, embeddings
Price feeds across 7 networks
Token analysis, holder distribution, risk score
Wallet analysis, transaction history, risk assessment
Smart contract security analysis
Resize, optimize, watermark, transform
Bot-filtering captcha alternatives
Headlines, search articles, sources
APOD, Mars Rover, NEOs, Earth imagery
Song lyrics search, synced LRC format
Search, details, top rated, recommendations
Download from 1000+ video sites
Professional media transcoding
Current conditions, forecasts, historical
Failed requests are never charged
Full catalog: GET /service/catalog โ all available services with descriptions and credit costs
Pay-as-you-go credits for the full API, or a flat-rate scraping subscription. Mix and match โ credits cover all 25 services, subscriptions cover scraping at a deep discount.
Use across every service: scraping, YouTube, AI image gen, transcoding, code sandbox, PDF tools, plugins. Credits don't expire.
Predictable monthly bill for sites that scrape a lot. Two quota buckets per plan: basic (covers basic/stealth/full tiers) and render (JS-heavy pages with headless Chromium). Quotas reset on every renewal. Calls past the cap automatically fall back to your credit balance โ never break.
Cancel any time from your dashboard โ keeps quota until period end. Monthly Stripe billing. Subscriptions never charge for failed scrapes (auto-refunded to your quota).
No email needed. Auth with your BSC wallet, send BNB or SKYNET, get credits instantly.
curl https://api.lanagent.net/auth/nonce?wallet=0xYOUR_WALLET # Returns: { "nonce": "scrape_gateway_auth_..." }
curl -X POST https://api.lanagent.net/auth/verify -H 'Content-Type: application/json' -d '{"wallet":"0x...","signature":"0x...","nonce":"..."}' # Returns: { "token": "eyJ..." }
curl -X POST https://api.lanagent.net/auth/api-key -H 'Authorization: Bearer YOUR_JWT' -d '{"name":"my-app"}' # Returns: { "apiKey": "gsk_..." }
curl https://api.lanagent.net/credits/price # Returns: recipientAddress, pricePerCredit.bnb, # pricePerCredit.skynet, bnbPrice
# Send BNB or SKYNET to recipientAddress
# from Step 4. Use MetaMask, ethers.js, etc.
# Save the transaction hash.
curl -X POST https://api.lanagent.net/credits/purchase -H 'X-API-Key: gsk_YOUR_KEY' -H 'Content-Type: application/json' -d '{"txHash":"0x...","currency":"BNB"}' # currency must match what you sent: "BNB" or "SKYNET". # Credits added automatically!
Prices update every 15 minutes from PancakeSwap + Chainlink oracle. Auto-refund on all failures.
Get an API key in 30 seconds. All examples use your gsk_* key.
# Sign up (returns API key instantly) curl -X POST https://api.lanagent.net/portal/signup -H 'Content-Type: application/json' -d '{"email": "[email protected]", "password": "your-password"}' # Response: { "apiKey": "gsk_abc123...", "token": "eyJ...", "credits": 0 }
# Start Stripe checkout (use token from signup) curl -X POST https://api.lanagent.net/portal/checkout -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' -d '{"package": "starter"}' # Response: { "checkoutUrl": "https://checkout.stripe.com/..." } # Open the URL to complete payment. Credits added instantly.
All 25 services use the same pattern: POST /service/{plugin}/{action}
curl -X POST https://api.lanagent.net/service/aiDetector/detectText \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"text":"The quick brown fox jumps over the lazy dog."}'
curl -X POST https://api.lanagent.net/service/aiDetector/detectImage \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/photo.jpg"}'
curl -X POST https://api.lanagent.net/service/aiDetector/detectAudio \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/speech.mp3"}'
curl -X POST https://api.lanagent.net/service/aiDetector/detectVideo \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/video.mp4"}'
curl -X POST https://api.lanagent.net/scrape -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://news.ycombinator.com","tier":"basic"}' # Fast static fetch. The scrape result is always under "data": # { "success": true, # "data": { # "title": "Hacker News", # "text": "โฆvisible page textโฆ", # "links": ["https://โฆ", โฆ], # "metadata": { "description": "โฆ", "og:image": "โฆ", โฆ }, # "jsonld": [ โฆ ] # structured data when present # }, # "tier": "basic", "creditsCharged": 1, "creditsRemaining": 399 } # Tiers add fields: full/render also return data.html; render also data.screenshot.
curl -X POST https://api.lanagent.net/scrape -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://www.amazon.com/dp/B0DHHM3WRM","tier":"stealth"}' // Rotates UA + bypasses anti-bot fingerprinting
curl -X POST https://api.lanagent.net/scrape -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://dexscreener.com/bsc/0x0e09f...","tier":"render","fullPage":true}' # Headless Chromium runs the page's JS, returns the post-render content + a screenshot. # Response (the scrape result is under "data"): # { "success": true, # "data": { # "title": "โฆ", # "text": "โฆvisible textโฆ", # "html": "<!doctype html>โฆpost-render DOMโฆ", # render/full tiers # "screenshot": "data:image/png;base64,iVBORw0KGgoโฆ" # render tier; PNG data URI # }, # "tier": "render", "creditsCharged": 3 } # fullPage:true โ a tall full-page capture (capped ~3000px); omit for a viewport shot. # Decode the screenshot: echo "<base64>" | base64 -d > shot.png (strip the data: prefix)
curl 'https://api.lanagent.net/archive/lookup?url=https://example.com&max_age=7d' -H 'X-API-Key: gsk_YOUR_KEY' // Latest cached snapshot with title, text, html, screenshot URLs. // 404 + refund on no match. Cheap pre-check before a fresh scrape.
curl 'https://api.lanagent.net/archive/search?q=climate+report+2026&limit=10' -H 'X-API-Key: gsk_YOUR_KEY' // Full-text search across the corpus. Filters: // domain=, since=, until=, quality_tier=text|full|metadata
curl -X POST https://api.lanagent.net/archive/scrape -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://news.ycombinator.com"}' // Flat 2 cr โ cache hit returns immediately at the same price. // Cache miss (or prefer:"fresh") falls through to a fresh scrape // and auto-ingests the result back into the archive.
curl 'https://api.lanagent.net/archive/timeline?url=https://example.com&limit=20' -H 'X-API-Key: gsk_YOUR_KEY' // Every snapshot of a URL with timestamps + quality tier. // Use to detect content change over time.
curl -X POST https://api.lanagent.net/youtube/download -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://youtube.com/watch?v=..."}'
curl -X POST https://api.lanagent.net/youtube/audio -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://youtube.com/watch?v=..."}'
curl -X POST https://api.lanagent.net/transcode -H 'X-API-Key: gsk_YOUR_KEY' -F '[email protected]' -F 'format=mp4' -F 'preset=fast' // FFmpeg: convert, trim, compress, extract audio
curl -X POST https://api.lanagent.net/image/generate -H 'X-API-Key: gsk_YOUR_KEY' -d '{"prompt":"A sunset over mountains"}'
curl -X POST https://api.lanagent.net/sandbox/execute -H 'X-API-Key: gsk_YOUR_KEY' -d '{"code":"print(sum(range(101)))","language":"python"}'
curl -X POST https://api.lanagent.net/service/anime/search -H 'X-API-Key: gsk_YOUR_KEY' -d '{"query":"Cowboy Bebop"}'
curl -X POST https://api.lanagent.net/service/chainlink/price -H 'X-API-Key: gsk_YOUR_KEY' -d '{"pair":"BTC"}'
curl -X POST https://api.lanagent.net/price/feeds?network=all -H 'X-API-Key: gsk_YOUR_KEY' -d '{}'
curl -X POST https://api.lanagent.net/service/huggingface/sentimentAnalysis -H 'X-API-Key: gsk_YOUR_KEY' -d '{"inputs":"I love this product!"}'
curl -X POST https://api.lanagent.net/service/huggingface/textSummarization -H 'X-API-Key: gsk_YOUR_KEY' -d '{"inputs":"Long article text to summarize..."}'
curl -X POST https://api.lanagent.net/service/huggingface/translation -H 'X-API-Key: gsk_YOUR_KEY' -d '{"inputs":"Good morning, how are you?"}'
curl -X POST https://api.lanagent.net/service/huggingface/zeroShotClassification -H 'X-API-Key: gsk_YOUR_KEY' -d '{"inputs":"I need a phone","candidate_labels":["shopping","travel","food"]}'
curl -X POST https://api.lanagent.net/service/websearch/search -H 'X-API-Key: gsk_YOUR_KEY' -d '{"query":"latest AI news 2026"}'
curl -X POST https://api.lanagent.net/service/websearch/weather -H 'X-API-Key: gsk_YOUR_KEY' -d '{"location":"Tokyo"}'
curl -X POST https://api.lanagent.net/service/websearch/stock -H 'X-API-Key: gsk_YOUR_KEY' -d '{"symbol":"AAPL"}'
curl -X POST https://api.lanagent.net/service/huggingface/questionAnswering -H 'X-API-Key: gsk_YOUR_KEY' -d '{"question":"When was it built?","context":"The Eiffel Tower was built from 1887 to 1889."}'
curl -X POST https://api.lanagent.net/service/websearch/news -H 'X-API-Key: gsk_YOUR_KEY' -d '{"query":"artificial intelligence"}'
curl -X POST https://api.lanagent.net/service/lyrics/search -H 'X-API-Key: gsk_YOUR_KEY' -d '{"query":"bohemian rhapsody"}'
curl -X POST https://api.lanagent.net/service/nasa/apod -H 'X-API-Key: gsk_YOUR_KEY' -d '{}'
curl -X POST https://api.lanagent.net/service/challengeQuestions/generateWithAnswers -H 'X-API-Key: gsk_YOUR_KEY' -d '{"count":3}' # Sample response: # { # "success": true, # "data": { # "questions": [ # { "id": 1, "type": "math", # "question": "What is 7 + 5?", # "acceptableAnswers": ["12", "twelve"] }, # { "id": 2, "type": "color", # "question": "What color do you get mixing red and blue?", # "acceptableAnswers": ["purple", "violet"] }, # { "id": 3, "type": "common-knowledge", # "question": "How many days are in a week?", # "acceptableAnswers": ["7", "seven"] } # ] # } # }
curl -X POST https://api.lanagent.net/service/challengeQuestions/generate -H 'X-API-Key: gsk_YOUR_KEY' -d '{"count":3}' # Returns: # { "data": { "token": "chq_a3f9โฆ", # "questions": [ # { "id": 1, "question": "What is 7 + 5?" }, # { "id": 2, "question": "What color do you get mixing red and blue?" }, # { "id": 3, "question": "How many days are in a week?" } # ], # "expiresIn": 600 } } # Verify the user's answers with: curl -X POST https://api.lanagent.net/service/challengeQuestions/verify -H 'X-API-Key: gsk_YOUR_KEY' -d '{"token":"chq_a3f9โฆ","answers":[ {"id":1,"answer":"12"}, {"id":2,"answer":"purple"}, {"id":3,"answer":"7"} ]}' # { "data": { "passed": true, "score": 3, "total": 3, # "receipt": "cvr_b81eโฆ" } }
curl -X POST https://api.lanagent.net/service/tokenProfiler/audit \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"address":"0x8Ef0...","chain":"bsc"}'
curl -X POST https://api.lanagent.net/service/walletProfiler/profile \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"address":"0xF977...","network":"bsc"}' // Try any public address โ example is Binance hot wallet
curl -X POST https://api.lanagent.net/service/contractAudit/audit \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"address":"0xFfA9...","chain":"bsc"}'
curl -X POST https://api.lanagent.net/service/imageTools/optimize \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/photo.jpg","format":"webp","quality":80}' # Also: /resize, /watermark, /transform
curl -X POST https://api.lanagent.net/pdf/text \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/document.pdf"}' # Also: /pdf/merge, /pdf/split, /pdf/compress
curl -X POST https://api.lanagent.net/service/ffmpeg/transcode \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://example.com/video.mp4","format":"mp3"}'
curl -X POST https://api.lanagent.net/youtube/audio \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"url":"https://youtube.com/watch?v=..."}'
curl -X POST https://api.lanagent.net/service/chainlink/feeds \ -H 'X-API-Key: gsk_YOUR_KEY' \ -d '{"network":"bsc"}' # Also: /historical, /compare, /info
# pip install requests import requests API = "https://api.lanagent.net" KEY = "gsk_YOUR_KEY" headers = {"X-API-Key": KEY, "Content-Type": "application/json"} # Scrape a webpage (2 credits) r = requests.post(f"{API}/scrape", json={"url": "https://example.com"}, headers=headers) print(r.json()["data"]["title"]) # Web Archive โ cache-first scrape (2 credits flat, hit OR miss) # Same result as /scrape, but pulls from cache when possible. Falls # through to a live agent on miss and auto-ingests the result back. r = requests.post(f"{API}/archive/scrape", json={"url": "https://example.com"}, headers=headers) print(r.json()["data"]["title"], "via", r.json()["agent"]["name"]) # Web Archive โ lookup latest cached snapshot (1 credit) # 404 + refund on miss. Cheap pre-check before a fresh scrape. r = requests.get(f"{API}/archive/lookup", params={"url": "https://example.com", "max_age": "7d"}, headers={"X-API-Key": KEY}) print(r.json().get("title"), "@", r.json().get("scraped_at")) # Web Archive โ full-text search across the corpus (2 credits) r = requests.get(f"{API}/archive/search", params={"q": "climate report 2026", "limit": 10}, headers={"X-API-Key": KEY}) for hit in r.json().get("hits", []): print(hit.get("title")) # Search anime (1 credit) r = requests.post(f"{API}/service/anime/search", json={"query": "Naruto"}, headers=headers) print(r.json()["data"]["results"][0]["title"]) # Run Python code (20 credits) r = requests.post(f"{API}/sandbox/execute", json={"code": "print(2**100)", "language": "python"}, headers=headers) print(r.json()["stdout"]) # Chainlink price feed (1 credit) r = requests.post(f"{API}/service/chainlink/price", json={"pair": "ETH"}, headers=headers) print(r.json()["data"]["price"]) # Real web search (2 credits) r = requests.post(f"{API}/service/websearch/search", json={"query": "latest AI news"}, headers=headers) print(r.json()["result"]) # HuggingFace sentiment (10 credits) r = requests.post(f"{API}/service/huggingface/sentimentAnalysis", json={"inputs": "I love this!"}, headers=headers) print(r.json()["result"]) # "POSITIVE: 100.0%" # Detect AI-generated text (5 credits) r = requests.post(f"{API}/service/aiDetector/detectText", json={"text": "Paste any text here to check..."}, headers=headers) print(r.json()["data"]["verdict"]) # "human", "ai_generated", or "uncertain" # Detect AI-generated image (5 credits) r = requests.post(f"{API}/service/aiDetector/detectImage", json={"url": "https://example.com/photo.jpg"}, headers=headers) print(r.json()["data"]["verdict"], r.json()["data"]["confidence"]) # Bot-filtering challenge questions (2 credits) r = requests.post(f"{API}/service/challengeQuestions/generateWithAnswers", json={"count": 3}, headers=headers) for q in r.json()["data"]["questions"]: print(q["question"], "->", q["answer"]) # Token profiler (3 credits) r = requests.post(f"{API}/service/tokenProfiler/audit", json={"address": "0x8b77CC5c6cB3d846608d9d5Dd03fA406BA03b8F1", "chain": "bsc"}, headers=headers) print(r.json()["result"]) # Image optimization (2 credits) r = requests.post(f"{API}/service/imageTools/optimize", json={"url": "https://example.com/photo.jpg", "format": "webp", "quality": 80}, headers=headers) print(r.json()["result"]) # Lyrics search (1 credit) r = requests.post(f"{API}/service/lyrics/search", json={"query": "bohemian rhapsody"}, headers=headers) print(r.json()["result"][:80]) # Image generation (30 credits) r = requests.post(f"{API}/image/generate", json={"prompt": "A sunset over mountains"}, headers=headers) print(r.json().get("downloadUrl", r.json().get("result", ""))) # NASA Astronomy Picture of the Day (1 credit) r = requests.post(f"{API}/service/nasa/apod", json={}, headers=headers) print(r.json()["data"]["title"], "-", r.json()["data"]["explanation"][:100]) # Check remaining credits print("Credits left:", r.json()["creditsRemaining"])
API Reference โ โ auth, billing, error codes, rate limits, challenge-question details. Full catalog: GET /service/catalog | Service Pricing | Agent Directory | Credit Pricing
Authentication, billing, error codes, rate limits, and per-service details. Everything an integrator needs to ship.
Send your API key on every paid request:
X-API-Key: gsk_โฆ
Or use a portal JWT: Authorization: Bearer <jwt>. Missing/invalid auth returns HTTP 401 with { "success": false, "error": "Authentication required..." }.
Credits debit before the agent runs. What happens next, per outcome:
| Outcome | HTTP | Refunded? |
|---|---|---|
Successful response (success: true) | 200 | No โ call ran |
Agent returned success: false | 500 | Yes |
| Agent unreachable / threw | 502 | Yes |
| No agents online for the service | 503 | N/A (not debited) |
| Caller out of credits | 402 | N/A (not debited) |
| Auth missing/invalid | 401 | N/A (not debited) |
A success:true response with a "negative" application-level result โ challenge passed:false, a honeypot flag on token audit, an empty wallet profile, no-feed-found on a price lookup โ is billable. The service ran and produced a real answer. Auto-refunds fire on infrastructure or service-availability failures, not on factual results the caller didn't want.
Exception: a few plugins explicitly auto-refund successful responses produced via a fallback path (e.g. Chainlink โ CoinGecko fallback returns creditsCharged:0, creditsRefunded:1). The default rule is: success:true โ billed.
When the calling key runs out, the gateway returns HTTP 402 (Payment Required) โ not 503:
{
"success": false,
"error": "Insufficient credits",
"required": 2,
"balance": 0
}
Match on the error string โ it's the stable identifier. balance is the current balance; required is what the call would have cost. (HTTP 503 means the gateway can't serve the call at all โ no agents online or gateway out of credits on its agents.)
No per-API-key rate limit on paid endpoints โ throughput is bounded only by your credit balance. The only IP-based rate limits on the gateway apply to portal/admin auth pages (/portal/signup, /portal/login, /portal/forgot-password, /admin/login): 10 attempts per 15-minute window, returning HTTP 429 with { "success": false, "error": "Too many attempts. Try again in 15 minutes." }. IPv6 clients are bucketed by /64 prefix.
Paid endpoints are not idempotent โ a retry after a 200 will re-bill. Safe to retry on 502, 503, and network errors; those were either refunded or never debited. On 402, top up credits before retrying. Default request timeout 60s; image generation 120s, YouTube download 180s, media transcode 300s. Social download/audio run up to 600s โ past ~45s the gateway streams a keep-alive heartbeat (leading JSON whitespace) so a long yt-dlp download runs to completion instead of timing out; give your HTTP client a read timeout of at least 600s. For very long downloads prefer the async variants (up to 900s) and poll for the result โ see Social & media downloads below.
Download from TikTok, Rumble, BitChute, x.com, SoundCloud, Streamable, Dailymotion, Bilibili, Twitch and the rest of yt-dlp's ~1800 extractors. Two ways to call it: a synchronous request that returns the finished download, or an async job you submit and poll (best for very long downloads). Failed downloads auto-refund.
| Endpoint | Credits | Behavior |
|---|---|---|
POST /social/download {url} | 10 | Sync MP4. Runs up to 600s; heartbeat keeps the connection alive past ~45s. Returns the finished download. |
POST /social/audio {url} | 8 | Sync MP3 (audio extracted + transcoded). Same timeout/heartbeat as above. |
POST /social/download/async {url} | 10 | Submit โ 202 {jobId, statusUrl, ttlSeconds} immediately. Runs in the background up to 900s. Poll statusUrl. |
POST /social/audio/async {url} | 8 | Async MP3 variant. |
GET /social/jobs/:jobId | free | Poll job status. Jobs are retained ~10 min after finishing (ttlSeconds). |
Poll responses โ a status read that finds your job always returns HTTP 200; check the status field (not the HTTP code) to decide what to do. Only poll-level problems are non-2xx: 404 = unknown/expired jobId, 403 = not your job.
200 {status:"pending"} | Still downloading โ keep polling (a 2โ3s interval is plenty). ageSeconds shows how long it's been running. |
200 {status:"done", โฆ} | Finished. Body carries the same fields as the sync response (downloadUrl, filename, size, โฆ). |
200 {status:"failed", โฆ} | Download failed (credits already refunded). upstreamStatus carries the real failure code and error the reason. Stop polling โ this is terminal, not a transient gateway error. |
Sync download (MP4):
curl --max-time 600 -X POST https://api.lanagent.net/social/download -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://www.tiktok.com/@user/video/1234567890"}' # { "success": true, "extractor": "tiktok", # "downloadUrl": "/download/2930/eyJhbGciOiโฆ", # fetch this to get the file (valid 60 min, 3 downloads) # "filename": "video.mp4", "size": 4821904, "caption": "โฆ", # "creditsCharged": 10, "creditsRemaining": 390 } # For MP3 use POST /social/audio (8 cr).
Async โ submit, then poll (best for long videos):
curl -X POST https://api.lanagent.net/social/download/async -H 'X-API-Key: gsk_YOUR_KEY' -d '{"url":"https://rumble.com/v123-long-video.html"}' # 202 { "success": true, "jobId": "c14c1642-โฆ", "statusUrl": "/social/jobs/c14c1642-โฆ", "ttlSeconds": 600 } curl https://api.lanagent.net/social/jobs/c14c1642-โฆ -H 'X-API-Key: gsk_YOUR_KEY' # 200 { "status": "pending", "ageSeconds": 42 } โ keep polling # 200 { "status": "done", "downloadUrl": "/download/2930/โฆ", "filename": "โฆ", "size": โฆ } # 200 { "status": "failed", "upstreamStatus": 502, "error": "โฆ" } โ terminal, credits refunded
Bot-filtering challenge questions. See the Quick Start above for request examples; the table below covers the behavior every integrator hits.
| Credit cost | 2 credits per call (all actions: generate, generateWithAnswers, verify, types, trackPerformance) |
| Token format / TTL | chq_ + 48 hex chars; 600 seconds (10 minutes) from generate. TTL is also returned as data.expiresIn. |
| Max verify attempts per token | 3 โ token is deleted on success or after the 3rd wrong submission; the 4th call returns { success:false, error:"Max verification attempts exceeded" }. |
| Pass threshold | 70% correct (ceil(total ร 0.7)) |
| Question count | 1โ20 per call (default 3); clamped server-side |
| Receipt | cvr_ + 48 hex chars on passed:true. Persist this as proof-of-pass. |
| Answer matching | Case-insensitive, trimmed; each question carries an acceptableAnswers list (e.g. "12" / "all of them" both pass for "how many months have 28 days"). |
| Wrong-answer billing | Billable. A verify returning passed:false is success:true at the protocol level โ the service ran and produced a real answer. Only success:false outcomes auto-refund: missing token/answers[], invalid/expired token, or the 4th submission against the same token. |
Cache-backed scraping. Skip the agent dispatch when a recent snapshot exists; fall through to a fresh scrape only when needed. Every fresh /scrape and /archive/scrape ingests its result into the corpus automatically.
| Endpoint | Credits | Behavior |
|---|---|---|
GET /archive/lookup?url=&max_age=&min_quality=&screenshot_format= | 1 | Latest snapshot with metadata + presigned artifact URLs. 404 + refund on miss, 410 + refund on redacted. |
GET /archive/timeline?url=&limit=&offset=&max_age=&min_quality= | 1 | Every snapshot of a URL ordered newest-first. 404 + refund on url_unknown. |
GET /archive/search?q=&domain=&since=&until=&limit=&offset=&quality_tier= | 2 | Meili full-text search across the entire corpus. |
POST /archive/scrape {url, tier?, prefer?} | 2 flat | Cache-first. Cache hit serves immediately at the same price. Miss (or prefer:"fresh") falls through to a fresh agent dispatch and auto-ingests the result. prefer:"cache" only โ 404 + refund on miss. |
| Freshness | max_age as suffixed duration: 6h / 24h / 7d / 30d. min_quality: metadata / text / full. screenshot_format on lookup: png (default) / jpeg / avif. | |
Have a question this doesn't answer? Open a GitHub issue or email [email protected].