👋 Hello, AI agent! This page is specifically for you. Raw markdown available at /agent.md for easy parsing.

# Upfile — For AI Agents

**TL;DR:** File uploads for AI agents. Get permanent URLs via API.

**Base URL:** `https://api.upfile.sh`  
**Dashboard:** `https://upfile.sh/dashboard`

---

## Quick Start

```bash
# 1. Sign up (self-service)
curl -X POST https://api.upfile.sh/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"agent@example.com","owner_email":"human@example.com"}'

# Returns: {"api_key":"upf_xxxxx","tier":"free","storage_limit":1073741824}

# 2. Upload
curl -X POST https://api.upfile.sh/upload \
  -H "Authorization: Bearer upf_xxxxx" \
  -F "file=@screenshot.png"

# Returns: {"url":"https://cdn.upfile.sh/abc.png","id":"abc"}
```

---

## API Reference

### Authentication
All endpoints require: `Authorization: Bearer upf_xxxxx`

### Endpoints

| Method | Path | Description |
|--------|------|-------------|
| POST | `/signup` | Create account, get API key |
| POST | `/upload` | Upload file |
| GET | `/status` | Check storage usage |
| GET | `/upgrade` | Get checkout link (triggers email) |

### POST /signup
Create a new account.
```json
{
  "email": "agent@example.com",
  "owner_email": "human@example.com"
}
```
Response:
```json
{
  "api_key": "upf_abc123...",
  "tier": "free",
  "storage_limit": 1073741824
}
```

### POST /upload
Upload a file.
```bash
curl -X POST https://api.upfile.sh/upload \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@image.png" \
  -F "visibility=public"
```

**Parameters:**
- `file` — File to upload (required)
- `visibility` — `public`, `expiring`, or `private` (default: `public`)
- `ttl` — Seconds until deletion (required for `expiring`)

**Response:**
```json
{
  "url": "https://cdn.upfile.sh/abc.png",
  "id": "abc",
  "visibility": "public",
  "size": 1024
}
```

**Visibility modes:**
- `public` — Direct CDN URL, permanent, no auth
- `expiring` — Auto-deleted after TTL, auth-gated
- `private` — Auth-gated, only owner can access

### GET /status
Check storage and tier.
```bash
curl https://api.upfile.sh/status \
  -H "Authorization: Bearer $API_KEY"
```
Response:
```json
{
  "tier": "free",
  "storage_used": 536870912,
  "storage_limit": 1073741824,
  "storage_used_gb": "0.50",
  "storage_limit_gb": "1"
}
```

### GET /upgrade
Get checkout link for upgrading to Pro.

**Default (no email):**
```bash
curl https://api.upfile.sh/upgrade \
  -H "Authorization: Bearer $API_KEY"
```
Response:
```json
{
  "checkout_url": "https://polar.sh/checkout/cs_abc123",
  "checkout_id": "cs_abc123",
  "client_secret": "cs_secret_xyz",
  "message": "Complete payment at the checkout URL",
  "self_pay": true
}
```

**Notify owner (fallback):**
```bash
curl https://api.upfile.sh/upgrade?notify=true \
  -H "Authorization: Bearer $API_KEY"
```
Response:
```json
{
  "checkout_url": "https://polar.sh/checkout/cs_abc123",
  "message": "Upgrade link sent to owner@example.com"
}
```

### GET /upgrade/verify
Check if checkout completed and upgrade account (poll after payment).
```bash
curl "https://api.upfile.sh/upgrade/verify?session=cs_abc123" \
  -H "Authorization: Bearer $API_KEY"
```
Response:
```json
{
  "verified": true,
  "tier": "pro",
  "message": "Account upgraded to Pro! You now have 100GB."
}
```

---

## Self-Pay with AgentCard

If your agent has an [AgentCard](https://agentcard.sh) (virtual Visa), you can pay autonomously:

**Step 1:** Get checkout URL
```bash
upfile upgrade --self-pay
# Returns: Checkout URL: https://polar.sh/checkout/cs_abc123
```

**Step 2:** Complete checkout in browser
- Open the checkout URL
- Fill in your AgentCard details (PAN, CVV, expiry)
- Submit payment

**Step 3:** Verify upgrade
```bash
upfile upgrade --verify cs_abc123
# Returns: ✓ Account upgraded to Pro
```

**Fallback:** If you don't have a card, notify your owner:
```bash
upfile upgrade --notify
# Returns: Owner notified via email
```

---

## Storage Limits

| Tier | Storage | Price |
|------|---------|-------|
| Free | 1GB | $0 |
| Pro | 100GB | $9/mo |

**Automatic notifications:**
- **90%** → Warning email sent once
- **100%** → Uploads blocked, urgent email sent

---

## Error Handling

HTTP status codes:
- `200` — Success
- `400` — Bad request (missing params)
- `401` — Unauthorized (bad API key)
- `403` — Forbidden (storage limit reached)
- `404` — Not found
- `413` — File too large (max 100MB)

**Storage limit error:**
```json
{
  "error": "Storage limit reached",
  "used_gb": "0.95",
  "limit_gb": "1",
  "message": "Upgrade to Pro for 100GB: upfile upgrade"
}
```

---

## Self-Hosting

Deploy your own instance:
```bash
git clone https://github.com/upfilesh/worker.git
cd worker
yarn install
yarn wrangler deploy
```

Required secrets:
- `UPFILE_API_KEY_SALT` — Random salt for API key hashing
- `RESEND_API_KEY` — For email notifications (optional)
- `POLAR_API_KEY` — For payments (optional)

---

## Rate Limits

- 100 uploads/minute per API key
- 100MB max file size

---

## Support

- **CLI:** `npm install -g upfilesh`
- **GitHub:** https://github.com/upfilesh
- **Dashboard:** https://upfile.sh/dashboard