Python Sdk
Python SDK for Kasookoo's server-side API. Server-only — it holds your
organization's secret key, which must never reach a browser.
This SDK only creates call intents — it doesn't place calls itself. That
half happens on the frontend, in either of two places:
kasookoo-sdk's
initSipCall({ phoneNumber, intentId, clientSecret })(readme.io: Calls) — for a custom call UI you build yourself.kasookoo-click-to-call-widget
(readme.io docs)'s
<kasookoo-dialer>— a drop-in call button/dial pad. It doesn't callinitSipCall()
directly itself; instead, it fetches an intent on its own from a route you
give it (intentEndpoint, passed to itsinit()), then dials with what
that route returns.
Either way, the shape is the same: your frontend asks your backend for a call
intent, your backend creates it with this SDK, and your route must respond
with the two fields the frontend needs to actually place the call:
intent_id and client_secret. Nothing else you put in that response
matters to either integration.
Install
pip install kasookoo-server-sdkUsage
import os
from kasookoo_server_sdk import Kasookoo
kasookoo = Kasookoo(secret_key=os.environ["KASOOKOO_SECRET_KEY"])
intent = kasookoo.call_intents.create(
subject="Website visitor", # must match the `subject` your frontend passes to init() — see below
phone_number="+18005551234",
max_duration_seconds=300, # optional
)call_intents.create() sends your secret key to Kasookoo and returns:
@dataclass
class CallIntent:
intent_id: str # unique id for this call intent
client_secret: str # short-lived secret for the frontend — hand this off, never the org secret key
subject: str
phone_number: str
expires_in: int # seconds until client_secret expires if unused
max_duration_seconds: int
status: str # "requires_dial", or any other status string the API returnsRespond from your route with at least intent_id and client_secret —
that's the whole contract, whichever frontend integration is consuming it
(see above): kasookoo-sdk's initSipCall(), or
kasookoo-click-to-call-widget's intentEndpoint. Your org's secret key
never needs to leave the server.
Keep subject in sync with the frontend's init()
subject in sync with the frontend's init()The subject you pass here must be the exact same value the frontend
passed to init() — kasookoo-sdk's KasookooClient.init({ subject }) or
kasookoo-click-to-call-widget's KasookooClickToCall.init({ subject }).
Kasookoo checks the two against each other and rejects the call intent if
they don't match (surfaced as a KasookooApiError — see
Errors below), so always pass subject here
explicitly, kept identical to whatever your frontend's init() call used —
don't assume it's implied or optional just because the frontend already sent
one.
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
secret_key | str | required | Your organization's secret key. |
base_url | str | https://sdk-test.kasookoo.ai | API base URL. |
timeout_seconds | float | 10.0 | Request timeout in seconds. |
All three are keyword-only arguments to Kasookoo(...).
Example: a mini Flask app
import os
from flask import Flask, jsonify, request
from kasookoo_server_sdk import Kasookoo
kasookoo = Kasookoo(secret_key=os.environ["KASOOKOO_SECRET_KEY"])
app = Flask(__name__)
@app.post("/my-api/call-intent")
def call_intent():
data = request.get_json()
try:
intent = kasookoo.call_intents.create(
subject=data.get("subject"),
phone_number=data.get("phoneNumber"),
)
return jsonify(intent_id=intent.intent_id, client_secret=intent.client_secret)
except Exception:
return "", 502Point your frontend's intentEndpoint at /my-api/call-intent. Protect this
route with authentication or rate limiting before going live.
Errors
The SDK raises two error types, both exported from the package:
from kasookoo_server_sdk import KasookooApiError, KasookooConfigErrorKasookooApiError
KasookooApiErrorKasookoo rejected the request, or couldn't be reached.
| Attribute | Description |
|---|---|
str(err) | Human-readable description (the API's own message when it sent one). |
status | HTTP status code. 0 if no response was received (network error or timeout). |
code | Error code from the API, if any. The SDK sets "timeout" and "network_error" itself when status is 0. |
details | The full parsed error response body, if any. |
KasookooConfigError
KasookooConfigErrorInvalid SDK usage, raised before any network call: a missing secret_key,
or an empty subject / phone_number passed to call_intents.create().
Handling them
try:
kasookoo.call_intents.create(subject=subject, phone_number=phone_number)
except KasookooApiError as err:
print(err.status, err.code, err)
except KasookooConfigError as err:
print(err)A subject that doesn't match the one your frontend passed to init() is
rejected by Kasookoo and surfaces as a KasookooApiError.
Requirements
- Python 3.9+. No runtime dependencies.
Updated 16 days ago
