Skip to content

Python SDK

Terminal window
pip install authpipe

Requires Python 3.10+. Uses httpx for HTTP and pydantic for types.

from authpipe import Authpipe
client = Authpipe(
api_key="sk_...",
base_url="https://api.authpipe.dev", # optional
api_version="2026-04-07", # optional
cache=True, # optional (default True)
cache_ttl_seconds=300, # optional (default 300)
)
from authpipe import AsyncAuthpipe
client = AsyncAuthpipe(api_key="sk_...")

Both clients support context managers:

# Sync
with Authpipe(api_key="sk_...") as client:
result = client.get_credential(provider="slack", tenant_id="org_acme")
# Async
async with AsyncAuthpipe(api_key="sk_...") as client:
result = await client.get_credential(provider="slack", tenant_id="org_acme")
OptionTypeDefaultDescription
api_keystrSecret or publishable API key (required)
base_urlstrhttps://api.authpipe.devAPI base URL
api_versionstr | NoneNoneAPI version header
cacheboolTrueEnable credential caching
cache_ttl_secondsint300Cache TTL in seconds

All parameters are keyword-only.

result = client.get_credential(
provider="slack",
tenant_id="org_acme",
user_id="user_jane", # optional
installation_id="inst_123", # optional
credential_for="any", # optional: "any", "installation", "user"
)
result.credential # str — access token or API key
result.credential_type # str — "oauth_token", "api_key", etc.
result.source # str — "connection" or "installation"
result.expires_at # datetime | None
result.scopes # list[str] | None

Async:

result = await client.get_credential(provider="slack", tenant_id="org_acme")
result = client.store_credential(
provider="sendgrid",
tenant_id="org_acme",
credential_type="api_key", # "api_key" or "webhook_secret"
credential="SG.xxxx",
user_id="user_jane", # optional
installation_id="inst_123", # optional
)
result.connection_id # str
result.status # str
session = client.create_auth_session(
provider="google",
tenant_id="org_acme",
redirect_url="https://yourapp.com/callback",
user_id="user_jane", # optional
scopes=["drive.readonly"], # optional
installation_id="inst_123", # optional
template_variables={"shop": "acme-store"}, # optional
)
session.session_id # str
session.authorization_url # str — redirect the user here
session = client.create_install_session(
provider="slack",
tenant_id="org_acme",
redirect_url="https://yourapp.com/installed",
user_id="user_admin", # optional
permissions=["channels:read", "chat:write"], # optional
)
conn = client.get_connection(connection_id="conn_abc123")
client.delete_connection(connection_id="conn_abc123")
result = client.refresh_connection(connection_id="conn_abc123")
result.refreshed # bool
result.expires_at # datetime | None
from authpipe.types import SearchRequest, SortDirective
resp = client.search_connections(SearchRequest(
filter={"tenant_id": {"eq": "org_acme"}, "status": {"eq": "active"}},
sort=[SortDirective(field="connected_at", direction="desc")],
cursor="cursor_token",
limit=25,
))
resp.data # list[Connection]
resp.has_more # bool
resp.next_cursor # str | None
resp.limit # int
inst = client.get_installation(installation_id="inst_abc123")
client.delete_installation(installation_id="inst_abc123")
resp = client.search_installations(SearchRequest(
filter={"tenant_id": {"eq": "org_acme"}},
))
config = client.create_provider_config(
provider_id="slack",
client_id="your-client-id",
client_secret="your-client-secret",
oauth_redirect_url="https://api.authpipe.dev/oauth/callback",
attachment="user",
enabled=True,
scopes=["channels:read"],
)
config = client.get_provider_config(config_id="pcfg_abc123")
config = client.update_provider_config(
config_id="pcfg_abc123",
client_secret="new-secret",
scopes=["channels:read", "chat:write"],
bot_scopes=["chat:write"],
signing_key="signing-secret",
enabled=True,
)
client.delete_provider_config(config_id="pcfg_abc123")
resp = client.search_provider_configs(SearchRequest(
filter={"provider_id": {"eq": "slack"}},
))
provider = client.get_provider(provider_id="slack")
resp = client.search_providers(SearchRequest(
query="email",
filter={"category": {"eq": "communication"}},
limit=10,
))
provider = client.create_custom_provider(
id="my-internal-api",
name="My Internal API",
auth_api_key={"key_field": "x-api-key"},
)
provider = client.get_custom_provider(custom_provider_id="my-internal-api")
provider = client.update_custom_provider(
custom_provider_id="my-internal-api",
name="Updated Name",
)
client.delete_custom_provider(custom_provider_id="my-internal-api")
resp = client.search_events(SearchRequest(
filter={"event_type": {"eq": "connection.created"}},
sort=[SortDirective(field="created_at", direction="desc")],
limit=50,
))
keys = client.list_api_keys() # list[APIKey]
result = client.create_api_key(name="Production", role="secret")
result.id # str
result.key # str (only returned once)
client.revoke_api_key(api_key_id="key_abc123")
config = client.get_webhook_config()
config.webhook_url # str
config.has_secret_1 # bool
config.has_secret_2 # bool
result = client.set_webhook_config(webhook_url="https://yourapp.com/webhooks")
result.webhook_url # str
result.secret # str (save this)
result = client.rotate_webhook_secret()
result.secret # new secret
client.delete_webhook_config()
ws = client.get_workspace(workspace_id="ws_abc123")
ws = client.update_workspace(workspace_id="ws_abc123", name="New Name")

The SDK raises AuthpipeAPIError for HTTP errors:

from authpipe.errors import AuthpipeAPIError
try:
result = client.get_credential(provider="slack", tenant_id="org_acme")
except AuthpipeAPIError as e:
print(e.status_code) # HTTP status
print(e.code) # Error code
print(e.message) # Human-readable message

Automatic retry on 429 and 5xx with exponential backoff (up to 3 attempts).

All response types are Pydantic BaseModel subclasses:

from authpipe.types import (
GetCredentialResult,
StoreCredentialResult,
CreateAuthSessionResult,
Connection,
Installation,
ProviderConfig,
Provider,
SearchRequest,
SearchResponse,
SortDirective,
)