# Majordomo — Agent Skill Reference

Majordomo is a fully autonomous AI email agent platform. You can use the REST API to programmatically create and manage email agents that read incoming emails via IMAP, generate replies with an LLM, and send them via SMTP — all without human intervention.

This document is intended for AI agents and automated tooling. All endpoints return JSON unless noted.

---

## Base URL

```
https://usemajordomo.com/api/v1
```

---

## Authentication

All endpoints except `/auth/register`, `/auth/login`, and public webhooks require a Bearer token.

```
Authorization: Bearer <JWT_TOKEN>
```

### Register

```http
POST /auth/register
Content-Type: application/json

{ "email": "agent@example.com", "password": "s3cr3t" }
```

Response: `{ "id": 1, "email": "...", "token": "<JWT>" }`

### Login

```http
POST /auth/login
Content-Type: application/json

{ "email": "agent@example.com", "password": "s3cr3t" }
```

Response: `{ "token": "<JWT>" }`

### Current user

```http
GET /auth/me
Authorization: Bearer <JWT>
```

---

## Mailboxes

An **agent mailbox** is an IMAP/SMTP inbox monitored by Majordomo. Each mailbox has its own persona, rules, and escalation policy.

### Create a hosted mailbox (simplest)

Majordomo can provision a mailbox at `<botname>@agents.usemajordomo.com` for you:

```http
POST /mailboxes-local
Authorization: Bearer <JWT>
Content-Type: application/json

{ "botname": "support-bot", "password": "generated-client-side-password" }
```

`botname` must be alphanumeric and may contain dashes. The resulting email address is `<botname>@agents.usemajordomo.com`.

### Connect an existing IMAP/SMTP mailbox

```http
POST /mailboxes
Authorization: Bearer <JWT>
Content-Type: application/json

{
  "email_address": "support@example.com",
  "auth_type": "imap_smtp",
  "imap_host": "imap.example.com",
  "imap_port": 993,
  "smtp_host": "smtp.example.com",
  "smtp_port": 587,
  "username": "support@example.com",
  "password_or_token": "app-password"
}
```

### List mailboxes

```http
GET /mailboxes
Authorization: Bearer <JWT>
```

Response: `[{ "id": 1, "email_address": "...", "status": "active", "created_at": "..." }]`

### Get mailbox details

```http
GET /mailboxes/{id}
Authorization: Bearer <JWT>
```

Response includes `persona`, `tone`, `rules`, `escalation_triggers`, and `json_data` (advanced settings).

---

## Agent Configuration

Configure the AI agent's behaviour for a specific mailbox.

```http
PUT /mailboxes/{id}/config
Authorization: Bearer <JWT>
Content-Type: application/json

{
  "persona": "You are a helpful customer-support agent for Acme Corp. ...",
  "tone": "friendly",
  "rules": "Always confirm receipt of orders. Never discuss pricing.",
  "escalation_triggers": [
    "legal threat", "refund over $500", "abuse or harassment"
  ],
  "poll_interval_in_minutes": 5,
  "once_per_day_per_thread": false,
  "suppress_footer": false
}
```

**Key fields:**

| Field | Type | Description |
|---|---|---|
| `persona` | string | The system prompt / character the agent plays. Max 2 000 tokens. |
| `tone` | string | Tone of voice — e.g. `"friendly"`, `"formal"`, `"concise"`. |
| `rules` | string | Plain-language rules the agent must follow. |
| `escalation_triggers` | string[] | Keywords or conditions that cause the agent to escalate (mark unread + notify owner) instead of replying. |
| `poll_interval_in_minutes` | int\|null | How often to poll for new email. `null` = default (1 min). |
| `once_per_day_per_thread` | bool | If `true`, the agent replies at most once per day per email thread. |
| `suppress_footer` | bool | If `true`, omits the `usemajordomo.com` branding footer from replies. |
| `llm_model` | string\|null | Override the LLM model for this mailbox (e.g. `"gpt-4o"`). `null` = global default. |
| `documents` | array\|string\|null | RAG document context. Either an inline array of `{"name","description","url"}` objects, or a URL that returns the same JSON array. |

### Document context example

```json
{
  "documents": [
    { "name": "FAQ", "description": "Frequently asked questions", "url": "https://example.com/faq.txt" },
    { "name": "Pricing", "description": "Current pricing tiers", "url": "https://example.com/pricing.txt" }
  ]
}
```

---

## Activity & Metrics

### Activity log (paginated)

```http
GET /mailboxes/{id}/activity
Authorization: Bearer <JWT>
```

Response: `[{ "id": 1, "action": "replied", "timestamp": "...", "reason": "...", "recipient": "user@example.com" }]`

**Actions:** `replied`, `escalated`, `discarded`

### Stats

```http
GET /mailboxes/{id}/stats
Authorization: Bearer <JWT>
```

Response: `{ "processed": 42, "escalated": 3, "date_range": "last 30 days" }`

---

## Delete a mailbox

```http
DELETE /mailboxes/{id}
Authorization: Bearer <JWT>
```

Immediately purges credentials and configuration.

---

## Billing

### Check subscription status

```http
GET /billing/status
Authorization: Bearer <JWT>
```

Response: `{ "plan": "pro", "status": "active", "next_billing_date": "...", "remaining_free_replies": 0 }`

### Create checkout session (upgrade)

```http
POST /billing/checkout
Authorization: Bearer <JWT>
Content-Type: application/json

{ "success_url": "https://example.com/success", "cancel_url": "https://example.com/cancel" }
```

Response: `{ "url": "https://checkout.stripe.com/..." }`

---

## System

### Health check (no auth required)

```http
GET /api/v1/health
```

Response: `{ "status": "ok", "database": { "status": "ok" } }`

### Version

```http
GET /api/v1/version
```

Response: `{ "sha": "abc1234", "date": "2025-01-01 12:00:00 +0000" }`

---

## Typical agent workflow

1. `POST /auth/register` → obtain `token`
2. `POST /mailboxes-local` → provision `botname@agents.usemajordomo.com`; note `id`
3. `PUT /mailboxes/{id}/config` → set `persona`, `rules`, `escalation_triggers`, optionally `documents`
4. The email agent starts polling automatically — no further action required
5. `GET /mailboxes/{id}/activity` → observe actions taken
6. `GET /mailboxes/{id}/stats` → aggregate metrics

---

## Privacy & compliance

- Email content is processed **in-memory only** and never persisted to disk.
- Credentials are **symmetrically encrypted at rest**.
- Servers are **EU-hosted** and GDPR-compliant.
- `DELETE /account` permanently erases all user data (Right to Erasure).

---

## OpenAPI / interactive docs

Full OpenAPI schema: `https://usemajordomo.com/docs` (auto-generated by FastAPI)
