Anima SDK for Python — unified agent identity infrastructure (email, phone, vault)
Project description
Anima Python SDK
The official Python SDK for the Anima API -- unified agent identity infrastructure for email, phone, and vault.
Installation
pip install anima-labs
Quick start
from anima import Anima
client = Anima(api_key="sk-...")
# Create an agent
agent = client.agents.create(
org_id="org_123",
name="Support Bot",
slug="support-bot",
)
# Send an email
message = client.messages.send_email(
agent_id=agent.id,
to=["user@example.com"],
subject="Hello from Anima",
body="Your order has been shipped!",
)
print(message.id)
client.close()
Async usage
Every method is available in an async variant via AsyncAnima:
import asyncio
from anima import AsyncAnima
async def main():
async with AsyncAnima(api_key="sk-...") as client:
agents = await client.agents.list(org_id="org_123")
for agent in agents.items:
print(agent.name)
asyncio.run(main())
Resources
Both Anima (sync) and AsyncAnima have identical resource interfaces. All async methods use await.
client.agents
| Method | Description |
|---|---|
create(*, org_id, name, slug, email?, provision_phone?, metadata?) |
Create a new agent |
get(agent_id) |
Get an agent by ID |
list(*, cursor?, limit?, org_id?, status?, query?) |
List agents with pagination |
update(agent_id, *, name?, slug?, status?, metadata?) |
Update agent fields |
delete(agent_id) |
Delete an agent |
rotate_key(agent_id) |
Rotate an agent's API key |
client.messages
| Method | Description |
|---|---|
send_email(*, agent_id, to, subject, body, cc?, bcc?, body_html?, headers?, metadata?) |
Send an email |
send_sms(*, agent_id, to, body, media_urls?, metadata?) |
Send an SMS |
get(message_id) |
Get a message by ID |
list(*, cursor?, limit?, agent_id?, thread_id?, channel?, direction?, date_from?, date_to?) |
List messages with filters |
search(query, *, agent_id?, channel?, direction?, status?, date_from?, date_to?, cursor?, limit?) |
Full-text search messages |
upload_attachment(message_id, *, filename, mime_type, size_bytes) |
Upload an attachment |
get_attachment_url(attachment_id) |
Get a download URL for an attachment |
client.emails
| Method | Description |
|---|---|
list(*, cursor?, limit?, agent_id?) |
List emails with pagination |
upload_attachment(message_id, *, filename, mime_type, size_bytes) |
Upload an email attachment |
get_attachment_url(attachment_id) |
Get a download URL for an attachment |
client.phones
| Method | Description |
|---|---|
provision(*, agent_id, country_code?, area_code?, capabilities?) |
Provision a phone number |
get(phone_id) |
Get phone details |
list(*, cursor?, limit?, agent_id?) |
List phone numbers |
release(phone_id) |
Release a phone number |
update_config(phone_id, *, is_primary?, ten_dlc_status?, metadata?) |
Update phone configuration |
client.domains
| Method | Description |
|---|---|
add(*, domain) |
Add a custom domain |
get(domain_id) |
Get domain details |
list() |
List all domains |
delete(domain_id) |
Remove a domain |
update(domain_id, *, feedback_enabled?) |
Update domain settings |
verify(domain_id) |
Trigger domain verification |
dns_records(domain_id) |
Get required DNS records |
deliverability(domain_id) |
Get deliverability statistics |
zone_file(domain_id) |
Export the domain zone file |
client.vault
| Method | Description |
|---|---|
provision(*, agent_id) |
Provision a vault for an agent |
deprovision(*, agent_id) |
Deprovision an agent's vault |
list_credentials(*, agent_id, type?) |
List stored credentials |
get_credential(credential_id) |
Get a credential by ID |
create_credential(*, agent_id, type, name, notes?, login?, card?, identity?, fields?, favorite?, generate_password?) |
Store a new credential. generate_password={...} has the vault mint the login password server-side — stored, never returned (masked ref only) |
update_credential(credential_id, *, name?, notes?, login?, card?, identity?, fields?, favorite?) |
Update a credential |
delete_credential(credential_id) |
Delete a credential |
search(*, agent_id, search, type?) |
Search credentials |
generate_password(*, length?, uppercase?, lowercase?, numbers?, symbols?) |
Generate a secure password |
get_totp(credential_id) |
Get a TOTP code |
status(agent_id) |
Get vault status |
sync(agent_id) |
Force vault sync |
client.extension
| Method | Description |
|---|---|
connect(*, agent_id?, ttl?) |
Mint a one-time connect handoff for a headless browser-extension worker. With a master key pass agent_id; with an agent key omit it. ttl is "15m", "1h", or "session". Returns a connect_url (no secret). |
handoff = client.extension.connect(agent_id="agent_123", ttl="15m")
print(handoff.connect_url) # open in the extension worker to complete the handshake
client.security
| Method | Description |
|---|---|
scan_content(*, org_id, channel, body, agent_id?, subject?, metadata?) |
Scan content for threats |
list_events(*, org_id, agent_id?, type?, severity?, cursor?, limit?) |
List security events |
client.organizations
| Method | Description |
|---|---|
create(*, name, slug, clerk_org_id?, tier?, settings?) |
Create an organization |
get(org_id) |
Get organization details |
list(*, cursor?, limit?, query?) |
List organizations |
update(org_id, *, name?, slug?, clerk_org_id?, tier?, settings?) |
Update an organization |
delete(org_id) |
Delete an organization |
rotate_key(org_id) |
Rotate the master API key |
client.webhooks
| Method | Description |
|---|---|
create(*, url, events, description?, active?, auth_config?, rate_limit_per_minute?, max_attempts?) |
Register a webhook endpoint |
get(webhook_id) |
Get webhook details |
list(*, cursor?, limit?) |
List webhooks |
update(webhook_id, *, url?, events?, description?, active?, auth_config?, rate_limit_per_minute?, max_attempts?) |
Update a webhook |
delete(webhook_id) |
Delete a webhook |
test(webhook_id, *, event?) |
Send a test event |
list_deliveries(webhook_id, *, cursor?, limit?) |
List delivery attempts |
Configure the auth Anima presents to your endpoint on each delivery (in addition
to the always-on X-Anima-Signature HMAC) plus delivery throttling:
from anima import WebhookAuthBearer
webhook = client.webhooks.create(
url="https://example.com/anima/webhook",
events=["message.received"],
# Also: WebhookAuthBasic(username=, password=),
# WebhookAuthCustomHeader(header_name=, value=), WebhookAuthNone().
auth_config=WebhookAuthBearer(token="your-endpoint-token"),
rate_limit_per_minute=120, # omit for unlimited
max_attempts=5, # 1-10, default 3
)
print(webhook.id, webhook.auth_type) # -> "wh_..." "BEARER"
The credential you set (token / password / header value) is write-only — it
is never returned by get or list. To remove auth on update, pass
WebhookAuthNone().
Webhook verification
Verify incoming webhook signatures to ensure authenticity:
from anima import Anima, AnimaError
payload = request.body # raw request body (str or bytes)
sig = request.headers["anima-signature"]
secret = "whsec_..."
# Option 1: verify only
is_valid = Anima.verify_webhook_signature(payload, sig, secret)
# Option 2: verify and parse in one step
try:
event = Anima.construct_webhook_event(payload, sig, secret)
print(event.type, event.data)
except AnimaError:
print("Invalid signature")
Error handling
All API errors raise typed exceptions that subclass AnimaError:
from anima import Anima, AuthenticationError, NotFoundError, RateLimitError, APIError
client = Anima(api_key="sk-...")
try:
agent = client.agents.get("nonexistent")
except AuthenticationError:
print("Invalid API key")
except NotFoundError:
print("Agent not found")
except RateLimitError:
print("Rate limited -- back off and retry")
except APIError as e:
print(f"API error {e.status_code}: {e.message}")
Configuration
| Parameter | Default | Description |
|---|---|---|
api_key |
required | Your Anima API key (sk-...) |
base_url |
https://api.useanima.sh |
API base URL |
timeout |
30.0 |
Request timeout in seconds |
max_retries |
3 |
Max automatic retries on transient errors |
client = Anima(
api_key="sk-...",
base_url="https://api.useanima.sh", # custom endpoint
timeout=60.0,
max_retries=5,
)
Requirements
Documentation
Full API documentation is available at docs.useanima.sh.
Community
Join the Anima Discord to ask questions in #python-sdk, share what you're building in #showcase, and stay up to date with releases in #announcements.
License
This project is licensed under the MIT License. See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anima_labs-0.4.0.tar.gz.
File metadata
- Download URL: anima_labs-0.4.0.tar.gz
- Upload date:
- Size: 53.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3e5b6a2bacca66684e0ba8580563e1688e611691b81a0b3700298c28d0488ff
|
|
| MD5 |
34c8e510f8d91a6530e1e758f229585c
|
|
| BLAKE2b-256 |
9d6747b5550ce1fede411ea178b8106b14ed9e3c7429a5c2fa4fc9f4087e645d
|
Provenance
The following attestation bundles were made for anima_labs-0.4.0.tar.gz:
Publisher:
release.yml on anima-labs-ai/python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anima_labs-0.4.0.tar.gz -
Subject digest:
e3e5b6a2bacca66684e0ba8580563e1688e611691b81a0b3700298c28d0488ff - Sigstore transparency entry: 2102142418
- Sigstore integration time:
-
Permalink:
anima-labs-ai/python@c1223a23078d0e6b4f309e4a40eb003a64617036 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/anima-labs-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c1223a23078d0e6b4f309e4a40eb003a64617036 -
Trigger Event:
push
-
Statement type:
File details
Details for the file anima_labs-0.4.0-py3-none-any.whl.
File metadata
- Download URL: anima_labs-0.4.0-py3-none-any.whl
- Upload date:
- Size: 54.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
955d299128a5f0fa209db2006a57c7036dc4c5d7f2a1916ffcd8294212f6cf4f
|
|
| MD5 |
609189d81f3023cd16908522307b6fae
|
|
| BLAKE2b-256 |
aaff8bf26d66db7f1b6d16af1dfa7c2afb3303c1272d6f05e498f0b37e866660
|
Provenance
The following attestation bundles were made for anima_labs-0.4.0-py3-none-any.whl:
Publisher:
release.yml on anima-labs-ai/python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anima_labs-0.4.0-py3-none-any.whl -
Subject digest:
955d299128a5f0fa209db2006a57c7036dc4c5d7f2a1916ffcd8294212f6cf4f - Sigstore transparency entry: 2102142565
- Sigstore integration time:
-
Permalink:
anima-labs-ai/python@c1223a23078d0e6b4f309e4a40eb003a64617036 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/anima-labs-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c1223a23078d0e6b4f309e4a40eb003a64617036 -
Trigger Event:
push
-
Statement type: