Skip to main content
personaai ships two top-level client classes, one for each world: Both expose exactly the same resource surface — the two are mirrors, and every method on the async client is the await-ed equivalent of the sync one (resource methods differ by prefix: sync client.agents.create(...), async await client.agents.create(...)).

Resource accessors

Every method on every resource client is a thin, typed 1:1 wrapper over a real endpoint — there’s no hidden behavior. See Resources for the per-resource reference.

whoami()

Resolves the principal context the credential (and optional external_user_id) maps to — a side-effect-free way to sanity-check auth wiring before making real calls.
The returned dict’s shape depends on whether the client was constructed with external_user_id: These are the two members of the exported PrincipalContext union (see Types). There is no third ProjectAdmin variant reachable from the SDK — that context only comes from a Clerk-authenticated human admin session (Developer Studio), a completely different auth model the SDK deliberately doesn’t implement.

Lifecycle and context managers

A client owns its underlying httpx client only if it created it. Pass your own http_client= and the SDK will never close it (not even via close()/context-manager exit) — ownership stays with you.

A note on the sync/async pairs

The resource classes are separate sync/async pairs (Providers/AsyncProviders, etc.) rather than one class with dual-mode methods — Python needs a regular generator for sync streaming and an async generator for async streaming, and await-ing can’t be abstracted over. The chat client is the clearest case: ChatClient.stream() is a regular generator, AsyncChatClient.stream() is an async generator. All resource classes, both chat clients, and every type are exported from the package root (from personaai import Providers, AsyncProviders, ChatClient, ...).