# Docs — the heydenys.com content API

> This site serves itself as data: every page is available as Markdown, the whole site fits in one file, and a read-only JSON API is described by OpenAPI 3.1 at https://www.heydenys.com/openapi.json.

## Read the whole site in one request

[https://www.heydenys.com/llms-full.txt](https://www.heydenys.com/llms-full.txt) is every page concatenated as Markdown — about 18 KB, roughly 4,400 tokens, and complete. [https://www.heydenys.com/llms.txt](https://www.heydenys.com/llms.txt) is the shorter llmstxt.org overview, including what this site is *not* a good source for.

## Every page as Markdown

Send `Accept: text/markdown` to any page URL, or append `.md` to the path, per the acceptmarkdown.com convention. Q-values are honoured; a client that refuses both HTML and Markdown gets a 406 listing what is available.

## The JSON API

Version 1.0.0. Read-only, no authentication and no key. Every response sets `Access-Control-Allow-Origin: *` and is cached at the edge for an hour.

Every endpoint answers at two addresses — the pinned one and the unversioned one — and returns identical bytes at both:

- `GET /api/v1` (also `/api`) — This index: every endpoint, and where the API is described.
- `GET /api/v1/pages` (also `/api/pages`) — Every page on the site with its title, summary and last-modified date.
- `GET /api/v1/pages/{slug}` (also `/api/pages/{slug}`) — One page, including its complete Markdown body.
- `GET /api/v1/profile` (also `/api/profile`) — The canonical facts about Denys Ishchenko: role, location, history, contact.
- `GET /api/v1/markdown/{slug}` (also `/api/markdown/{slug}`) — One page as raw Markdown, unwrapped.

Start at [https://www.heydenys.com/api/v1](https://www.heydenys.com/api/v1), which lists all of it, including the two policies below.

## Versioning and deprecation

`/api/v1/...` is pinned to the v1 response shapes and is the one to hard-code. `/api/...` serves the same bytes but always tracks the current major, so it is the convenient one and the one that can move under a client. Every JSON response states which shape produced it in the `API-Version` header.

Nothing is deprecated. When something is, the responses that are going away start carrying `Deprecation` (RFC 9745) with the date the decision took effect and `Sunset` (RFC 8594) with the date they stop answering, at least 180 days apart, plus `Link: rel="deprecation"` pointing at the page that explains it. A breaking change to a response shape is not a deprecation: it is a new major at /api/v2, and /api/v1 keeps answering until its own Sunset date. Pin /api/v1 if that matters; /api/... without a version always tracks the current major.

## Rate limits

600 requests per 60 seconds per client address, enforced at the origin. Every JSON response carries the quota, readable from a browser too —`RateLimit-Policy: "content";q=600;w=60`, and `RateLimit-Limit: 600` for older clients — so a client can pace itself before its first failure.

Successful responses are cached at the edge for an hour and mostly never reach the origin, so they are never counted. That is also why a cached 200 carries no live counter: a per-client number inside a shared-cached body would be about whoever missed the cache. The live `RateLimit` header appears on the responses that are `no-store` — every error, and the 429, which also carries `Retry-After` in seconds.

Polling is the wrong shape for this site anyway. It is 10 pages that change a few times a year; [https://www.heydenys.com/llms-full.txt](https://www.heydenys.com/llms-full.txt) is all of them in one request.

## From the command line

There is a one-file client, no install and no dependencies:

```
curl -fsSL https://www.heydenys.com/cli/heydenys.mjs -o heydenys.mjs
node heydenys.mjs profile
node heydenys.mjs page fitline
node heydenys.mjs read
```

It calls the pinned base, honours `Retry-After`, and prints the API's own error hints. Node 18 or newer. It is not on npm.

## OpenAPI

[https://www.heydenys.com/openapi.json](https://www.heydenys.com/openapi.json) — OpenAPI 3.1, with a unique operationId, a summary and a description on every operation, typed parameters and a response schema for every status, which is what makes it usable as a function-calling tool definition. The same document is served at https://www.heydenys.com/openapi.yaml and https://www.heydenys.com/api/openapi.json, and every page advertises it with `rel="service-desc"`. An agent holding nothing but the domain can also find all of it through the RFC 9727 catalogue at [https://www.heydenys.com/.well-known/api-catalog](https://www.heydenys.com/.well-known/api-catalog).

## Errors are JSON

Every non-2xx response under `/api` uses one envelope: `error.status`, `error.code` (stable, matchable), `error.message`, `error.hint` naming a call that would have worked, and `error.documentation`. A 404 from `/api/pages/{slug}` also carries every slug that does exist. The one exception is a Markdown read of a page that does not exist, which answers 404 in Markdown, listing every page that does.

## What this API is not

It is read-only and will stay that way. It publishes no availability, no rates and no contract terms — this site publishes none of those anywhere, so an answer inferred from it would be invented. Email me@heydenys.com for those.

---

Canonical HTML: https://www.heydenys.com/docs
Site overview for agents: https://www.heydenys.com/llms.txt
