Skip to main content

krenzo

Search and extract API for LLM agents. One endpoint for live web search, one for turning any URL into clean markdown — returned as token-efficient context rather than raw HTML.

No runtime dependencies.

pip install krenzo

Quickstart

Get a key at krenzo.in/dashboard/keys, then:

export KRENZO_API_KEY=krz_live_...
from krenzo import Krenzo

client = Krenzo()

for hit in client.search("nvidia q3 earnings", max_results=5):
    print(hit.source, "—", hit.title)
results = client.search(
    "western digital analyst price target",
    depth="deep",              # also returns page contents for the top results
    max_results=10,
    include_domains=["stockanalysis.com"],
    freshness="week",
)

for r in results:
    print(r.title, r.url)
    if r.content:              # populated when depth="deep"
        print(r.content[:500])

depth="deep" fetches and extracts the top results in the same call, which saves a round trip per result when you were going to read them anyway.

Extract

pages = client.extract([
    "https://example.com/a",
    "https://example.com/b",
])

for p in pages:
    if p.ok:
        print(p.title, p.word_count)
        print(p.content)
    else:
        print("failed:", p.url, p.error_type, p.error_message)

Each URL carries its own ok/error, so one dead link does not discard the rest of the batch. Pass format="text" for plain text instead of markdown, and render=True for pages that build their content in the browser with JavaScript.

When an empty page is not an empty page

A page that refused you and a page with nothing on it look identical downstream — and only one of them is a bug in your parser. extract_one makes the difference explicit, so you can skip the source rather than treat a refusal as an empty document. It reports the refusal; it does not work around it.

from krenzo import Krenzo, BlockedError

client = Krenzo()

try:
    text = client.extract_one("https://www.tipranks.com/stocks/wdc/forecast")
except BlockedError as e:
    print("needs a browser or was refused:", e)

Batch extract() reports the same thing without raising: check p.needs_rendering and p.error_type.

Answer

A grounded answer in one call, with every quote checked against the page it came from.

res = client.answer("What did the RBI decide on the repo rate?", max_sources=4)

print(res.answer)
for c in res.citations:
    print(f"  — {c.quote}\n    {c.url}")

The model proposes quotes; the service verifies each one against the fetched source and drops anything it cannot find. A fabricated citation therefore cannot reach you. Two fields are worth reading every time:

  • res.unverified — quotes that were dropped. Empty means every claim was grounded; non-empty means the answer drifted from its sources.
  • res.skipped — pages found but not readable, with a reason. An answer built on one of four sources is weaker than one built on four.

If the sources do not contain the answer, it says so and returns no citations rather than guessing. Pass render=True to retry unreadable sources through a browser. It costs the same flat rate as any other call — it is off by default because it is slower, not because it is dearer.

Errors

Exception When
AuthenticationError missing, malformed, or revoked key
InsufficientCredits balance cannot cover the call — top up
RateLimited too many requests; carries retry_after
UpstreamError search index or origin failed; usually transient
BlockedError page refused, or needs a browser (extract_one only)
KrenzoError base class for all of the above

Rate limits and upstream failures are retried automatically with backoff. Authentication and credit errors are not — they fail identically on a retry.

Usage and billing

Every call records what it cost:

client.search("anything")
print(client.last_usage.balance_usd, client.last_usage.free_calls_remaining)

$0.04 per call, flat across search, extract and answer — including rendered fetches. extract is billed per URL, so a 20-URL batch is 20 calls ($0.80). Failed requests are not billed, and a call that fails upstream is refunded automatically.

Billing and settlement are in INR (₹3.52 per call); the USD figure is a conversion at a fixed reference rate. Treat the price above as indicative and last_usage.charged_paise as authoritative — it is what you were actually charged, and it stays correct if the published rate changes. Current pricing is always at krenzo.in/pricing.

Configuration

KRENZO_API_KEY your API key (or pass api_key=)
KRENZO_API_URL override the base URL, for testing against a local server
client = Krenzo(api_key="krz_live_...", timeout=30, max_retries=3)

Never hard-code a key in published source. A key committed to a repository is a key anyone can spend, and keys cannot be un-published. Read it from the environment or a secret manager.

License

MIT

Metadata

Release files for krenzo 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for krenzo 0.1.2
File Size Uploaded
krenzo-0.1.2.tar.gz 10.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for krenzo 0.1.2
File Interpreter ABI Platform
krenzo-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 19.6 kB

Release files / krenzo-0.1.2.tar.gz

Download URL krenzo-0.1.2.tar.gz
Size 10.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6280424c661f566a78095409015126548fecea0b7cff68423352d8ee187e75a3
BLAKE2b-256 checksum
How to use checksums
4e24f528a21364afd22d6e6044bb86e0761656753709bc883cbd9d7d3c35c3e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release files / krenzo-0.1.2-py3-none-any.whl

Download URL krenzo-0.1.2-py3-none-any.whl
Size 9.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8456dd88674ac60793cee5c973b8816482558215411cfac5c68a5c13349734d4
BLAKE2b-256 checksum
How to use checksums
d8d2330e8a1b02b42f09156d6db883c0b4d483c7376995d66421cba7d51e1d10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.0

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page