> ## Documentation Index
> Fetch the complete documentation index at: https://secndai.manicule.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For every page in one file, fetch https://secndai.manicule.dev/llms-full.txt (large).
> To search and read these docs as tools, connect the MCP server at https://secndai.manicule.dev/api/mcp.
> Every agent surface: https://secndai.manicule.dev/.well-known/llms-manifest.json

# Python (/sdk/python)

<!-- agent-signals: reading_time_min: 1 · est_tokens: 530 · updated: 2026-11-12 -->
Related: [TypeScript](/sdk/typescript.md), [Document classification](/cookbooks/document-classification.md)

> Synchronous and asynchronous clients with typed errors.

Requires Python 3.12 or newer. Install the local `packages/sdk-python` project as described in the SDK overview. Store the key on your server.

```python
import os
from secnd import Secnd

client = Secnd(api_key=os.environ["SECND_API_KEY"])
result = client.decide({
    "model": "ren-zero-2026-11-12",
    "type": "noul",
    "situation": "The customer asks to cancel before renewal.",
    "question": "Is cancellation explicitly requested?",
    "threshold": 0.9,
})
print(result["choice"], result["probability"], result["action"])
```

`Secnd(api_key, base_url="https://api.secndai.com", max_retries=2, timeout=30.0)` accepts a request dictionary. Timeout is in seconds per attempt. Set `max_retries` from 0 through 5. HTTPS is required except on localhost.

## Async

```python
import asyncio
import os
from secnd import AsyncSecnd

async def main():
    client = AsyncSecnd(api_key=os.environ["SECND_API_KEY"])
    result = await client.decide({
        "model": "ren-zero-2026-11-12",
        "type": "noul",
        "situation": "Please cancel my plan.",
        "question": "Is cancellation explicitly requested?",
    })
    print(result["action"])

asyncio.run(main())
```

The async client uses a thread-backed transport. It keeps the event loop free while a request waits; cancelling the coroutine does not necessarily stop the underlying HTTP request. Bound concurrency and rely on request timeouts.

## Errors and retries

Catch `AuthenticationError`, `ValidationError`, `RateLimitError`, or `ServerError`; each extends `SecndError`. Error instances expose `status`, `code`, and `retry_after` plus the message through `str(error)`. Network or invalid-response failures can raise the base `SecndError`.

Retries cover `429` and server errors only, with exponential backoff (up to 30 seconds) or the full `Retry-After` up to 60 seconds; a longer `Retry-After` raises `RateLimitError` with `retry_after` instead of retrying. Transport failures are surfaced without automatic retry. A 30-second per-attempt timeout is not a 30-second total deadline.
