---
title: "Contributing to the API"
description: "How to add or change an endpoint and keep these docs in sync."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.deathspot.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributing to the API

The API reference on this site is generated from one OpenAPI file,
[`developer-docs/src/api/openapi.yaml`](https://github.com/mwanjajoel/deathspot/blob/main/developer-docs/src/api/openapi.yaml).
**If you change the API, change the spec in the same pull request.**

## Where things live

| Concern | Path |
| --- | --- |
| Route handlers | `app/api/**/route.ts` (Next.js App Router) |
| Input validation | `lib/validation.ts` (zod) |
| Data access | `lib/db.ts` (supabase-js) |
| Database schema, RLS and functions | `supabase/migrations/*.sql` |
| Rate limits and visitor hashing | `lib/rate-limit.ts` (`RATE_LIMITS`) |
| Search (spots, places, nearby) | `lib/search.ts` |
| Tests | `test/unit/`, `test/integration/` (Vitest) |
| API spec | `developer-docs/src/api/openapi.yaml` |
| Guides (this site) | `developer-docs/src/content/docs/*.mdx` |

## Adding an endpoint

1. **Validate input** with a zod schema in `lib/validation.ts`. Keep limits in sync with
   database `check` constraints.
2. **Write to the database through a Postgres function**, not a direct table write. Public
   writes use `security definer` functions that only the `service_role` can execute. Add them
   in a **new** numbered migration; never edit an applied one.
3. **Rate-limit** the handler by wrapping it: `export const GET = withRateLimit("read", async (req) => …)`.
   Add a policy to `RATE_LIMITS` if none fits, and document it in [Rate limits](/rate-limits).
4. **Return errors as `{ "error": string }`** with the right status code (see
   [Errors and limits](/errors-and-limits)).
5. **Document it** in `openapi.yaml`: summary, description, parameters, request body, and every
   response with an example. Reuse `components/schemas` and `components/responses`.
6. **Test it.** Add unit tests for pure logic and failure branches, and integration tests that
   call the route handler against the local stack. Coverage must stay at 100%:

```sh
   pnpm supabase:up
   pnpm test:coverage
```

7. **Preview the docs** and check the generated page and code samples:

```sh
   cd developer-docs
   pnpm install
   pnpm dev          # http://localhost:4321/api
```

## Writing guides

Guides are MDX files in `developer-docs/src/content/docs/`. Add the page to `sidebar.items` in
`developer-docs/nimbus.config.ts`. Components available in MDX are registered in
`src/components.ts`: `Aside`, `Card`, `CardGrid`, `Steps`, `Tabs`, `TabItem`, `PackageManagers`
and `Render`.

Before opening a PR:

```sh
pnpm exec nimbus-docs check   # config, links, MDX components, types
pnpm build                    # the full site, including the API reference
```

## Agent-friendly by default

Nimbus publishes a Markdown version of every page (append `index.md` to any URL), plus
`/llms.txt`, `/api/llms.txt` and `/llms-full.txt`. Coding assistants can read the whole API
in one request.

Source: https://docs.deathspot.org/contributing/index.mdx
