# zero8.dev developer portal

zero8.dev exposes a public, read-only JSON API so agents and scripts can read the writing, the projects, and the contact route without scraping HTML.

- **Base URL:** `https://zero8.dev/api/v1`
- **OpenAPI 3.1:** https://zero8.dev/openapi.json (also https://zero8.dev/openapi.yaml)
- **Authentication:** none. No key, no signup, no OAuth. Do not send credentials.
- **Rate limit:** not enforced. Keep sustained traffic under roughly 60 requests per minute.
- **CORS:** `Access-Control-Allow-Origin: *` on every endpoint.

## Quickstart

```sh
curl -s https://zero8.dev/api/v1 | jq
curl -s "https://zero8.dev/api/v1/posts?limit=5" | jq '.data[].title'
curl -s "https://zero8.dev/api/v1/search?q=agent+harness" | jq '.data[0]'
curl -s https://zero8.dev/api/v1/posts/the-one-percent-internet | jq -r .content_markdown
```

## Endpoints

| Operation | Method | Path | Purpose |
| --- | --- | --- | --- |
| `getApiIndex` | GET | `/api/v1` | Discovery document listing every endpoint. |
| `getProfile` | GET | `/api/v1/profile` | Identity, expertise, availability, contact. |
| `listServices` | GET | `/api/v1/services` | Consulting areas and best-fit engagements. |
| `listPosts` | GET | `/api/v1/posts` | Published writing. `?tag=`, `?limit=`, `?offset=`. |
| `getPost` | GET | `/api/v1/posts/{slug}` | One post including its full Markdown body. |
| `listProjects` | GET | `/api/v1/projects` | Projects. `?status=live\|sunset\|delivered`. |
| `getProject` | GET | `/api/v1/projects/{id}` | One project by slug id. |
| `searchContent` | GET | `/api/v1/search` | Relevance-ranked search. `?q=` required. |

## Errors

Every failure is JSON with the same envelope — never an HTML page.

```json
{
  "error": {
    "code": "not_found",
    "status": 404,
    "message": "No post with slug \"nope\".",
    "hint": "List valid slugs at /api/v1/posts.",
    "documentation_url": "https://zero8.dev/developers",
    "openapi_url": "https://zero8.dev/openapi.json"
  }
}
```

Codes: `not_found` (404), `invalid_request` (400), `method_not_allowed` (405), `unsupported_media_type` (415), `internal_error` (500). Branch on `code`; recover with `hint`.

## Markdown representations

Every content page is available as Markdown at the same canonical URL:

```sh
curl -s -H "Accept: text/markdown" https://zero8.dev/blog
curl -s https://zero8.dev/blog.md
```

Responses carry `Vary: Accept, Accept-Encoding`, so shared caches keep the HTML and Markdown variants separate.

## MCP server

The same data is exposed over the Model Context Protocol at `https://zero8.dev/mcp` (Streamable HTTP). Stateless, read-only, no authentication — POST JSON-RPC 2.0 and read the reply; no session is issued.

```sh
curl -s -X POST https://zero8.dev/mcp -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'
```

| Tool | Returns |
| --- | --- |
| `zero8_get_profile` | Identity, expertise, availability, contact. |
| `zero8_list_posts` | Published writing, optionally filtered by tag. |
| `zero8_get_post` | One post in full Markdown. |
| `zero8_search_writing` | Relevance-ranked search over the writing. |
| `zero8_list_projects` | Projects, optionally filtered by status. |

## Other machine surfaces

- Site guide for agents: https://zero8.dev/llms.txt
- MCP server card: https://zero8.dev/.well-known/mcp/server-card.json
- MCP registry manifest: https://zero8.dev/server.json
- AI catalog (every AI-facing surface): https://zero8.dev/.well-known/ai-catalog.json
- Agent instructions (when to use this site): https://zero8.dev/.well-known/agent-instructions
- API catalog (RFC 9727): https://zero8.dev/.well-known/api-catalog
- Crawl policy: https://zero8.dev/robots.txt
- Sitemap: https://zero8.dev/sitemap.xml
- RSS feed: https://zero8.dev/feed.xml

## Versioning and deprecation policy

The path carries the major version. Additive changes — new fields, new endpoints — ship inside `v1`. Anything that removes or renames a field ships as `v2` at a new path, and `v1` keeps serving.

Every response advertises its version in `X-Api-Version` and links this policy as `Link: <.../developers#versioning-and-deprecation>; rel="deprecation"`. While a version is current, `X-Api-Deprecated: false` is returned.

When a version is deprecated:

- `X-Api-Deprecated` flips to `true` and a `Deprecation` header (RFC 9745) carries the date the deprecation took effect.
- A `Sunset` header (RFC 8594) carries the date the version stops responding — never less than **180 days** after the `Deprecation` date.
- The deprecated version keeps serving unchanged until its sunset date. Nothing is removed silently, and no breaking change ever lands inside a live version.
- The notice is repeated in the OpenAPI description, in llms.txt, and on this page.

After the sunset date the path returns `410 Gone` with the same JSON error envelope, whose `hint` names the successor endpoint.

**Current status:** `v1` is current and not deprecated. No sunset date is set. Report a problem to hello@zero8.dev.

---

Canonical HTML: https://zero8.dev/developers
Site guide for agents: https://zero8.dev/llms.txt · JSON API: https://zero8.dev/api/v1 · OpenAPI: https://zero8.dev/openapi.json