These examples walk through the complete agent lifecycle: discovering service capabilities, registering to obtain an API key, running a credibility-scored search, and checking your usage and billing tier. Both scripts are self-contained — Python requires only the requests package, and Node.js uses the built-in fetch available since Node 18. You can run them as-is against the live API to see real output immediately.
Full source code
"""
Lithtrix — full lifecycle example (Python).
Demonstrates: discover → register → search → check usage → upgrade prompt.
Requirements: Python 3.9+, requests (`pip install requests`)
Usage:
python python_agent.py
To skip registration (if you already have a key):
LITHTRIX_API_KEY=ltx_your_key python python_agent.py
"""
import os
import requests
BASE_URL = "https://lithtrix.ai"
def discover() -> dict:
"""Read service capabilities."""
resp = requests.get(f"{BASE_URL}/v1/capabilities", timeout=10)
resp.raise_for_status()
return resp.json()
def register(agent_name: str, owner_identifier: str) -> str:
"""Register as a new agent. Returns the one-time API key."""
resp = requests.post(
f"{BASE_URL}/v1/register",
json={"agent_name": agent_name, "owner_identifier": owner_identifier},
timeout=10,
)
resp.raise_for_status()
data = resp.json()
print(f"[register] agent_id={data['agent_id']}")
print(f"[register] api_key={data['api_key']} ← store this securely!")
return data["api_key"]
def search(api_key: str, query: str, num_results: int = 5) -> list[dict]:
"""Search the web. Returns credibility-scored results."""
resp = requests.get(
f"{BASE_URL}/v1/search",
params={"q": query, "num_results": num_results},
headers={"Authorization": f"Bearer {api_key}"},
timeout=15,
)
resp.raise_for_status()
data = resp.json()
usage = data.get("usage", {})
print(
f"[search] calls_total={usage.get('calls_total')} "
f"calls_remaining={usage.get('calls_remaining')} "
f"cached={data.get('cached')}"
)
return data["results"]
def check_usage(api_key: str) -> dict:
"""Check current tier, usage, and limit."""
resp = requests.get(
f"{BASE_URL}/v1/billing",
headers={"Authorization": f"Bearer {api_key}"},
timeout=10,
)
resp.raise_for_status()
return resp.json()
def main() -> None:
# Step 1: Discover
print("\n--- Step 1: Discover ---")
caps = discover()
print(f"Service: {caps['service']} version={caps['version']}")
print(f"Free tier: {caps['rate_limits']['free_tier']}")
# Step 2: Register (or use existing key from env)
api_key = os.getenv("LITHTRIX_API_KEY")
if not api_key:
print("\n--- Step 2: Register ---")
api_key = register(
agent_name="python-example-agent",
owner_identifier="example@lithtrix.ai",
)
else:
print(f"\n--- Step 2: Using existing key from env ---")
# Step 3: Search
print("\n--- Step 3: Search ---")
query = "Singapore climate policy 2025"
results = search(api_key, query, num_results=3)
for i, r in enumerate(results, 1):
print(
f" {i}. [{r['credibility_score']:.1f}] {r['title']}\n"
f" {r['url']}"
)
# Step 4: Check usage
print("\n--- Step 4: Check Usage ---")
billing = check_usage(api_key)
print(f"Tier: {billing['tier']}")
print(f"calls_total={billing['calls_total']} call_limit={billing['call_limit']}")
if billing.get("over_limit"):
print("NOTE: over_limit=true — upgrade to Pro to continue searching.")
print(f"Upgrade path: GET {BASE_URL}/v1/billing/config → POST {BASE_URL}/v1/billing/setup")
print("\nDone.")
if __name__ == "__main__":
main()
/**
* Lithtrix — full lifecycle example (Node.js).
*
* Demonstrates: discover → register → search → check usage.
*
* Requirements: Node.js 18+ (uses built-in fetch)
*
* Usage:
* node node_agent.js
*
* To skip registration (if you already have a key):
* LITHTRIX_API_KEY=ltx_your_key node node_agent.js
*/
const BASE_URL = "https://lithtrix.ai";
async function discover() {
const res = await fetch(`${BASE_URL}/v1/capabilities`);
if (!res.ok) throw new Error(`discover failed: ${res.status}`);
return res.json();
}
async function register(agentName, ownerIdentifier) {
const res = await fetch(`${BASE_URL}/v1/register`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ agent_name: agentName, owner_identifier: ownerIdentifier }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(`register failed: ${res.status} ${err.message ?? ""}`);
}
const data = await res.json();
console.log(`[register] agent_id=${data.agent_id}`);
console.log(`[register] api_key=${data.api_key} ← store this securely!`);
return data.api_key;
}
async function search(apiKey, query, numResults = 5) {
const url = new URL(`${BASE_URL}/v1/search`);
url.searchParams.set("q", query);
url.searchParams.set("num_results", String(numResults));
const res = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(`search failed: ${res.status} ${err.message ?? ""}`);
}
const data = await res.json();
const { calls_total, calls_remaining } = data.usage ?? {};
console.log(`[search] calls_total=${calls_total} calls_remaining=${calls_remaining} cached=${data.cached}`);
return data.results;
}
async function checkUsage(apiKey) {
const res = await fetch(`${BASE_URL}/v1/billing`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (!res.ok) throw new Error(`billing failed: ${res.status}`);
return res.json();
}
async function main() {
// Step 1: Discover
console.log("\n--- Step 1: Discover ---");
const caps = await discover();
console.log(`Service: ${caps.service} version=${caps.version}`);
console.log(`Free tier: ${caps.rate_limits.free_tier}`);
// Step 2: Register (or use existing key from env)
let apiKey = process.env.LITHTRIX_API_KEY;
if (!apiKey) {
console.log("\n--- Step 2: Register ---");
apiKey = await register("node-example-agent", "example@lithtrix.ai");
} else {
console.log("\n--- Step 2: Using existing key from env ---");
}
// Step 3: Search
console.log("\n--- Step 3: Search ---");
const results = await search(apiKey, "Singapore climate policy 2025", 3);
results.forEach((r, i) => {
console.log(` ${i + 1}. [${r.credibility_score.toFixed(1)}] ${r.title}`);
console.log(` ${r.url}`);
});
// Step 4: Check usage
console.log("\n--- Step 4: Check Usage ---");
const billing = await checkUsage(apiKey);
console.log(`Tier: ${billing.tier}`);
console.log(`calls_total=${billing.calls_total} call_limit=${billing.call_limit}`);
if (billing.over_limit) {
console.log("NOTE: over_limit=true — upgrade to Pro to continue searching.");
console.log(`Upgrade path: GET ${BASE_URL}/v1/billing/config → POST ${BASE_URL}/v1/billing/setup`);
}
console.log("\nDone.");
}
main().catch((err) => {
console.error(err.message);
process.exit(1);
});
Running the examples
Python
pip install requests
python python_agent.py
If you already have a Lithtrix API key, pass it via the environment variable to skip the registration step:
LITHTRIX_API_KEY=ltx_your_key python python_agent.py
Node.js
Node.js 18+ includes fetch natively — no additional packages needed.
To skip registration with an existing key:
LITHTRIX_API_KEY=ltx_your_key node node_agent.js
If you already have a Lithtrix API key, set LITHTRIX_API_KEY in your environment before running either script. The registration step will be skipped and the existing key will be used for the search and billing calls.
What to expect
Both scripts print progress for each of the four lifecycle steps:
- Discover — logs the service name, API version, and free-tier call limit from
/v1/capabilities
- Register — prints the new
agent_id and api_key (shown once — save it); skipped if LITHTRIX_API_KEY is already set
- Search — runs a sample query and prints the top 3 results with their credibility scores and URLs, plus live usage counters (
calls_total, calls_remaining)
- Check usage — prints your current tier, total calls made, and your call limit; if
over_limit is true, it also prints the upgrade path