# How to Customize Endpoint Names in FastCRUD's crud_router: A Complete Guide

> Customize endpoint names in FastCRUD crud_router easily. Map operation keys to custom path segments for flexible API routing beyond default REST conventions. Learn more.

- Repository: [Benav Labs/fastcrud](https://github.com/benavlabs/fastcrud)
- Tags: how-to-guide
- Published: 2026-02-26

---

**You can customize endpoint names in `crud_router` by passing an `endpoint_names` dictionary that maps operation keys like `"create"`, `"read"`, and `"delete"` to your desired URL path segments, allowing you to override the default REST conventions used by the `benavlabs/fastcrud` library.**

The `crud_router` function in FastCRUD automatically generates FastAPI routes for your SQLAlchemy models. By default, it creates standard REST endpoints, but you can fully customize the URL structure using the `endpoint_names` parameter to match your API's naming conventions or legacy requirements.

## Understanding the endpoint_names Parameter

The `endpoint_names` parameter accepts a dictionary where keys represent CRUD operations and values define the URL path segment for that operation. The supported keys are:

- `"create"` – POST endpoint for creating records
- `"read"` – GET endpoint for retrieving a single record
- `"update"` – PATCH/PUT endpoint for modifying records
- `"delete"` – DELETE endpoint for soft deletes
- `"db_delete"` – DELETE endpoint for hard/permanent deletes
- `"read_multi"` – GET endpoint for listing multiple records

### Default Endpoint Name Behavior

According to the source code in [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py) (lines 28-36), the `EndpointCreator` class defines the following default mapping:

```python
self.default_endpoint_names = {
    "create": "",
    "read": "",
    "update": "",
    "delete": "",
    "db_delete": "db_delete",
    "read_multi": "",
}

```

Most operations default to an empty string, meaning they use the base path directly (e.g., `/tasks`). Only `db_delete` has a non-empty default of `"db_delete"` (resulting in `/tasks/db_delete/{id}`).

## How Endpoint Names Are Resolved in the Source Code

The actual path resolution occurs in the `_get_endpoint_path` method within [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py) (lines 52-57). This method merges your custom `endpoint_names` with the defaults and constructs the final URL:

```python
endpoint_name = self.endpoint_names.get(
    operation, self.default_endpoint_names.get(operation, operation)
)
path = f"{self.path}/{endpoint_name}" if endpoint_name else self.path

```

For operations that involve primary keys (`read`, `update`, `delete`, and `db_delete`), the router automatically appends the primary key parameters after the operation segment (lines 58-63). This results in paths like `/tasks/custom_name/{id}`.

## Practical Examples for Customizing Endpoint Names

### Basic Usage with Custom Names

To completely rename all endpoints for a task management API, pass a comprehensive `endpoint_names` dictionary to `crud_router`:

```python
from fastapi import FastAPI
from fastcrud import crud_router
from .database import async_session
from .models import Task
from .schemas import CreateTaskSchema, UpdateTaskSchema

app = FastAPI()

task_router = crud_router(
    session=async_session,
    model=Task,
    create_schema=CreateTaskSchema,
    update_schema=UpdateTaskSchema,
    path="/tasks",
    tags=["Task Management"],
    endpoint_names={
        "create": "add_task",
        "read": "get_task",
        "update": "modify_task",
        "delete": "remove_task",
        "db_delete": "permanently_remove_task",
        "read_multi": "list_tasks",
    },
)

app.include_router(task_router)

```

This configuration generates the following routes:

- `POST /tasks/add_task` – Create a task
- `GET /tasks/get_task/{id}` – Retrieve a single task
- `PATCH /tasks/modify_task/{id}` – Update a task
- `DELETE /tasks/remove_task/{id}` – Soft delete a task
- `DELETE /tasks/permanently_remove_task/{id}` – Hard delete a task
- `GET /tasks/list_tasks` – List all tasks

### Customizing Only Specific Operations

You can override only the operations you care about while keeping the defaults for others. This example customizes only the creation and listing endpoints:

```python
user_router = crud_router(
    session=async_session,
    model=User,
    create_schema=CreateUserSchema,
    update_schema=UpdateUserSchema,
    path="/users",
    tags=["Users"],
    endpoint_names={
        "create": "register",
        "read_multi": "search",
    },
)

```

This generates:

- `POST /users/register` – Create user (custom)
- `GET /users/{id}` – Read user (default)
- `PATCH /users/{id}` – Update user (default)
- `GET /users/search` – List users (custom)

### Mixing Custom and Default Names

When you want most endpoints to use the base path but need specific exceptions, provide an empty string for defaults and custom strings for exceptions:

```python
order_router = crud_router(
    session=async_session,
    model=Order,
    create_schema=CreateOrderSchema,
    update_schema=UpdateOrderSchema,
    path="/orders",
    tags=["Orders"],
    endpoint_names={
        "read_multi": "list",   # Custom: /orders/list

        # All others default to empty string → /orders

    },
)

```

This configuration results in:

- `POST /orders` – Create
- `GET /orders/{id}` – Read
- `PATCH /orders/{id}` – Update
- `GET /orders/list` – List all
- `DELETE /orders/{id}` – Soft delete
- `DELETE /orders/db_delete/{id}` – Hard delete (uses default `db_delete` suffix)

## Summary

- **Use the `endpoint_names` parameter** in `crud_router` to customize URL paths for CRUD operations.
- **Valid keys** include `"create"`, `"read"`, `"update"`, `"delete"`, `"db_delete"`, and `"read_multi"`.
- **Default behavior** uses empty strings for most operations (base path only) except `"db_delete"` which defaults to `"db_delete"`.
- **Path resolution** occurs in [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py) via the `_get_endpoint_path` method, which merges custom names with defaults.
- **Primary key routes** automatically append `/{pk}` after the custom endpoint name segment.

## Frequently Asked Questions

### What are the valid keys for the endpoint_names dictionary?

The `endpoint_names` dictionary accepts six string keys that correspond to the CRUD operations generated by FastCRUD: `"create"` (POST), `"read"` (GET single), `"update"` (PATCH/PUT), `"delete"` (soft DELETE), `"db_delete"` (hard DELETE), and `"read_multi"` (GET list). Each key maps to a string value that becomes the URL path segment for that operation.

### Can I use empty strings in endpoint_names?

Yes, empty strings are valid values and represent the default behavior where the operation uses the base path directly without any additional suffix. For example, setting `"create": ""` results in the endpoint `POST /tasks` (assuming your base path is `/tasks`). This is how FastCRUD handles most operations by default, except for `db_delete` which uses `"db_delete"` as its default suffix.

### How do primary key parameters affect custom endpoint paths?

For operations that target specific records (`read`, `update`, `delete`, and `db_delete`), FastCRUD automatically appends the primary key parameters to the end of the custom path segment. For example, if you set `"read": "fetch_item"`, the resulting route becomes `GET /tasks/fetch_item/{id}` rather than just `GET /tasks/fetch_item`. This behavior is hardcoded in the `_get_endpoint_path` method within [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py).

### Where is the endpoint name logic implemented in FastCRUD?

The core logic for resolving endpoint names resides in the `EndpointCreator` class located at [`fastcrud/endpoint/endpoint_creator.py`](https://github.com/benavlabs/fastcrud/blob/main/fastcrud/endpoint/endpoint_creator.py). Specifically, the `__init__` method (lines 28-36) handles the merging of user-provided `endpoint_names` with default values, while the `_get_endpoint_path` method (lines 52-63) constructs the final URL paths by looking up operation names in the merged dictionary and appending primary key segments where appropriate.