Metadata-Version: 2.4
Name: keyid
Version: 0.2.9
Summary: KeyID.ai SDK — agent email infrastructure
License: MIT
Project-URL: Homepage, https://keyid.ai
Project-URL: Repository, https://github.com/KeyID-AI/sdk-py
Keywords: keyid,agent,ai-agent,email,agent-email,ed25519,identity,llm,ai-tools,ai-infrastructure,autonomous
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.25
Requires-Dist: cryptography>=41.0

# keyid

**Free email addresses and phone numbers for AI agents. No signup. No human needed.**

Your agent gets a real email address in 3 lines of code, with optional phone number on demand. Send, receive, reply, search — full email + SMS capabilities with zero registration, zero cost, zero human involvement.

[KeyID.ai](https://keyid.ai) handles everything: domain management, rotation, reputation monitoring, deliverability, phone pool management. Your agent just generates a keypair and calls `provision()`.

## Install

```bash
pip install keyid
```

## Quick Start

```python
from keyid import KeyID

agent = KeyID()

# Register — get an email address instantly
result = agent.provision()
print(f"Agent email: {result['email']}")

# Optionally request a phone number
phone_result = agent.request_phone()
print(f"Agent phone: {phone_result['phone']}")

# Read inbox
inbox = agent.get_inbox()
for msg in inbox["messages"]:
    print(f"{msg['from']}: {msg['subject']}")

# Send email
agent.send("user@example.com", "Hello", "Message body")

# Reply to a message
agent.reply(inbox["messages"][0]["id"], "Thanks!")
```

## Authentication

KeyID uses Ed25519 challenge-response authentication. The SDK handles this automatically:

1. On first use, a keypair is generated (or loaded from env/options)
2. `provision()` registers the public key and returns an email address
3. All subsequent calls auto-authenticate via signed nonce exchange

```python
# Option 1: Auto-generate keypair (default)
agent = KeyID()

# Option 2: Provide existing keypair
agent = KeyID(public_key="...hex...", private_key="...hex...")

# Option 3: Custom base URL
agent = KeyID(base_url="https://your-instance.com")
```

## API Reference

### Identity

| Method | Description |
|--------|-------------|
| `provision()` | Register agent, get email |
| `request_phone()` | Request a phone number (opt-in, authenticated) |
| `get_identity()` | Full profile (email, phone, avatarUrl, bio, reputation score/tier) |
| `get_addresses()` | List all addresses (current + historical) |
| `update_identity(**kwargs)` | Update profile (display_name, avatar_url, bio, website_url, profile_public) |
| `get_reputation()` | Get own reputation score (0-100), tier, factor breakdown |
| `get_public_profile(agent_id)` | Get another agent's public profile (no auth required) |
| `recover(recovery_token, new_public_key?, new_private_key?)` | Rotate keypair using recovery token |

### Messages

| Method | Description |
|--------|-------------|
| `get_inbox(**kwargs)` | Fetch inbox with pagination, filtering, search, channel filter |
| `get_message(id)` | Get single message detail |
| `update_message(id, **kwargs)` | Update labels, read/starred status |
| `get_unread_count()` | Count unread inbound messages |
| `send(to, subject, body, **kwargs)` | Send email (HTML, CC/BCC, scheduled) |
| `reply(message_id, body, **kwargs)` | Reply to a message |
| `reply_all(message_id, body, **kwargs)` | Reply-all |
| `forward(message_id, to, body=None)` | Forward a message |

### Threads

| Method | Description |
|--------|-------------|
| `list_threads(**kwargs)` | List conversation threads |
| `get_thread(thread_id)` | Get thread with all messages |
| `delete_thread(thread_id, permanent=False)` | Delete thread |

### Drafts

| Method | Description |
|--------|-------------|
| `create_draft(**kwargs)` | Create a draft |
| `get_draft(draft_id)` | Get draft detail |
| `update_draft(draft_id, **kwargs)` | Update draft |
| `delete_draft(draft_id)` | Delete draft |
| `send_draft(draft_id)` | Send a draft |

### Settings

| Method | Description |
|--------|-------------|
| `get_signature()` | Get email signature |
| `set_signature(signature)` | Set email signature |
| `get_forwarding()` | Get forwarding settings |
| `set_forwarding(forwarding_address)` | Configure email forwarding |
| `get_auto_reply()` | Get auto-reply/vacation settings |
| `set_auto_reply(**kwargs)` | Configure auto-reply |

### Contacts

| Method | Description |
|--------|-------------|
| `list_contacts(**kwargs)` | List saved contacts |
| `create_contact(**kwargs)` | Create a contact |
| `get_contact(contact_id)` | Get contact detail |
| `update_contact(contact_id, **kwargs)` | Update contact |
| `delete_contact(contact_id)` | Delete contact |

### Webhooks

| Method | Description |
|--------|-------------|
| `list_webhooks()` | List webhooks |
| `create_webhook(url, events=None)` | Create webhook |
| `get_webhook(webhook_id)` | Get webhook detail |
| `update_webhook(webhook_id, **kwargs)` | Update webhook |
| `delete_webhook(webhook_id)` | Delete webhook |
| `get_webhook_deliveries(**kwargs)` | Delivery history |

### Verification

| Method | Description |
|--------|-------------|
| `get_links(message_id)` | Extract links from a message |
| `get_codes(message_id)` | Extract verification codes from a message |
| `follow_link(message_id=None, link_index=None, url=None)` | Follow a verification link, returns final URL and redirects |

### Persona

| Method | Description |
|--------|-------------|
| `get_persona()` | Get agent persona profile |
| `create_persona(**kwargs)` | Create persona profile |
| `update_persona(**kwargs)` | Update persona profile |

### Registrations

| Method | Description |
|--------|-------------|
| `add_registration(service_name, **kwargs)` | Log a service registration |
| `list_registrations(**kwargs)` | List registrations with optional filters |
| `get_registration(id)` | Get registration by ID |
| `update_registration(id, **kwargs)` | Update a registration |
| `delete_registration(id)` | Delete a registration |

### Vault

| Method | Description |
|--------|-------------|
| `list_vault()` | List all vault entries (keys + metadata) |
| `get_vault_entry(key)` | Get a vault entry by key |
| `put_vault_entry(key, value, **kwargs)` | Store a value in the vault |
| `delete_vault_entry(key)` | Delete a vault entry |

### Lists & Metrics

| Method | Description |
|--------|-------------|
| `add_to_list(direction, type, entry)` | Add to allow/blocklist |
| `remove_from_list(direction, type, entry)` | Remove from list |
| `get_list(direction, type)` | Get list entries |
| `get_metrics(**kwargs)` | Query usage metrics |

## Features

- **Scheduled Send** — `agent.send("to@x.com", "Sub", "Body", scheduled_at="2025-01-01T10:00:00Z")`
- **Full-Text Search** — `agent.get_inbox(search="invoice")`
- **Starred Messages** — `agent.update_message(id, is_starred=True)`
- **Auto-Reply** — `agent.set_auto_reply(enabled=True, body="Out of office")`
- **HTML Email** — `agent.send("to@x.com", "Sub", "text", html="<h1>Hello</h1>")`
- **SMS Inbox** — `agent.get_inbox(channel="sms")` — filter by email or SMS
- **SMS Webhooks** — subscribe to `sms.received` events

## Requirements

- Python 3.9+
- `httpx` (installed automatically)

## License

MIT
