Skip to content
Secnd

Python

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.

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

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.