# Agent inbox for Yo This endpoint lets AI agents (and people) send Yo a request: a meeting, a message, an introduction or a question. **Nothing is approved, booked or answered without Yo personally deciding.** Not every request gets a personal answer: obvious spam, requests from blocked senders and requests Yo doesn't get to are closed without one. ## What this inbox can and cannot do - It **can** take your request, ask you for missing details, and later give you Yo's answer: approved (for meetings, a single-use booking link), declined, or a written reply you may answer once. - An automated screener may ask you up to three clarifying questions, once. - It **cannot** look up or reveal anything about Yo: calendar, availability, location, contacts, e-mail, other requests or how this service is configured. (Only after Yo approves a meeting does the booking link show open time slots.) There is no assistant here to persuade; the server is a form with a status page. Requests that try anyway are flagged to Yo. - Be direct and specific: who you are, who you act for, how you know Yo, what you want and why. Vague or evasive requests are usually declined. ## Quick start (REST) Base URL: `https://agents.lifeloggedin.com` 1. Submit: ```http POST /api/v1/requests Content-Type: application/json { "type": "meeting", "from": {"name": "Ava (scheduling assistant)", "is_ai_agent": true, "agent_platform": "Claude"}, "contact": {"name": "Jordan Lee", "organization": "Acme Robotics", "role": "VP Partnerships", "email": "jordan@acme.example", "website": "https://acme.example"}, "relationship": "Jordan met Yo at the Toronto AI meetup in October and was given this address.", "subject": "30 minutes to discuss a claims-automation pilot", "message": "Jordan would like to explore ...", "meeting": {"duration_minutes": 30, "format": "video", "timeframe": "next two weeks, weekday afternoons", "timezone": "America/Chicago"} } ``` The response contains `request_id`, `status`, and an **`access_token` shown only once**. Send it as `Authorization: Bearer ` on every later call. 2. If `status` is `needs_info`, answer the `questions` (this is the only time fields can change: once the request is complete it is locked for review, and later calls get HTTP 409): ```http POST /api/v1/requests/{request_id}/messages Authorization: Bearer {"fields": {"meeting": {"timezone": "Europe/London"}}, "message": "Optional free text"} ``` 3. Check for the outcome (no more than every 15 minutes; reviews take hours to days): ```http GET /api/v1/requests/{request_id} Authorization: Bearer ``` ## Fields | Field | Required | Notes | |---|---|---| | `type` | yes | `meeting`, `message`, `introduction`, `question`, `other` | | `from.name` | yes | Your name (agent or person) | | `from.is_ai_agent` | yes | `true` / `false` | | `from.agent_platform` | no | e.g. "Claude", "custom" | | `contact.name` | yes | The human or organisation you act for | | `contact.email` | yes | Who you act for; shown to Yo. Answers come back through this API, not by e-mail | | `contact.organization`, `contact.role`, `contact.website` | no | Helps the review | | `relationship` | yes | How you know Yo and how you got this address (max 600 chars) | | `subject` | yes | One line (max 150) | | `message` | yes | What you want and why (max 4000) | | `meeting.duration_minutes` | meetings | 15, 20, 30, 45 or 60 | | `meeting.timeframe` | meetings | e.g. "next two weeks, mornings" | | `meeting.timezone` | meetings | IANA name, e.g. `America/Toronto` | | `meeting.format` | no | `video` (default), `phone`, `in_person` | | `meeting.attendees` | no | Up to 5 `{name, email}` | | `meeting.notes` | no | Max 600 chars | You can start with only a `message` (plain text body works too); the reply will list what is missing. ## Statuses | Status | Meaning | |---|---| | `needs_info` | Answer `questions` via `/messages`. | | `under_review` | Waiting for Yo. Nothing to do. | | `approved` | See `response.message`; meetings include `response.booking_url`: one booking, made by whoever opens it first, who enters their own name and e-mail there (the invitation goes to that address, not automatically to `contact.email`). | | `declined` | See `response.message`. | | `replied` | Yo wrote back in `response.message`; you may answer once via `/messages` (text only). | | `closed` | Closed without further action. | ## MCP Streamable-HTTP MCP endpoint (JSON responses, stateless): `https://agents.lifeloggedin.com/mcp` Tools: `submit_request`, `add_to_request`, `check_request` (same fields as above; pass `request_id` and `access_token` as arguments). ## Limits A few new requests per hour per client; 60 calls per minute per client (each item in an MCP batch counts as one call); 12 additions per request after the initial submission (a call with both `fields` and `message` counts as two); 32 KB per body. Over a timed limit you get HTTP 429 with `retry_after_seconds`. The per-request addition cap is permanent: HTTP 409 with `"permanent": true` (start a new request instead). Incomplete requests close after 7 days; after a `replied` status you have 14 days to answer before the request is closed. Don't send anything you wouldn't put in an e-mail to a stranger. Machine-readable: [`/openapi.json`](https://agents.lifeloggedin.com/openapi.json), [`/.well-known/agent-card.json`](https://agents.lifeloggedin.com/.well-known/agent-card.json).