---
title: API overview
description: One base URL, one key, and the whole surface on one page.
---

```
https://api.zevcontent.net
```

Every request carries `Authorization: Bearer <key>`, and the key selects the
project. There is no project id in any URL.

> **INFO: The API describes itself**
>
> `GET /v1/introspection` returns your project's whole contract as JSON: every
> type, every module, every endpoint and every convention, with the real numbers.
> It is generated from the code that serves the requests, so it cannot be out of
> date. See [Introspection](/api/introspection).

## The surface

### Custom content

| | |
|---|---|
| `GET /v1/content/{type}` | A singleton's values, or a paginated collection |
| `GET /v1/content/{type}/{entryId}` | One entry by id |
| `POST /v1/content/{type}/entries` | Create an entry *(secret key)* |
| `PUT /v1/content/{type}` | Save a singleton *(secret key)* |
| `GET /v1/schema/content-types` | Every type definition *(secret key)* |
| `PUT /v1/schema/content-types/{type}` | Create or update a type *(secret key)* |

See [Content](/api/content).

### Blog

| | |
|---|---|
| `GET /v1/blog/articles` | Published articles, newest first |
| `GET /v1/blog/articles/{slug}` | One article, with its body |
| `GET /v1/blog/categories` | Every category |
| `GET /v1/blog/categories/{slug}` | One category page |

See [Blog](/modules/blog).

### Knowledge base

| | |
|---|---|
| `GET /v1/kb/tree` | The navigation tree, sections nested |
| `GET /v1/kb/articles` | Published articles in reading order |
| `GET /v1/kb/articles/{slug}` | One article, with its body |
| `POST /v1/kb/articles/{slug}/vote` | Helpful / not helpful *(publishable key)* |

See [Knowledge base](/modules/knowledge-base).

### Authors

| | |
|---|---|
| `GET /v1/authors` | Every author |
| `GET /v1/authors/{slug}` | One author page |

See [Authors](/modules/authors).

### Utility

| | |
|---|---|
| `GET /v1/introspection` | The whole project, described |
| `GET /v1/ping` | Confirms a key resolves |

## Conventions that hold everywhere

- **[Authentication](/api/authentication)**: two key kinds, and what each may do.
- **[Pagination and filtering](/api/pagination)**: every listing pages; nothing returns everything.
- **[Rate limits](/api/rate-limits)**: three separate budgets, counted per key.
- **[Errors](/api/errors)**: one envelope, and messages written to be acted on.

## The response envelope

A single item:

```json
{ "data": { … }, "meta": { … } }
```

A listing:

```json
{ "data": [ … ], "meta": { "limit": 20, "has_more": true, "next_offset": 20, "next_cursor": null } }
```

`meta` on a built-in module also carries `module` and `release_independent`, so
a caller inspecting a payload can tell what it is looking at without matching
on the URL it asked for.

## Stability

These URLs and these keys end up in static builds and mobile releases we do not
control, so the rule is **additive only**: new keys may appear, existing ones do
not change meaning and do not disappear.

Two consequences worth knowing:

- A listing omits `body`, and always will. Adding it later would be additive;
  removing it would not, which is why it starts absent.
- `authors` and `categories` are arrays with no singular `author`/`category`
  beside them. Two names for one thing is how a contract rots.