{"service":"Lithtrix Search API","version":"2.1.0","description":"Agent-native search API with per-agent persistent JSON memory (CRUD, list, stats, context reload, optional semantic search), binary blob storage (upload, download, list, metadata, soft-delete), document parsing (PDF, DOCX, CSV, XLSX) with sync or async + callback, semantic search over parsed chunks, plus verified, credibility-scored web search results.","base_url":"https://api.lithtrix.ai","capabilities":["web-search","agent-registration","persistent-memory","semantic-memory","semantic-memory-search","document-blobs","document-parsing","document-semantic-search","parse-async-callbacks","structured-feedback","usage-tracking","key-rotation","mcp"],"authentication":{"type":"bearer","header":"Authorization","format":"Bearer ltx_...","obtain_via":"POST /v1/register"},"endpoints":[{"method":"POST","path":"/v1/register","auth_required":false,"description":"Register a new agent and receive a one-time API key.","request_body":{"agent_name":"string (required, 1-100 chars)","owner_identifier":"string (required, 1-255 chars, e.g. email or URL)","referral_agent":"string (optional) — referring agent UUID; same value as that agent's referral_code from GET /v1/me. Omit if unknown."},"response":{"api_key":"ltx_... (show once, store securely)","agent_id":"uuid","message":"string"}},{"method":"GET","path":"/v1/search","auth_required":true,"description":"Search the web via Brave Search. Returns credibility-scored results.","query_params":{"q":"string (required, 1-500 chars)","num_results":"integer (optional, 1-20, default 10)"},"response":{"results":"array of {title, url, snippet, source, credibility_score (0-1), published_date}","usage":"{calls_total, calls_remaining}","cached":"boolean","response_time_ms":"integer","_lithtrix":"{search_id uuid, register_url, …} — use search_id for POST /v1/feedback"}},{"method":"POST","path":"/v1/feedback","auth_required":true,"description":"Structured feedback (helpful / unhelpful / wrong) on a prior result. ref_type: search_id, memory_key, blob_id, or parse_id; ref_id is not validated against your data. Monthly caps: free 100, starter 1,000, pro 10,000 (UTC month).","request_body":{"ref_type":"search_id | memory_key | blob_id | parse_id","ref_id":"string (opaque id from the prior operation)","signal":"helpful | unhelpful | wrong","note":"optional, max 500 characters — avoid secrets/PII"}},{"method":"GET","path":"/v1/feedback/stats","auth_required":true,"description":"Rolling aggregates for this agent only (UTC): last_7d, last_30d, by_ref_type, limit, remaining for the current calendar month."},{"method":"GET","path":"/v1/me","auth_required":true,"description":"Get the authenticated agent's profile (tier, limits, referral_code, referral_agent).","response":{"referral_code":"uuid — always present; equals this agent's id; share for referral_agent on new registrations","referral_agent":"uuid or null — referrer's id if this agent registered with referral_agent"}},{"method":"PUT","path":"/v1/memory/{key}","auth_required":true,"description":"Store or update a JSON value for this agent (key in path; body has value, optional ttl, importance, source, confidence). Metered SET ops + storage."},{"method":"GET","path":"/v1/memory/{key}","auth_required":true,"description":"Retrieve one stored JSON value by key."},{"method":"DELETE","path":"/v1/memory/{key}","auth_required":true,"description":"Delete one stored key for this agent."},{"method":"GET","path":"/v1/memory","auth_required":true,"description":"List memory keys (metadata only), paginated; optional prefix and importance filters."},{"method":"GET","path":"/v1/memory/stats","auth_required":true,"description":"Memory usage snapshot: ops this month, storage bytes, tier limits, over_limit."},{"method":"GET","path":"/v1/memory/context","auth_required":true,"description":"Top N memories by importance then recency — for session-start context reload."},{"method":"GET","path":"/v1/memory/search","auth_required":true,"description":"Semantic similarity search over stored memories (natural-language query; requires vector + embedding configuration).","query_params":{"q":"string (required, 1-500 chars)","limit":"integer (optional, 1-20, default 5)","importance":"string (optional, importance floor)","threshold":"number (optional, 0-1 similarity minimum, default 0.7)"},"response":{"results":"array of hits with key, value, similarity, provenance fields","total_returned":"integer"}},{"method":"PUT","path":"/v1/blobs","auth_required":true,"description":"Upload a binary blob (multipart `file` or raw body with Content-Type). Returns content-addressed blob_id; duplicate bytes are idempotent (200 vs 201). New uploads enforce aggregate tier blob storage (413 BLOB_STORAGE_LIMIT)."},{"method":"GET","path":"/v1/blobs","auth_required":true,"description":"List blob metadata for this agent (paginated).","query_params":{"page":"integer (default 1)","per_page":"integer (1-100, default 50)"}},{"method":"GET","path":"/v1/blobs/{blob_id}","auth_required":true,"description":"Download raw blob bytes (supports HTTP Range)."},{"method":"GET","path":"/v1/blobs/{blob_id}/signed-url","auth_required":true,"description":"Mint a short-lived HTTPS URL for direct GET from storage without Bearer on download; optional query expires_in (seconds, bounded). Treat URLs as read capability tokens.","query_params":{"expires_in":"integer (optional) — TTL seconds; default server config; min 60; max from server"}},{"method":"GET","path":"/v1/blobs/{blob_id}/meta","auth_required":true,"description":"JSON metadata for one blob (no body bytes)."},{"method":"DELETE","path":"/v1/blobs/{blob_id}","auth_required":true,"description":"Soft-delete a blob for this agent (204)."},{"method":"POST","path":"/v1/blobs/{blob_id}/parse","auth_required":true,"description":"Parse stored blob bytes (PDF, DOCX, CSV, XLSX). Default sync under PARSE_SYNC_MAX_BYTES; query async=true enqueues QStash with optional JSON callback_url (HTTPS, public IP/DNS). Counts toward parse_ops; per-minute parse rate limits by tier.","query_params":{"async":"boolean (optional) — async parse + poll when true"}},{"method":"GET","path":"/v1/blobs/{blob_id}/parse/{parse_id}","auth_required":true,"description":"Poll parse job status and structured result when complete."},{"method":"GET","path":"/v1/blobs/search","auth_required":true,"description":"Semantic search over parsed chunk embeddings (requires vector + OpenAI embeddings). One metered search call shared with GET /v1/search (429 before embedding when over quota).","query_params":{"q":"string (required, 1-500 chars)","limit":"integer (optional, 1-20)","threshold":"number (optional, 0-1)"}},{"method":"GET","path":"/v1/usage","auth_required":true,"description":"Get monthly usage stats and 7-day daily breakdown."},{"method":"POST","path":"/v1/keys/rotate","auth_required":true,"description":"Invalidate current API key and receive a new one."},{"method":"GET","path":"/health","auth_required":false,"description":"Health check endpoint."}],"rate_limits":{"free_tier":"Web-discovery calls: lifetime cap = base trial quota (default 300) + 100 × verified referrals (other agents who registered with referral_agent = your UUID). usage.search_calls_limit on GET /v1/search reflects the effective cap.","starter_tier":"1500 web-discovery calls per UTC calendar month; overage ~$0.015/call (informational)","pro_tier":"5000 web-discovery calls per UTC calendar month; overage ~$0.012/call (informational)","per_minute":{"free":"60 requests/minute","starter":"600 requests/minute","pro":"600 requests/minute"},"note":"Search responses include usage (lifetime for free, monthly for starter/pro). GET /v1/billing adds search_calls_* fields for paid tiers; memory_storage_bytes (KV only), blob_embed_storage_bytes, combined_memory_storage_bytes vs memory_storage_limit_bytes; blob_storage_bytes and blob_storage_limit_bytes for aggregate blobs. GET /v1/blobs/search shares the web+blob search quota with GET /v1/search (usage_logs endpoint includes /v1/blobs/search). Parse routes enforce parse_ops and per-minute parse limits (5 / 30 / 60 per minute free / starter / pro). Memory routes return usage (ops, storage) in JSON bodies. Blob routes share a separate per-agent per-minute counter (60 free / 600 starter+pro) in addition to the global middleware cap."},"referral_rewards":{"free_tier":"Lifetime web-discovery limit = free_tier_lifetime_limit (default 300) + 100 × (count of other agents with referral_agent equal to your agent UUID). Matching is UUID-only (referral_code on GET /v1/me). Self-referral excluded. Starter and Pro: monthly search caps only; no referral bonus.","enabled":true,"eligible_tiers":["free"],"bonus_per_referral":100,"bonus_unit":"lifetime_web_discovery_calls","how_to_refer":"Pass your referral_code as referral_agent in POST /v1/register. Your referral_code is your agent UUID — call GET /v1/me (authenticated) to retrieve it, or call GET /v1/capabilities with your Bearer token and it is included here.","self_referral":"excluded","cap":"none"},"document_storage":{"summary":"Per-agent binary blobs; content-addressed blob_id. Authenticated with the same Bearer token.","blob_id_format":"b_ followed by 16 lowercase hex characters (derived from SHA-256 of bytes).","operations":{"put":"PUT /v1/blobs — multipart field `file` or raw body with Content-Type; optional filename query","get_bytes":"GET /v1/blobs/{blob_id} — raw bytes; supports Range","list":"GET /v1/blobs — paginated metadata (page, per_page)","meta":"GET /v1/blobs/{blob_id}/meta — JSON metadata only","signed_url":"GET /v1/blobs/{blob_id}/signed-url — time-limited HTTPS read URL (Supabase Storage); optional expires_in query; anyone with the URL can GET bytes until expiry","delete":"DELETE /v1/blobs/{blob_id} — soft-delete (404 on repeat or wrong agent)","parse":"POST /v1/blobs/{blob_id}/parse — extract text/tables; optional ?async=true + JSON callback_url","parse_poll":"GET /v1/blobs/{blob_id}/parse/{parse_id} — poll async or read sync result","semantic_doc_search":"GET /v1/blobs/search?q=... — semantic chunk search; one search call vs shared web quota"},"error_codes":{"BLOB_TOO_LARGE":"Single upload exceeds server max (BLOB_MAX_UPLOAD_BYTES)","BLOB_STORAGE_LIMIT":"New upload would exceed aggregate tier blob storage cap (strict > limit); see GET /v1/billing blob_storage_bytes / blob_storage_limit_bytes","BLOB_NOT_FOUND":"Unknown id, wrong agent, or soft-deleted","BLOB_SIGNED_URL_TTL_INVALID":"expires_in out of allowed range (min 60s, max from server)"},"mcp_tool_definitions":["https://api.lithtrix.ai/mcp/lithtrix-blob-upload.json","https://api.lithtrix.ai/mcp/lithtrix-blob-download.json","https://api.lithtrix.ai/mcp/lithtrix-blob-list.json","https://api.lithtrix.ai/mcp/lithtrix-blob-meta.json","https://api.lithtrix.ai/mcp/lithtrix-blob-delete.json","https://api.lithtrix.ai/mcp/lithtrix-blob-signed-url.json","https://api.lithtrix.ai/mcp/lithtrix-blob-parse.json","https://api.lithtrix.ai/mcp/lithtrix-blob-parse-status.json","https://api.lithtrix.ai/mcp/lithtrix-blob-search.json","https://api.lithtrix.ai/mcp/lithtrix-feedback.json"]},"billing_tiers":{"free":{"search_quota":"Web-discovery: lifetime cap = 300 (default base) + 100 per qualifying referral; see top-level referral_rewards (optional Bearer adds your_referral_code)","memory_ops_per_month":1000,"memory_storage_mb":5,"blob_storage_mb":50,"search_overage_per_call_usd":null},"starter":{"search_quota":"1500 web-discovery calls per UTC month","memory_ops_per_month":5000,"memory_storage_mb":25,"blob_storage_mb":2048,"approx_price_usd_per_month":29,"search_overage_per_call_usd":0.015},"pro":{"search_quota":"5000 web-discovery calls per UTC month","memory_ops_per_month":null,"memory_storage_mb":100,"blob_storage_mb":20480,"approx_price_usd_per_month":99,"search_overage_per_call_usd":0.012}},"credibility_scoring":{"description":"Every search result includes a credibility_score (0.0-1.0)","scale":{"1.0":".gov domains","0.9":".edu domains","0.8":"major news sources (BBC, Reuters, AP News, etc.)","0.7":".org domains","0.5":"all other sources"}},"feedback":{"summary":"Append-only structured signal on prior Lithtrix results — stored for future routing and credibility improvements (no scoring loop in Arc 11).","endpoints":{"submit":"POST /v1/feedback","stats":"GET /v1/feedback/stats"},"ref_types":["search_id","memory_key","blob_id","parse_id"],"signals":["helpful","unhelpful","wrong"],"monthly_limits":{"free":100,"starter":1000,"pro":10000},"mcp_tool_definition":"https://api.lithtrix.ai/mcp/lithtrix-feedback.json"}}