> For the complete documentation index, see [llms.txt](https://docs.novel.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.novel.dev/guides/knowledge-base/novel-server/creating-a-rest-endpoint.md).

# Creating a REST Endpoint

## Using `novel new api`

You can use the scaffolding CLI to generate a rest endpoint for you. This is the easiest way to create a REST endpoint.

{% embed url="<https://docs.novel.dev/novel-server/novel-cli/novel-new#novel-new-api>" %}

```sh
novel new api
```

Follow the instructions and your new API should be in `/app/api`.

## Manual Creation

{% stepper %}
{% step %}

### Create a new directory in `` `/app/api` ``

Create a new directory with the kebab-case format that identifies the function of the endpoint uniquely.&#x20;

A good format is \[subject]-\[action]

Examples:&#x20;

* user-create
* post-search
  {% endstep %}

{% step %}

### Create a new index.js or index.ts file inside the directory

Copy the template file below

{% code title="/app/api/user-create/index.ts" lineNumbers="true" %}

```typescript
export default function Handler(instance) {
    instance.post('/your/endpoint', handler);

    async function handler(request, reply) {
        // your logic
    }
}
```

{% endcode %}

{% embed url="<https://docs.novel.dev/novel-server/routing>" %}
{% endstep %}

{% step %}

### Restart Novel

New endpoints are not picked up by the server hot reload. You will need to restart the novel dev server
{% endstep %}
{% endstepper %}

***

## Enhancements

### Routing Options

{% embed url="<https://fastify.dev/docs/latest/Reference/Routes/#routes-options>" %}

### Using OpenAPI&#x20;

You can generate OpenAPI schemas based on Fastify's validation and serialization model

{% embed url="<https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/>" %}

{% code title="/app/api/user-create/schema.json" lineNumbers="true" %}

```json
{
    "body": {
        "type": "object",
        "properties": {
            "id": {
                "type": "string"
            }
        }
    }
}
```

{% endcode %}

This is automatically loaded into your route.

### Validation

Because of Fastify's validation model, request input is already controlled on a framework level. If you prefer to validate further, you can make use of `zod` internally like so:

{% embed url="<https://zod.dev/?id=basic-usage>" %}

{% code title="/app/api/user-create/index.ts" lineNumbers="true" %}

```typescript
import Accounts from 'novel/models/accounts';
import { z } from 'zod';

export default function Handler(instance) {
    instance.post('/your/endpoint', handler);

    async function handler(request, reply) {
        if (Accounts.z.safeParse(request.body)) {
            // your logic
        }
        if (z.safeParse(request.body)) {
            // your logic
        }
    }
}
```

{% endcode %}

{% embed url="<https://docs.novel.dev/novel-server/validation>" %}

{% embed url="<https://docs.novel.dev/novel-server/models#validations>" %}

### Route Directives

You can apply authentication, throttling, and other tools via Novel's route directives.

{% embed url="<https://docs.novel.dev/novel-server/routing/route-directives>" %}
