···11+---
22+title: API Overview
33+description: XRPC endpoints served by your Hatk server.
44+---
55+66+Hatk serves [XRPC](https://atproto.com/specs/xrpc) endpoints at `/xrpc/{nsid}`. All built-in endpoints use the `dev.hatk` namespace.
77+88+## Protocol
99+1010+- **Queries** are GET requests with parameters in the query string
1111+- **Procedures** are POST requests with JSON (or binary) request bodies
1212+- All responses are JSON unless otherwise noted
1313+1414+## Authentication
1515+1616+Authenticated endpoints require an OAuth DPoP bearer token in the `Authorization` header:
1717+1818+```
1919+Authorization: DPoP <token>
2020+```
2121+2222+Configure OAuth in your `config.yaml` to enable authentication. See [Configuration](/getting-started/configuration).
2323+2424+## Client usage
2525+2626+The generated client provides typed methods for all endpoints:
2727+2828+```typescript
2929+// Query (GET)
3030+const result = await api.query('dev.hatk.getRecords', {
3131+ collection: 'fm.teal.alpha.feed.play',
3232+ limit: 10,
3333+})
3434+3535+// Procedure (POST)
3636+const result = await api.call('dev.hatk.createRecord', {
3737+ collection: 'fm.teal.alpha.feed.play',
3838+ repo: userDid,
3939+ record: { createdAt: new Date().toISOString() },
4040+})
4141+4242+// Upload binary data
4343+const result = await api.upload(file)
4444+```
4545+4646+## Built-in endpoints
4747+4848+| Endpoint | Type | Auth | Description |
4949+| ------------------------------------- | --------- | ---- | ------------------------------- |
5050+| [`getRecord`](/api/records) | Query | No | Fetch a single record by AT URI |
5151+| [`getRecords`](/api/records) | Query | No | List records with filters |
5252+| [`createRecord`](/api/records) | Procedure | Yes | Create a record via user's PDS |
5353+| [`putRecord`](/api/records) | Procedure | Yes | Create or update a record |
5454+| [`deleteRecord`](/api/records) | Procedure | Yes | Delete a record |
5555+| [`getFeed`](/api/feeds) | Query | No | Retrieve a named feed |
5656+| [`describeFeeds`](/api/feeds) | Query | No | List available feeds |
5757+| [`searchRecords`](/api/search) | Query | No | Full-text search |
5858+| [`uploadBlob`](/api/blobs) | Procedure | Yes | Upload a binary blob |
5959+| [`getPreferences`](/api/preferences) | Query | Yes | Get user preferences |
6060+| [`putPreference`](/api/preferences) | Procedure | Yes | Set a preference |
6161+| [`describeLabels`](/api/labels) | Query | No | List label definitions |
6262+| `describeCollections` | Query | No | List indexed collections |
···69697070---
71717272-See [Feeds guide](/guides/feeds/) for how to define feeds with `defineFeed()`.
7272+See [Feeds guide](/guides/feeds) for how to define feeds with `defineFeed()`.
-62
docs/site/src/content/docs/api/index.mdx
···11----
22-title: API Overview
33-description: XRPC endpoints served by your Hatk server.
44----
55-66-Hatk serves [XRPC](https://atproto.com/specs/xrpc) endpoints at `/xrpc/{nsid}`. All built-in endpoints use the `dev.hatk` namespace.
77-88-## Protocol
99-1010-- **Queries** are GET requests with parameters in the query string
1111-- **Procedures** are POST requests with JSON (or binary) request bodies
1212-- All responses are JSON unless otherwise noted
1313-1414-## Authentication
1515-1616-Authenticated endpoints require an OAuth DPoP bearer token in the `Authorization` header:
1717-1818-```
1919-Authorization: DPoP <token>
2020-```
2121-2222-Configure OAuth in your `config.yaml` to enable authentication. See [Configuration](/getting-started/configuration/).
2323-2424-## Client usage
2525-2626-The generated client provides typed methods for all endpoints:
2727-2828-```typescript
2929-// Query (GET)
3030-const result = await api.query('dev.hatk.getRecords', {
3131- collection: 'fm.teal.alpha.feed.play',
3232- limit: 10,
3333-})
3434-3535-// Procedure (POST)
3636-const result = await api.call('dev.hatk.createRecord', {
3737- collection: 'fm.teal.alpha.feed.play',
3838- repo: userDid,
3939- record: { createdAt: new Date().toISOString() },
4040-})
4141-4242-// Upload binary data
4343-const result = await api.upload(file)
4444-```
4545-4646-## Built-in endpoints
4747-4848-| Endpoint | Type | Auth | Description |
4949-| ------------------------------------- | --------- | ---- | ------------------------------- |
5050-| [`getRecord`](/api/records/) | Query | No | Fetch a single record by AT URI |
5151-| [`getRecords`](/api/records/) | Query | No | List records with filters |
5252-| [`createRecord`](/api/records/) | Procedure | Yes | Create a record via user's PDS |
5353-| [`putRecord`](/api/records/) | Procedure | Yes | Create or update a record |
5454-| [`deleteRecord`](/api/records/) | Procedure | Yes | Delete a record |
5555-| [`getFeed`](/api/feeds/) | Query | No | Retrieve a named feed |
5656-| [`describeFeeds`](/api/feeds/) | Query | No | List available feeds |
5757-| [`searchRecords`](/api/search/) | Query | No | Full-text search |
5858-| [`uploadBlob`](/api/blobs/) | Procedure | Yes | Upload a binary blob |
5959-| [`getPreferences`](/api/preferences/) | Query | Yes | Get user preferences |
6060-| [`putPreference`](/api/preferences/) | Procedure | Yes | Set a preference |
6161-| [`describeLabels`](/api/labels/) | Query | No | List label definitions |
6262-| `describeCollections` | Query | No | List indexed collections |
···34343535---
36363737-See [Labels guide](/guides/labels/) for how to define labels and hydrate them in responses.
3737+See [Labels guide](/guides/labels) for how to define labels and hydrate them in responses.
···3737 hatk start
3838 ```
39394040-See [Configuration](/getting-started/configuration/) for all available environment variables.
4040+See [Configuration](/getting-started/configuration) for all available environment variables.
···38383939### `config.yaml`
40404141-Main configuration — relay URL, database path, port, OAuth settings, backfill options, and more. See [Configuration](/getting-started/configuration/) for all options.
4141+Main configuration — relay URL, database path, port, OAuth settings, backfill options, and more. See [Configuration](/getting-started/configuration) for all options.
42424343### `package.json`
4444···89899090### `feeds/`
91919292-Feed generators using `defineFeed()`. Each file exports a feed with a `generate` function that queries DuckDB and returns record URIs, plus an optional `hydrate` function for enrichment. See [Feeds guide](/guides/feeds/).
9292+Feed generators using `defineFeed()`. Each file exports a feed with a `generate` function that queries DuckDB and returns record URIs, plus an optional `hydrate` function for enrichment. See [Feeds guide](/guides/feeds).
93939494```
9595feeds/
···98989999### `xrpc/`
100100101101-Custom XRPC endpoint handlers organized by namespace path. Each file uses `defineQuery()` or `defineProcedure()` and must have a matching lexicon. See [XRPC Handlers guide](/guides/xrpc-handlers/).
101101+Custom XRPC endpoint handlers organized by namespace path. Each file uses `defineQuery()` or `defineProcedure()` and must have a matching lexicon. See [XRPC Handlers guide](/guides/xrpc-handlers).
102102103103```
104104xrpc/
···108108109109### `og/`
110110111111-OpenGraph image routes using satori for server-side rendering. Each file exports a `path` and `generate()` function that returns a virtual DOM element. See [OpenGraph guide](/guides/opengraph/).
111111+OpenGraph image routes using satori for server-side rendering. Each file exports a `path` and `generate()` function that returns a virtual DOM element. See [OpenGraph guide](/guides/opengraph).
112112113113```
114114og/
···117117118118### `hooks/`
119119120120-Lifecycle hooks. Currently supports `on-login.ts`, which fires after a user authenticates via OAuth. The hook receives the user's `did` and an `ensureRepo` helper. See [Hooks guide](/guides/hooks/).
120120+Lifecycle hooks. Currently supports `on-login.ts`, which fires after a user authenticates via OAuth. The hook receives the user's `did` and an `ensureRepo` helper. See [Hooks guide](/guides/hooks).
121121122122```
123123hooks/
···126126127127### `labels/`
128128129129-Label definitions for content moderation. Each file exports a label definition with `evaluate()` logic. See [Labels guide](/guides/labels/).
129129+Label definitions for content moderation. Each file exports a label definition with `evaluate()` logic. See [Labels guide](/guides/labels).
130130131131```
132132labels/
···135135136136### `seeds/`
137137138138-Test fixture data. Contains a `seed.ts` that creates accounts and records against the local PDS during development. Run with `hatk seed` or automatically during `hatk dev`. See [Seeds guide](/guides/seeds/).
138138+Test fixture data. Contains a `seed.ts` that creates accounts and records against the local PDS during development. Run with `hatk seed` or automatically during `hatk dev`. See [Seeds guide](/guides/seeds).
139139140140```
141141seeds/
···190190 └── +page.svelte # OAuth redirect target
191191```
192192193193-The Vite plugin proxies API routes to the hatk backend during development. In production, `vite build` compiles to `public/`. See [Frontend guide](/guides/frontend/) for details.
193193+The Vite plugin proxies API routes to the hatk backend during development. In production, `vite build` compiles to `public/`. See [Frontend guide](/guides/frontend) for details.
194194195195### `test/`
196196···204204| `test/browser/` | Playwright browser tests |
205205| `test/fixtures/` | Shared test data and helpers |
206206207207-Run all tests with `hatk test`. See [Testing](/cli/testing/) for details.
207207+Run all tests with `hatk test`. See [Testing](/cli/testing) for details.
208208209209---
210210
···72727373When the user is logged in, requests include `Authorization: DPoP <token>` and a `DPoP` proof header. When logged out, it falls back to plain `fetch`.
74747575-See [OAuth](/guides/oauth/) for setting up `getAuthFetch()`.
7575+See [OAuth](/guides/oauth) for setting up `getAuthFetch()`.
76767777## Error handling
7878
···113113}
114114```
115115116116-Pass this to the [API client](/guides/api-client/) so all requests are authenticated when a user is logged in:
116116+Pass this to the [API client](/guides/api-client) so all requests are authenticated when a user is logged in:
117117118118```typescript
119119export const api = createClient<XrpcSchema>(origin, {
···180180 scope: atproto transition:generic
181181```
182182183183-See [Configuration](/getting-started/configuration/) for all OAuth options.
183183+See [Configuration](/getting-started/configuration) for all OAuth options.