# auth.md

Agent registration for **Unsubscribe Tool** (`unsubscribetool.com`) — an email unsubscribe service that scans your inbox for subscriptions and lets you unsubscribe from all in one click. Zero data retention, never sells your data.

This document describes how AI agents authenticate with and interact with our service. Follow the steps below: **discover → register → claim → use → handle revoke**.

## Discovery

Agent discovery metadata is published at these well-known URIs:

| Resource | URL |
|----------|-----|
| OAuth Protected Resource Metadata | `/.well-known/oauth-protected-resource` |
| OAuth Authorization Server Metadata | `/.well-known/oauth-authorization-server` |
| API Catalog (RFC 9727) | `/.well-known/api-catalog` |
| OpenAPI Spec | `/.well-known/openapi.json` |
| MCP Server Card | `/.well-known/mcp/server-card.json` |
| Agent Skills Index | `/.well-known/agent-skills/index.json` |
| AI Policy | `/.well-known/ai.txt` |

## Register

Agents register via the `agent_auth` block in `/.well-known/oauth-authorization-server`.

**Register URI**: `https://unsubscribetool.com/auth.md`

### Identity Types Supported

1. **Anonymous** — Agent registers without a user identity. Receives a scoped API key with pre-claim permissions.
   - Credential types: `api_key`

2. **Identity Assertion (Verified Email)** — Agent asserts a user identity via verified email. Receives an access token or API key with full permissions.
   - Assertion types: `verified_email`
   - Credential types: `access_token`, `api_key`

### Registration Flow

#### Anonymous Registration

```
POST /agent/auth
Content-Type: application/json

{
  "type": "anonymous",
  "requested_credential_type": "api_key"
}

→ 200 OK
{
  "api_key": "usk_...",
  "claim_token": "uct_..."
}
```

The agent operates with pre-claim scopes until the user claims ownership.

#### Verified-Email Identity Assertion

```
POST /agent/auth
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "assertion": "user@example.com"
}

→ 200 OK
{
  "claim_token": "uct_..."
}
```

## Claim

**Claim URI**: `https://unsubscribetool.com/auth.md#claim`

After anonymous or verified-email registration, the user must claim ownership:

1. Agent sends `POST /agent/auth/claim` with `claim_token` and user email
2. Service sends a one-time claim URL to the user's email
3. User opens the URL and enters the 6-digit OTP
4. Agent completes: `POST /agent/auth/claim/complete` with `claim_token` and OTP
5. Service swaps API key permissions from pre-claim to post-claim scopes

```
POST /agent/auth/claim/complete
Content-Type: application/json

{
  "claim_token": "uct_...",
  "otp": "123456"
}

→ 200 OK
{
  "status": "claimed"
}
```

## Use

Once registered and claimed, agents use credentials to access the API:

### OAuth 2.0 (Microsoft Identity Platform)

For Outlook/Hotmail users, Microsoft OAuth 2.0 is used for IMAP access:

- **Authorization Endpoint**: `https://login.microsoftonline.com/common/oauth2/v2.0/authorize`
- **Token Endpoint**: `https://login.microsoftonline.com/common/oauth2/v2.0/token`
- **JWKS URI**: `https://login.microsoftonline.com/common/discovery/v2.0/keys`
- **Grant Types**: `authorization_code`, `refresh_token`, `device_code`
- **Scopes**: `openid`, `profile`, `email`, `offline_access`, `https://outlook.office.com/IMAP.AccessAsUser.All`

### IMAP Authentication (Non-Outlook Providers)

For Gmail, iCloud, Proton Mail, Yahoo, and Zoho:
- Credentials transmitted over WebSocket (`wss://unsubscribetool.com/ws`)
- Credentials exist **only in server memory** during scanning
- Credentials are **never written to disk, database, or logs**

### Available Tools

| Tool | Description | Input |
|------|-------------|-------|
| `scan_inbox` | Scan inbox for subscription emails | `email`, `provider` |
| `batch_unsubscribe` | Unsubscribe from multiple senders | `subscriptions[]` |
| `subscription_audit` | Generate cost & frequency audit | `email` |

## Handle Revoke

**Revocation URI**: `https://login.microsoftonline.com/common/oauth2/v2.0/logout`

Agents handle revocation events by:
1. Listening for revocation events from the authorization server
2. Invalidating cached credentials immediately
3. Re-registering if continued access is needed

Revocation endpoint: `POST /agent/auth/revoke` with `claim_token` or `api_key`

## Privacy & Data Handling

- **Zero Data Retention**: Email credentials processed in memory only, destroyed after scanning
- **Never Sells Your Data**: No selling, sharing, or monetizing of user data
- **No Data Persistence**: Scan results returned to user, not stored on servers
- **GDPR Compliant**: Available in EU/EEA
- **CAN-SPAM Compliant**: Unsubscribe requests follow RFC 2369

## Rate Limits

- Free tier: 3 inbox scans per day
- No limit on blog content access

## Contact

- **Website**: https://unsubscribetool.com
- **Blog**: https://unsubscribetool.com/blog/
- **Privacy Policy**: https://unsubscribetool.com/privacy.html
- **Terms of Service**: https://unsubscribetool.com/terms.html
- **Email**: support@unsubscribetool.com

---

*Last updated: 2026-07-20*
