Python SDK for Circle.so covering three APIs:
- Headless Auth API -- token management for headless integrations
- Admin API V2 -- server-side community management (~120 endpoints)
- Headless Client API V1 -- member-facing operations (~100 endpoints)
pip install circle-so-python-sdkCircle uses two different API tokens. Which one you need depends on what you want to access:
| Token | Source | Use for |
|---|---|---|
| Admin API token | Circle Admin > Settings > API | client.admin.* -- manage members, spaces, posts as admin |
| Headless Auth token | Circle Admin > Developers > Headless Auth | client.auth.* + client.headless.* -- DMs, notifications, posts as a user |
These are not interchangeable. Admin endpoints return 401 with a headless token and vice versa.
from circle import CircleClient
# --- Admin API (server-side management) ---
# Requires: Admin API token
admin_client = CircleClient(api_token="YOUR_ADMIN_TOKEN")
community = admin_client.admin.get_community()
members = admin_client.admin.list_community_members()
# --- Creating posts (admin API) ---
# tiptap_body MUST be wrapped in a "body" key, and uses camelCase node types
tiptap_body = {
"body": {
"type": "doc",
"content": [
{"type": "paragraph", "content": [{"type": "text", "text": "Hello world"}]},
{"type": "bulletList", "content": [
{"type": "listItem", "content": [{"type": "paragraph", "content": [{"type": "text", "text": "Item one"}]}]},
]},
]
}
}
post = admin_client.admin.posts.create_post(
space_id=123456,
name="My Post Title",
tiptap_body=tiptap_body,
status="published",
)
# --- Headless API (user-scoped: DMs, notifications, posts) ---
# Requires: Headless Auth token
headless_client = CircleClient(api_token="YOUR_HEADLESS_TOKEN")
# Option 1: Convenience method (recommended)
user = headless_client.headless_as_user(email="you@example.com")
rooms = user.chat_notif_members.list_chat_rooms()
unread = user.chat_notif_members.get_unread_chat_rooms()
# Option 2: Manual two-step flow
token = headless_client.auth.create_auth_token(email="you@example.com")
user_client = CircleClient(api_token=token.access_token, community_url="https://your-community.circle.so")
spaces = user_client.headless.list_spaces()from circle import AsyncCircleClient
async with AsyncCircleClient(api_token="YOUR_TOKEN") as client:
members = await client.admin.list_community_members()| API | Endpoints | Sync | Async |
|---|---|---|---|
| Headless Auth | 4 | Yes | Yes |
| Admin V2 | ~118 | Yes | Yes |
| Headless Client V1 | ~101 | Yes | Yes |
- Quickstart -- install, auth, basic usage
- Admin API -- all admin endpoints with examples
- Headless API -- all headless endpoints with examples
- Auth API -- headless auth token management
- Models -- complete models reference
- Webhooks -- signature verification and payload parsing
- Limitations -- known Circle API limitations (mentions, polls, moderators)
src/circle/
__init__.py # Public API exports
client.py # CircleClient / AsyncCircleClient facade
http.py # Sync/Async HTTP transport with retry
exceptions.py # Typed exceptions (401/403/404/422/429)
pagination.py # Auto-pagination helpers
rate_limit.py # Token bucket rate limiter
validation.py # Request body validation models
webhooks.py # Webhook signature verification
models/
auth.py # HeadlessAuthToken, RefreshedAccessToken
admin/ # ~35 Pydantic models for Admin API
headless/ # ~40 Pydantic models for Headless API
api/
auth.py # Headless Auth client (4 endpoints)
admin_*.py # 8 Admin API client modules
headless_*.py # 3 Headless API client modules
- Clone the repo and install in dev mode:
pip install -e .[dev] - Run tests:
pytest tests/ -v --ignore=tests/integration - Follow conventional commit format for commit messages
MIT