# AI Daily — Docs for AI agents

> Build a listener integration for AI Daily in five minutes. No signup, no API keys, no rate-limit gymnastics.

## Quickstart

Three lines, in order, get you from zero to a real episode:

```bash
# 1. Health check
curl https://ai-daily-6ke.pages.dev/status

# 2. Find an episode about something the listener cares about
curl 'https://ai-daily-6ke.pages.dev/api/search?q=ai&limit=3'

# 3. Read the full transcript of the top result (replace 1 with the id)
curl https://ai-daily-6ke.pages.dev/1.md
```

## Authentication

**None required.** Every endpoint is public, read-only, and CORS-open. No keys, no tokens, no signup.

Rate limits are documented (60 req/min per IP) but enforced at the edge — your code only needs to honor `X-RateLimit-Remaining` and `Retry-After` if you see them. There's no auth header to add.

## Code examples

### curl
```bash
# Latest episode as JSON
curl 'https://ai-daily-6ke.pages.dev/?mode=agent'

# Episode in markdown (use Accept header or .md suffix)
curl https://ai-daily-6ke.pages.dev/1.md
curl -H 'Accept: text/markdown' https://ai-daily-6ke.pages.dev/1

# NLWeb /ask, JSON
curl -X POST -H 'Content-Type: application/json' -d '{"query":"agentic commerce"}' https://ai-daily-6ke.pages.dev/ask

# NLWeb /ask, SSE streaming
curl -N -H 'Accept: text/event-stream' 'https://ai-daily-6ke.pages.dev/ask?q=agentic+commerce'

# MCP initialize (Streamable HTTP)
curl -X POST -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize"}' \
  https://ai-daily-6ke.pages.dev/mcp
```

### JavaScript / TypeScript
```js
// Search
const r = await fetch('https://ai-daily-6ke.pages.dev/api/search?q=ai+agents&limit=5');
const { results } = await r.json();

// Latest episode card
const agent = await fetch('https://ai-daily-6ke.pages.dev/?mode=agent').then(r => r.json());
console.log(agent.latestEpisode);

// MCP tool call
const mcp = await fetch('https://ai-daily-6ke.pages.dev/mcp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0', id: 1,
    method: 'tools/call',
    params: { name: 'search_episodes', arguments: { query: 'ai', limit: 5 } },
  }),
}).then(r => r.json());
```

### Python
```python
import requests

# Search
r = requests.get('https://ai-daily-6ke.pages.dev/api/search', params={'q': 'ai agents', 'limit': 5})
results = r.json()['results']

# NLWeb ask
r = requests.post('https://ai-daily-6ke.pages.dev/ask', json={'query': 'agentic commerce'})
for ep in r.json()['results']:
    print(ep['title'], ep['url'])
```

### Claude.ai (custom MCP connector)
```
Settings → Connectors → Add custom connector
URL: https://ai-daily-6ke.pages.dev/mcp
Transport: Streamable HTTP
Auth: None
```
After adding, Claude can call `search_episodes`, `get_episode`, `get_latest_episode`, `list_episodes`, and `subscribe_via_rss` directly.

### ChatGPT (custom GPT)
```
Configure → Actions → Import from URL
URL: https://ai-daily-6ke.pages.dev/.well-known/openapi.json
Auth: None
```
Or import the OpenAI plugin manifest at `https://ai-daily-6ke.pages.dev/.well-known/ai-plugin.json`.

### Cursor (MCP)
```json
{
  "mcpServers": {
    "ai-daily": {
      "url": "https://ai-daily-6ke.pages.dev/mcp",
      "transport": "streamable-http"
    }
  }
}
```

## API reference

| Endpoint | Method | Description |
|---|---|---|
| `/api/search?q=&limit=` | GET | Ranked full-text search over title + description + transcript |
| `/ask` | POST | NLWeb-style natural-language ask. JSON or SSE (`Accept: text/event-stream`) |
| `/ask?q=` | GET | Same as POST /ask but query-string |
| `/mcp` | POST | MCP JSON-RPC (Streamable HTTP). Methods: initialize, ping, tools/list, tools/call |
| `/mcp` | GET | MCP server manifest |
| `/.well-known/mcp` | GET/POST | MCP discovery + live handshake (same JSON-RPC handler) |
| `/.well-known/mcp/server-card.json` | GET | Preview-able server card (name, version, tools[]) |
| `/status` | GET | Service health for circuit-breaker logic |
| `/episodes.json` | GET | Full episode list with metadata |
| `/search-index.json` | GET | Flat search index for offline indexing |
| `/<id>` | GET | Episode HTML page (SSR'd, JS-free) |
| `/<id>.md` | GET | Episode in markdown (or `Accept: text/markdown`) |
| `/<id>?mode=agent` | GET | Episode as compact agent JSON |
| `/?mode=agent` | GET | Homepage as agent JSON (capabilities + endpoints + latest episode) |
| `/index.md` | GET | Homepage as markdown |
| `/AGENTS.md` | GET | This deployment's AGENTS.md |
| `/llms.txt`, `/episodes/llms.txt`, `/api/llms.txt`, `/.well-known/llms.txt` | GET | Section-scoped llms.txt files |
| `/.well-known/openapi.json` | GET | OpenAPI 3.1 spec |
| `/.well-known/agent.json` | GET | Agent capability declaration (schemaVersion 1.0) |
| `/.well-known/agent-card.json` | GET | A2A-style skill card |
| `/.well-known/agent-skills/index.json` | GET | agentskills.io v0.2.0 index |
| `/.well-known/ai-plugin.json` | GET | OpenAI plugin manifest |
| `/.well-known/schema-map.xml` | GET | NLWeb pointer to all structured feeds |
| `/rss.xml` | GET | RSS 2.0 feed |

Full typed schema for every operation is in [`https://ai-daily-6ke.pages.dev/.well-known/openapi.json`](https://ai-daily-6ke.pages.dev/.well-known/openapi.json).

## Errors

Every error is a structured JSON envelope:
```json
{
  "error": {
    "code": "episode_not_found",
    "message": "We don't have an episode #999 on this show.",
    "hint": "/episodes.json — full catalog with valid IDs",
    "docs_url": "/api/llms.txt"
  }
}
```

| Status | Code examples | When |
|---|---|---|
| 400 | `missing_query`, `bad_limit`, `bad_body` | Bad input |
| 404 | `episode_not_found` | Episode ID doesn't exist |
| 405 | `method_not_allowed` | Wrong HTTP method |
| 429 | `rate_limited` | Over 60 req/min/IP |
| 500 | `internal_error` | Something broke server-side |

## Rate limits

- **60 requests/minute per IP** across every endpoint listed above.
- Headers on every API response: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (Unix seconds).
- 429 responses also carry `Retry-After` (seconds).
- Self-throttle on those headers — don't backoff blindly.

## More

- Listener-agent integration guide: [`https://ai-daily-6ke.pages.dev/AGENTS.md`](https://ai-daily-6ke.pages.dev/AGENTS.md)
- Show briefing: [`https://ai-daily-6ke.pages.dev/llms.txt`](https://ai-daily-6ke.pages.dev/llms.txt)
- API briefing: [`https://ai-daily-6ke.pages.dev/api/llms.txt`](https://ai-daily-6ke.pages.dev/api/llms.txt)
- Coil source (the platform that generated this site): https://github.com/mluggy/coil
