Web data infrastructure for AI agents and research
Cormorant searches the web, fetches any page or PDF, and looks up companies in official registers, through one API that tells you what every call cost.
Service status- CacheInstant answers for pages fetched recently.cached
- Direct fetchA plain request that carries a real browser's TLS and HTTP/2 fingerprint.TLS fingerprint
- Headless browserRenders JavaScript-heavy pages and waits out interstitials.JS rendering
- Residential networkFor sites that block data-centre traffic, from a country you choose if needed.geo-targeted
- Archives & alternative copiesWhen the original is gone or paywalled: snapshots and verified copies elsewhere.archive
You get back clean text and the exact bytes with their SHA-256, the route that worked, timings for every step and how the call is billed.
What you get
Search
Several engines asked at once, results merged by agreement and cached, so the same question costs once.
POST /v1/searchFetch
Any page or PDF as clean text plus the exact bytes, with paywall and archive handling built in.
POST /v1/fetchCompany data
One structured register with source attribution, built from official registers, GLEIF and SEC EDGAR.
GET /v1/companies/{id}Batch
Up to 50,000 searches or fetches per job, with a callback to your server when it is done.
POST /v1/batch/fetch
A search, then a fetch
Two JSON requests with one API key. Every response says which route answered, whether it came from the cache, and how the call is billed.
# 1. Search the web
curl -sS https://api.cormorant.ch/v1/search \
-H "Authorization: Bearer $CORMORANT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "Holcim annual report 2025", "max_results": 5}'
# 2. Fetch the page you picked
curl -sS https://api.cormorant.ch/v1/fetch \
-H "Authorization: Bearer $CORMORANT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://www.holcim.com/investors"}'import os
import httpx
client = httpx.Client(
base_url="https://api.cormorant.ch",
headers={"Authorization": f"Bearer {os.environ['CORMORANT_API_KEY']}"},
timeout=180,
)
# 1. Search the web
hits = client.post(
"/v1/search", json={"query": "Holcim annual report 2025", "max_results": 5}
).json()["results"]
# 2. Fetch the first result
page = client.post("/v1/fetch", json={"url": hits[0]["url"]}).json()
if page["error"] is None:
print(page["title"], page["tier"], page["billing_category"])
print(page["text"][:500])Built for production
Public status page and status API
People read /status; your monitors poll /v1/status. Incidents and maintenance are posted there first.
Usage and spend limits per key
Give every key its own monthly budget and request quota, and see usage per key, project and day.
Webhooks and callbacks
Signed notifications when a batch finishes, a limit is near or a watched company changes.
Idempotent batches
Send the same batch twice with one idempotency key and it runs once, and is charged once.
Hosted in the EU
API, storage and logs run on servers in Germany. Request logs are deleted after 90 days.
Usage-based pricing
Tell us about your workload. You pay for what you use, every call reports how it was billed, and Cormorant escalates to heavier routes only when a page needs them. We reply with a price for your volume and an API key to try it.