`authdog` 0.1.1 is the official Python client for the [Authdog REST API](/docs/api). Install it from PyPI. It is a management and userinfo client, not a web-framework session binding.

Need to protect FastAPI, Django, Flask, Starlette, or aiohttp routes? That is a different package. See [Python backends](/docs/backend/python).

## Install

```bash
python -m pip install "authdog==0.1.1"
```

Requires Python 3.8.1+ and `httpx` 0.24+. Source: [`python/`](https://github.com/authdog/sdk/tree/main/python) in [authdog/sdk](https://github.com/authdog/sdk). PyPI: [authdog](https://pypi.org/project/authdog/0.1.1/).

## Configure

Construct one client with the public API base URL. Pass a management Bearer credential (`ad_…`) when you call privileged endpoints:

```python
import os
from authdog import AuthdogClient

client = AuthdogClient(
    "https://api.authdog.com",
    api_key=os.environ["AUTHDOG_API_TOKEN"],
)
```

Keep the token server-side. `get_userinfo` still uses the caller access token, not the management key.

Use the client as a context manager so the HTTP session closes:

```python
from authdog import AuthdogClient

with AuthdogClient("https://api.authdog.com", api_key="ad_...") as client:
    probe = client.health()
```

`health()` is public and works without an API key.

## Resolve a user from an access token

```python
from authdog import APIError, AuthenticationError, AuthdogClient

client = AuthdogClient("https://api.authdog.com")

try:
    info = client.get_userinfo(access_token)
    print(info.user.display_name)
    print(info.user.emails[0].value)
except AuthenticationError:
    # 401: missing, invalid, or expired access token
    raise
except APIError:
    # transport or non-401 HTTP failure
    raise
```

`UserInfoResponse` uses snake_case attributes (`user.display_name`, `session.remaining_seconds`).

## Call the management API

Namespaces wrap Waves 1–2 of the public `/v1` surface:

| Attribute | Resources |
| --- | --- |
| `organizations` | Organizations, invitations, members, keys |
| `tenants` | Tenants, domains, seats |
| `projects` | Applications under a tenant |
| `environments` | Environment records |
| `users` | Directory users in a tenant + environment |
| `groups` | Groups and membership |
| `rbac` | Roles, permissions, resources, mappings, ABAC |
| `audit` | Administrative audit logs |
| `events` | Identity event stream |
| `webhooks` | Webhook subscriptions |
| `notification_channels` | SIEM / notification channels |
| `service_accounts` | Service accounts |
| `personal_access_tokens` | PATs |
| `api_secrets` | Environment API secrets |

```python
with AuthdogClient("https://api.authdog.com", api_key="ad_...") as client:
    orgs = client.organizations.list()
    users = client.users.list("ten_123", "env_456", limit=25)
```

Directory calls take `tenant_id` then `environment_id`. OpenAPI at [`/v1/openapi`](https://api.authdog.com/v1/openapi) is the field-level contract.

## Errors

- `AuthdogError` — base class
- `AuthenticationError` — 401
- `APIError` — transport failure or other HTTP 4xx/5xx (`status_code` when present)

## Next

- [API reference](/docs/api): auth, versioning, and resource families
- [Backend requests](/docs/backend): validate sessions on incoming requests
- [Python backends](/docs/backend/python): FastAPI / Django / Flask / Starlette / aiohttp session bindings
- [Users](/docs/users): directory model the `users` namespace talks to
