Errors
Every non-2xx response from Search or Fetch maps to one of a small set of typed exceptions, whichever client makes the call.
Status codes and exceptions
Section titled “Status codes and exceptions”The Python SDK’s raise_for_status() does the mapping; every exception derives
from TelemError and carries .message, .status_code, and .body:
| HTTP status | Exception | Meaning |
|---|---|---|
400 |
BadRequestError |
Malformed request — e.g. an unknown provider name |
401 / 403 |
AuthError |
Missing or invalid credentials |
402 |
APIStatusError |
Monthly spend limit would be exceeded — a spend cap the account set for itself; raise or remove it |
404 |
NotFoundError |
The resource (e.g. a session id) doesn’t exist |
429 |
APIStatusError |
Rate limited — per-key requests/minute (Retry-After: 60) or the account’s daily quota (Retry-After: 3600); back off for the header’s seconds |
| any other non-2xx | APIStatusError |
Everything else, including 5xx |
The 402/429 ceilings are opt-in guardrails, not built-in limits: each
exists only if set on your key, project, or account — unset means no ceiling,
and having credit means you keep going. Need more? Tell us.
The error message includes the response body’s detail field when present — a
plain string, or, for FastAPI validation errors, each item’s msg joined with
", ".
Two failures never reach a status code at all, because no HTTP response was received to map:
| Exception | Raised when |
|---|---|
TelemConnectionError |
The request timed out or the transport failed before any response arrived |
TelemServerVersionError |
The router answered without the normalized response the SDK requires (normalized_schema_version < 2) |
from telem import Telem, BadRequestError
try: Telem().search("hi", providers_include=["does-not-exist"])except BadRequestError as exc: print(exc.status_code, exc.message)This table is the ground truth for every Telem surface, not just the SDK: the MCP server, the agent-tool plugins, and any client calling the HTTP API directly all see the same status codes for the same reasons.
How the agent-tool plugins handle errors
Section titled “How the agent-tool plugins handle errors”OpenClaw, OpenCode, and Pi each wire up telem_search and telem_fetch on top of
the same two endpoints, and all three handle failure the same way, in two cases.
A partial failure renders inline, next to the results that did come back. When
one provider in a search (or one URL in a telem_fetch batch) fails while others
succeed, the interaction still succeeds and the failure shows up as a line inside
the formatted tool result:
- Search:
[provider] failed: <message> - Fetch:
### <url>section withError: <type>: <message>instead of page content
A request-level failure throws. When the POST itself returns non-2xx, the
tool’s execute() throws a JavaScript Error rather than returning formatted
text:
Telem search failed: HTTP 401 <first 200 characters of the response body>Telem fetch failed: HTTP 401 <first 200 characters of the response body>The plugin does not catch that throw and turn it into result text — that is the
host’s job. OpenClaw’s persisted transcript carries an isError flag on tool
results, which the plugin reads back when it rebuilds conversation history: the
standard way a host tells the model a tool call failed without stopping the
conversation.