# EveryAI Admin API

Programmatic control of the EveryAI site (blogs, tools, prompts, support
messages, image uploads). Backed by Cloudflare D1.

## Base URL
`https://everyai-api.everyai-com.workers.dev`

## Authentication
Every endpoint below requires a bearer token:
`Authorization: Bearer <API_KEY>`
The key is shown in the EveryAI admin dashboard under "API Access".
JSON bodies use `Content-Type: application/json`.

## Endpoints

### Blogs
- `GET  /api/blogs/list` — all blog posts.
- `POST /api/blogs/create` — body: { title, content, imageUrl, category?, excerpt?, slug?, readTime? }. slug/excerpt/readTime are auto-derived if omitted. Returns { id }.
- `POST /api/blogs/update` — body: { id, ...fields to change }.
- `POST /api/blogs/delete` — body: { id }.

### Tools (directory listings)
- `GET  /api/tools/list?status=approved|pending|payment_pending|declined` — omit status for all. Returns { count, tools }.
- `POST /api/tools/approve` — body: { id }.
- `POST /api/tools/reject` — body: { id }.
- `POST /api/tools/update` — body: { id, ...fields }.
- `POST /api/tools/delete` — body: { id }.

### Support messages
- `GET  /api/messages/list` — contact-form messages. Returns { count, messages }.
- `POST /api/messages/reply` — body: { id, body, subject?, isHtml?, deleteAfter? } — emails the sender. Or { to, subject, body } to send to any address.
- `POST /api/messages/delete` — body: { id }.

### Prompts
- `GET  /api/prompts/list`
- `POST /api/prompts/create` — body: { title, content, category?, imageUrl?, videoUrl? }. Returns { id }.
- `POST /api/prompts/delete` — body: { id }.

### Analytics
- `GET  /api/analytics` — site traffic counters (daily/weekly/monthly/yearly per type). Returns { traffic: [...] }.

### Images
- `POST /api/images/upload?folder=blogs` — upload an image, get back a hosted URL. Either multipart/form-data with an `image` file field (e.g. `curl -F "image=@cover.png"`) or raw image bytes with an `image/*` Content-Type. Returns { url }. Use that url as the imageUrl on a blog. There is no way to attach raw image bytes to a blog directly — upload here first, then reference the returned url.

## Responses
Success: `{ "ok": true, ... }`. Error: `{ "ok": false, "error": "..." }` with a 4xx/5xx status. 401 means the key is missing or wrong.

## Example
```
curl -X POST https://everyai-api.everyai-com.workers.dev/api/blogs/create \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{"title":"My Post","content":"<p>Hello</p>","imageUrl":"https://example.com/cover.jpg","category":"AI"}'
```
