# Tetrajedr API

A knowledge base built for AI agents.

Store, search, and link markdown documents with YAML metadata through a plain HTTP API. Documents connect via wiki-links forming a navigable graph. Every change is versioned. Every response is markdown. Every write is a form post.

Agents don't need SDKs, parsing, or special tooling — they read markdown and submit forms natively.

## Quick Start

1. **Get a token:** `POST /auth/magic-link` with `email=you@example.com`
2. **Check your email** and click the login link
3. **Use the token:** `Authorization: Bearer tet_...`

```bash
# Request a login link
curl -X POST -d "email=you@example.com" https://api.tetrajedr.com/auth/magic-link

# After clicking the link, use your token:
curl -H "Authorization: Bearer tet_..." https://api.tetrajedr.com/home
```

## Public Endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | `/` | This page |
| GET | `/health` | Health check |
| POST | `/auth/magic-link` | Request login link (form: `email`) |
| GET | `/auth/verify?token=` | Verify login link, get API token |

## Authenticated Endpoints

All require `Authorization: Bearer tet_...` header.

### Documents

| Method | Path | Description |
|--------|------|-------------|
| GET | `/home` | Your knowledge base entry point |
| GET | `/docs/{slug}` | Read a document |
| POST | `/docs/{slug}` | Create a document (form: `title`, `body`) |
| POST | `/docs/{slug}/update` | Update (form: partial fields, optional `expected_version`) |
| POST | `/docs/{slug}/delete` | Soft-delete |
| POST | `/docs/{slug}/restore` | Restore deleted document |
| POST | `/docs/{slug}/rename` | Rename (form: `new_slug`) |
| GET | `/docs/{slug}/history` | Version history |
| GET | `/docs/{slug}/diff?from=1&to=2` | Diff between versions |
| GET | `/docs/{slug}/ast?view=headings` | AST exploration (tree, metadata, body, links, headings, summary) |

### Search

| Method | Path | Description |
|--------|------|-------------|
| GET | `/search?q=text` | Full-text search |
| GET | `/search?tag=value` | Metadata filter |
| GET | `/search/ast?has_link=slug` | Structural search |

### Graph

| Method | Path | Description |
|--------|------|-------------|
| GET | `/graph/{slug}` | Outgoing links + backlinks |
| GET | `/graph/{slug}/outgoing` | Outgoing links only |
| GET | `/graph/{slug}/backlinks` | Backlinks only |
| GET | `/graph/{slug}/tree?depth=3` | Graph traversal (max depth 5) |

### Schema

| Method | Path | Description |
|--------|------|-------------|
| GET | `/schema` | All typed documents (forms, workflows, lists, etc.) |
| GET | `/schema?type=form` | Filter by type |
| GET | `/schema/for/{slug}` | Typed docs referencing a slug |

### Media

| Method | Path | Description |
|--------|------|-------------|
| POST | `/media` | Upload file (multipart) |
| GET | `/media` | List uploads |

### Admin

| Method | Path | Description |
|--------|------|-------------|
| GET | `/tokens` | List API tokens |
| POST | `/tokens` | Create token (form: `name`, `role`, `scopes`) |
| GET | `/snapshots` | Global change log |

## Response Format

- **Content-Type:** `text/markdown; charset=utf-8`
- **Auth errors:** 401 (missing/invalid token), 403 (insufficient scope)
- **Not found:** 404 with "Did you mean?" suggestions
- **Validation:** 422 with field-level errors
- **Rate limited:** 429 with retry-after

## Documentation

- API: https://api.tetrajedr.com/
- Website: https://tetrajedr.com
