Skip to the content
Menu: Python

Python SDK

The zentiq package calls every operation of the API from your server. It runs on Python 3.9 or later with the standard library only, and ships typed dictionaries for every object in the OpenAPI document.

Install
pip install "zentiq>=1,<2"

Coming to PyPI

zentiq 1.0.0 is being released with the 2026-10-01 contract. The command above installs 1.0.0 or a later 1.x only, so it works as soon as 1.0.0 is out.

The client#

Python
import os
from zentiq import Zentiq

zentiq = Zentiq(api_key=os.environ["ZENTIQ_API_KEY"])  # a server secret
me = zentiq.get_me()
print(me["organization"]["displayName"], me["apiKey"]["effectiveScopes"])

Zentiq(api_key=None, base_url="https://app.zentiqai.com/v1", api_version="2026-10-01", max_retries=2, timeout=90.0, transport=None): without api_key it reads ZENTIQ_API_KEY; transport lets you bring your own HTTP stack.

Operations#

Every operation is a method named after its operation id in snake_case. Path parameters come first, then the body as a dict (or, for a GET, the query as keyword arguments):

Python
persona = zentiq.create_persona({"name": "Ava", "systemPrompt": "You are Ava, Acme's product specialist."})
zentiq.update_persona(persona["id"], {"greeting": None})  # None sends null: it clears the greeting
page = zentiq.list_personas(limit=20)                      # {"data": [...], "nextCursor": ...}
for p in zentiq.paginate("list_personas", limit=100):
    print(p["id"], p["name"])

Answers are plain dictionaries with the API's own field names (systemPrompt, nextCursor), typed with TypedDicts (from zentiq.types import Persona). Every method also takes idempotency_key, api_version and timeout. zentiq.request("createPersona", body=…) calls any operation by its id.

Errors#

The same kinds as the Node SDK, as exceptions: ZentiqError and InvalidRequestError, ConsentError, AuthenticationError, InsufficientMinutesError, PermissionDeniedError, UpgradeRequiredError, FeatureNotInPlanError, NotFoundError, ConflictError, VersionConflictError, DuoNotLiveError, IdempotencyError, GoLiveRefusedError, RateLimitError, ServerError and APIConnectionError (named so they never shadow Python's own PermissionError and ConnectionError). Each has status, code, message, param, details, request_id and, where it applies, retry_after.

Python
from zentiq import UpgradeRequiredError, ZentiqError

try:
    zentiq.create_voice({"audioBase64": "data:audio/wav;base64,...", "consent": {"attested": True, "subject": "myself"}})
except UpgradeRequiredError as e:
    print(e.feature, e.plan, e.message)
except ZentiqError as e:
    print(e.status, e.code, e.request_id)

Waiting and webhooks#

Python
from zentiq import verify_webhook

doc = zentiq.create_document(pack["id"], {"url": "https://www.example.com/help"})
zentiq.wait_until_ready("get_document", doc["id"])  # ready, or raises on failed

# In your webhook handler: the raw body, exactly as it arrived
event = verify_webhook(raw_body, request.headers, os.environ["ZENTIQ_WEBHOOK_SECRET"])
if event["type"] == "lead.captured":
    print(event["data"]["inboxItemId"])