talqing is the Python client for the /v1 API, generated from the same
OpenAPI document as the TypeScript SDK. It carries every operation under the
same names, sync and async.
httpx is the only runtime dependency you will notice.
The package ships a py.typed marker, so a type checker in your project sees
every TypedDict it declares — no stub package and no # type: ignore.
Creating a client
A personal access token has no prefix. It is an opaque signed string: do not
parse it and do not assume a shape.
Talqing.from_env(**overrides) reads TALQING_API_KEY and TALQING_BASE_URL,
and anything you pass wins over the environment:
AsyncTalqing has exactly the same shape with every operation a coroutine, and
takes an httpx.AsyncBaseTransport:
with, call talqing.close() — await talqing.close() on the
async client.
Two properties come with the client: talqing.base_url, and talqing.http, the
underlying httpx.Client already carrying the base URL and the token.
The call shape
Operations are reached by resource, exactly as the API names them. Path parameters are positional. Everything else — body fields and query parameters alike — is a keyword argument.An argument you do not pass is not sent
Every optional argument defaults to a sentinel,OMIT, and an argument still at
OMIT is left out of the request entirely. That is what makes an explicit
null sayable — the distinction a PATCH needs and a plain None default
would destroy:
OMIT is exported from talqing if you ever need to pass it deliberately, for
instance when building arguments in a dict.
The one renamed method
telephony.phone_numbers.import_() — import is a Python keyword. Everything
else carries the API’s own name.
Errors
Every non-2xx raisesTalqingAPIError. There is one error envelope, so there is
nothing to branch on.
A failure that never reached the API — a proxy’s HTML
502, a gateway
timeout — has no envelope to parse. It still raises TalqingAPIError, with the
raw body text as the message and an empty errors. A connection error or a
timeout raises httpx’s own exception, unchanged.
Pagination
paginate(page, *, limit=200, **filters) takes the bound method itself, not a
call to it, and passes anything else straight through as a filter. It stops when
has_more is false. paginate_async is the awaited form, driven with
async for. See pagination.
Streams
The six event-stream endpoints return aStream — an iterator of decoded
frames, and a context manager. Opening is not a coroutine on either client, so
async for reads exactly the way for does.
break or an exception.
404, 401, 403 — the client reads the error
body before anything else and raises TalqingAPIError immediately. A finished
stream cannot be reopened: it raises
RuntimeError: this stream is finished; open a new one to watch again. See
streaming for every frame each one emits.
Typing
Responses come back as decoded JSON, described by TypedDicts. Nothing is validated, coerced or renamed on arrival. A response is a plaindict at
runtime; the TypedDicts exist for your type checker and your editor and cost
nothing when you run. Two consequences worth knowing:
- Read fields with
response["field"], notresponse.field. - The SDK can never reject a payload the API considers valid. A field added to a response after your version was generated arrives intact — your type checker will not know about it, and your code still gets it.
Escape hatches
request(method, path, *, query=None, body=None) applies the same OMIT
filtering and the same error handling as a generated method, and returns the
decoded body.
The namespaces
Every method under them is in the Endpoints section of the API reference.
The path here is the operation’s id there:
telephony.phone_numbers.assign is
POST /v1/telephony/phone-numbers/{number_id}/assign.
Worked examples
Create and publish an agent
agents.update takes the complete config, not a patch — read the agent,
change what you need, send the whole object back:
Place an outbound call
Page through calls
Read the credit balance
base_url points at.
Credits do not move between regions, so label it with the region before you show
it to anyone. See pricing and credits.
Talk to a text agent and watch the reply
client_message_id is your own UUID and is the one deduplication key in this
API: re-sending with the same one is ignored rather than delivered twice, so a
retry is safe.
Streaming
Every frame the six event streams emit.
Errors
Every status code and what to retry.