# HTTP API reference

> Every Eggent HTTP address — which are open to integrations with a token, which need a web sign-in, and what they accept and return.

Source: https://eggent.ai/docs/http-api/

Eggent has two kinds of HTTP addresses:

- **The external API** (`/api/external/*`) — for integrations. Authorised with a token: `Authorization: Bearer <token>`. In detail in [HTTP API for integrations](https://eggent.ai/docs/external-api.md).
- **The web app API** — everything else. Needs a sign-in: the session cookie set by `/api/auth/login`. The interface itself uses these addresses; for automation, prefer the external API.

Base URL: `https://name.cloud.eggent.ai` in the cloud, or your server's address.

## External API {#external}

| Method and path | What it does |
| --- | --- |
| `POST /api/external/message` | Send a message, get an answer (JSON or an SSE stream) |
| `POST /api/external/media-message` | The same with a file, `multipart/form-data` |
| `POST /api/external/telegram/sent` | For a Telegram bot that sends the answers itself: `{"telegramChatId","messageIds","chatId"}` — which messages carried an answer from which chat, so a reply to them continues that chat |
| `GET /api/external/token`, `POST /api/external/token` | See or issue the token (needs a sign-in) |

## Service {#service}

| Method and path | What it does |
| --- | --- |
| `GET /api/health` | Health check: `{"status":"ok","timestamp":"…","version":"0.2.9"}`. No auth |
| `POST /api/auth/login` | Sign in: `{"username":"…","password":"…"}` → session cookie |

## Projects {#projects}

| Method and path | What it does |
| --- | --- |
| `GET /api/projects` | List projects |
| `POST /api/projects` | Create: `{"name","description","instructions"}` |
| `GET`, `PUT`, `DELETE /api/projects/:id` | Read, change, delete a project |
| `GET`, `PUT /api/projects/:id/context` | The project's context (`context.md`) |
| `GET`, `PUT /api/projects/:id/memory` | The project's memory (`memory.md`) |
| `GET`, `PUT /api/projects/:id/model` | The project's model (`model.json`) |
| `GET`, `DELETE /api/projects/:id/skills` | The project's skills. `DELETE` takes `{"name"}` and removes that skill, with the earlier versions kept when it was replaced |
| `POST /api/projects/:id/skills/upload` | Upload one skill as a file (a multipart form: `file`, and `replace=1` to replace an installed one) |
| `GET`, `PUT /api/projects/:id/mcp` | The project's MCP servers (`.mcp.json`) |

For context, memory, skills and MCP, use `none` for `:id` to address the orchestrator. The orchestrator has no model of its own: it answers with the workspace model.

## What the agent has learned {#learning}

| Method and path | What it does |
| --- | --- |
| `GET /api/learning` | The notes, the skills the agent wrote, and whether learning is on |
| `POST /api/learning` | `{"enabled":true\|false}`, or add or remove one note: `{"action":"add","target":"user\|notes","content":"…"}`, `{"action":"remove","target":"user\|notes","text":"…"}` |

## Chats {#chats}

| Method and path | What it does |
| --- | --- |
| `POST /api/chat` | Send a message from the interface (streaming) |
| `GET /api/chat/history` | The chat list, or one chat's history |
| `GET /api/chat/:id/stream` | Attach to an answer that is still being written |
| `POST /api/chat/:id/stop` | Stop the work in a chat |
| `GET`, `POST`, `DELETE /api/chat/files` | Chat attachments |

## Project files {#files}

| Method and path | What it does |
| --- | --- |
| `GET /api/files` | Folder contents |
| `GET /api/files/content` | A file's text |
| `GET /api/files/download` | Download a file. With `inline=1`, open it in the browser, isolated |
| `GET /api/files/zip` | A folder (`path=`) or several files (repeat `path=`) as one `.zip`; `check=1` answers what it would hold. Refused with 413 above the limits |
| `GET /api/files/stat` | Which of the listed paths still exist |
| `GET`, `POST /api/files/telegram` | Whether Telegram can be reached; send one file to your own chat |
| `POST /api/files/upload` | Upload files and folders, `multipart/form-data` |
| `DELETE /api/files` | Delete a file or folder |
| `GET`, `DELETE /api/files/versions` | A file's [history](https://eggent.ai/docs/files.md#history) (`project`, `path`), or delete it |
| `GET /api/files/versions/content` | The text of version `n` |
| `GET /api/files/versions/download` | Version `n` as a file |
| `POST /api/files/versions/restore` | `{ project, path, n, force? }` — restore version `n` as a new version |
| `GET`, `POST /api/files/versions/usage` | How much the history takes; `{ "action": "clear", "olderThanDays" }` clears it |
| `GET /api/files/page-link` | Where a [page](https://eggent.ai/docs/files.md#pages) is shown (`project`, `path`, `mode=edit\|print`), for a while |
| `GET /api/files/page-element` | The block picked on a page: label, lines, source (`sha`, `el`) |
| `POST /api/files/page-edit` | `{ project, path, sha, edits }` — words changed on a page, written where they came from |
| `GET /api/files/page-print` | A file made ready to [save as PDF](https://eggent.ai/docs/files.md#pdf) |

Upload parameters: `project`, `path`, `files` (repeatable), `relativePaths` (where each file goes, by position), `directories` (empty folders), `conflict` — `skip` (default), `overwrite` or `rename`. One request carries at most 100 MB, otherwise the answer is `413`.

```bash
curl -X POST https://name.cloud.eggent.ai/api/files/upload \
  -b cookies.txt \
  -F "project=my-project" \
  -F "path=." \
  -F "conflict=rename" \
  -F "files=@./notes.md"
```

## Task board {#board}

Writes need a session from the same site and a JSON body, like the terminal's routes.

| Method and path | What it does |
| --- | --- |
| `GET /api/board` | Every card, whether the board is paused, which cards are being worked on; `?archived=1` includes cards put away |
| `GET /api/board/summary` | How many cards wait for you, run and are queued |
| `POST /api/board/cards` | A new card: `title`, `body`, `projectId`, `after`, `review`, `start` |
| `GET`, `PATCH`, `DELETE /api/board/cards/:id` | One card; `PATCH` edits it or moves it with `{ "move": { "to": "inbox" \| "queued" \| "done" \| "archived" \| "unarchived", "position" } }` |
| `POST /api/board/cards/:id/answer` | `{ "text" }` — the answer to the card's question |
| `POST /api/board/cards/:id/stop` | Stop it; a queued card goes back to the Inbox |
| `POST /api/board/start-all` | Every Inbox card (of `projectId`, when given) into the queue |
| `POST /api/board/resume` | Let the board go on after the model service refused |

## Company {#company}

Only in a workspace that belongs to a [company](https://eggent.ai/docs/company.md). Writes need a session from the same site and a JSON body.

| Method and path | What it does |
| --- | --- |
| `GET /api/mail/contacts` | The company's people and unread messages |
| `GET /api/mail/thread` | The thread with a person (`with`, `before`, `limit`) |
| `POST /api/mail/send` | `{ to, text, files?, replyTo? }` |
| `POST /api/mail/read` | `{ with, upTo }` — mark read |
| `POST /api/mail/assign` | `{ messageId }` — open a chat with the agent about a message |
| `GET /api/mail/attachments/:id` | A file from a thread |
| `GET /api/shares` | Files shared with you and files you shared |
| `GET /api/shares/people` | Who a file can be shared with |
| `GET /api/shares/file` | One of your files and who it is shared with (`project`, `path`) |
| `POST /api/shares/share` | `{ project, path, people: [{ id, role }] }` — the list given is everybody who has it |
| `GET /api/shares/:id`, `GET /api/shares/:id/text` | A shared file: who has it, and what it holds |
| `GET`, `POST /api/shares/:id/content` | The file; `{ baseSha, text }` changes its text onto that version |
| `POST /api/shares/:id/page-edit` | `{ sha, edits }` — words changed on a shared page |
| `GET`, `POST /api/shares/:id/comments` | Comments; `{ body, quote?, anchor?, replyTo? }` |
| `POST /api/shares/:id/comments/:comment/resolve`, `/delete` | Resolve (`{ resolved }`) or delete a comment |
| `POST /api/shares/:id/stop` | Stop sharing |
| `GET /api/approvals` | Approvals: `box=waiting\|sent\|involved` |
| `GET /api/approvals/file` | One of your files and its approval (`project`, `path`) |
| `POST /api/approvals/send` | `{ project, path, approvers, note? }` — the version the file holds now |
| `GET /api/approvals/:id` | One approval with its rounds |
| `POST /api/approvals/:id/decide` | `{ round, decision: "approve" \| "reject", comment? }` |
| `POST /api/approvals/:id/cancel` | Withdraw |
| `GET /api/approvals/:id/rounds/:round/file`, `/text` | A round's version, as a file or as text |

## Schedules {#schedules}

| Method and path | What it does |
| --- | --- |
| `GET /api/pi-schedules` | Every scheduled task across the projects and the orchestrator, with whether and why one is paused |
| `POST /api/pi-schedules` | Change one task: `{"action": "pause" \| "resume" \| "retime" \| "delete", "jobId": "…"}` (`retime` also takes `schedule`) |
