# How to Add New API Endpoints in CasaOS: v1 vs v2 Routes Explained

> Learn to add new API endpoints in CasaOS by understanding v1 route registration and v2 OpenAPI extensions. Master route creation for your CasaOS applications.

- Repository: [IceWhale/CasaOS](https://github.com/IceWhaleTech/CasaOS)
- Tags: how-to-guide
- Published: 2026-06-27

---

**To add new API endpoints in CasaOS, register Echo handlers manually in [`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go) for the legacy v1 layer, or extend the OpenAPI specification and implement the generated `ServerInterface` methods for the modern v2 layer.**

CasaOS is an open-source home cloud system that exposes two parallel HTTP API routing layers. When you need to add new API endpoints in CasaOS, you must understand the architectural differences between the hand-written **v1** Echo router and the code-generated **v2** OpenAPI server, as each requires a distinct implementation workflow.

## Understanding CasaOS API Architecture (v1 vs v2)

CasaOS maintains two simultaneous API versions with different technical implementations:

### v1 (Echo) Routing Layer

The **v1** API uses explicit Echo framework routing. Each endpoint is registered manually in the `InitV1Router()` function found in [`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go). Handler files reside in `route/v1/*.go` (e.g., [`route/v1/file.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/file.go), [`route/v1/system.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/system.go)) and follow standard Echo handler signatures: `func(echo.Context) error`.

### v2 (OpenAPI-generated) Routing Layer

The **v2** API is generated from an OpenAPI specification. The router builds automatically from a `ServerInterface` implementation provided by the `CasaOS` struct in [`route/v2/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/route.go). After modifying the spec in [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml), you run the code generator to create new interface methods, which you then implement in the `CasaOS` receiver.

## Adding Endpoints to the CasaOS v1 API

To add a new endpoint to the legacy v1 layer, follow the manual registration pattern used by existing handlers.

### Step 1: Create the Handler Function

Create a new file in `route/v1/` or add to an existing handler file. The function must accept `echo.Context` and return an error.

```go
// route/v1/hello.go
package v1

import "github.com/labstack/echo/v4"

// Hello returns a simple greeting for v1 clients.
func Hello(c echo.Context) error {
    return c.String(200, "Hello from CasaOS v1")
}

```

### Step 2: Register the Route in InitV1Router

Edit [`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go) to wire your handler to a path inside the `InitV1Router()` function.

```go
// route/v1/route.go
func InitV1Router(e *echo.Echo) {
    v1Group := e.Group("/v1")
    {
        // ... existing routes ...
        v1Group.GET("/hello", Hello)  // ← new endpoint registration
    }
}

```

No code generation is required. Rebuild the binary to expose the new endpoint.

## Adding Endpoints to the CasaOS v2 API

The v2 layer requires a contract-first approach using OpenAPI code generation.

### Step 1: Extend the OpenAPI Specification

Add your new path and operation to the specification file, typically located at [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml).

```yaml

# codegen/openapi.yaml

paths:
  /hello:
    get:
      summary: Simple greeting
      responses:
        '200':
          description: Greeting text
          content:
            text/plain:
              schema:
                type: string

```

### Step 2: Regenerate the Server Code

Run the repository's code generation command to update the `ServerInterface` and router wiring.

```bash
make codegen

# or: go generate ./...

```

This creates a new method signature in the generated `ServerInterface` type (e.g., `GetHello(ctx echo.Context) error`) and updates the automatic routing logic.

### Step 3: Implement the Generated Interface Method

Create or edit a file in `route/v2/` to implement the method on the `CasaOS` struct. The method name matches the generated interface.

```go
// route/v2/hello.go
package v2

import "github.com/labstack/echo/v4"

// GetHello implements the ServerInterface method generated from openapi.yaml.
func (c *CasaOS) GetHello(ctx echo.Context) error {
    return ctx.String(200, "Hello from CasaOS v2")
}

```

The generated router automatically maps `/v2/hello` to your `GetHello` method using the spec-defined HTTP method and path.

## Choosing Between v1 and v2 for New Endpoints

Consider these factors when deciding which layer to extend:

- **Deployment speed**: **v1** allows rapid prototyping without build-time code generation. **v2** requires regenerating server stubs after every OpenAPI change.
- **API contract stability**: **v2** guarantees consistency between the specification and implementation, making it ideal for external client integrations. **v1** relies on manual documentation.
- **Client compatibility**: Most existing CasaOS UI and integrations still consume **v1** endpoints. Newer official clients (e.g., mobile apps) target **v2**.
- **Maintenance burden**: **v1** handlers are isolated, while **v2** changes require synchronizing the spec, generated code, and implementation.

Use **v1** for internal tooling or temporary endpoints. Use **v2** for production-grade features that require versioned, documented contracts.

## Complete Code Examples

### v1 Example: Adding a /hello Endpoint

Handler implementation in [`route/v1/hello.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/hello.go):

```go
package v1

import "github.com/labstack/echo/v4"

func Hello(c echo.Context) error {
    return c.String(200, "Hello from CasaOS v1")
}

```

Registration in [`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go):

```go
v1Group := e.Group("/v1")
{
    v1Group.GET("/hello", Hello)
}

```

### v2 Example: Adding a /hello Endpoint

OpenAPI specification fragment in [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml):

```yaml
/hello:
  get:
    summary: Simple greeting
    responses:
      '200':
        description: Greeting
        content:
          text/plain:
            schema:
              type: string

```

Implementation in [`route/v2/hello.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/hello.go):

```go
package v2

import "github.com/labstack/echo/v4"

func (c *CasaOS) GetHello(ctx echo.Context) error {
    return ctx.String(200, "Hello from CasaOS v2")
}

```

## Key Files and Locations

- **[`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go)** – Echo router bootstrap where v1 endpoints are explicitly linked to handlers via `InitV1Router()`.
- **`route/v1/*.go`** – Concrete v1 handler implementations (e.g., [`file.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/file.go), [`system.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/system.go)).
- **[`route/v2/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/route.go)** – Provides the `ServerInterface` implementation through the `CasaOS` struct for the generated v2 router.
- **[`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml)** – Source OpenAPI specification that drives v2 code generation.
- **`codegen/*`** – Auto-generated server code containing the `ServerInterface` type and automatic router wiring.
- **`service/*`** – Business logic services consumed by both v1 and v2 handlers (e.g., [`service/file_upload.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/file_upload.go)).

## Summary

- **For v1**: Write a standard Echo handler function and register it manually in `InitV1Router()` inside [`route/v1/route.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v1/route.go).
- **For v2**: Extend [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml), run `make codegen`, and implement the resulting method on the `CasaOS` struct in `route/v2/`.
- Both API versions coexist in CasaOS, allowing you to select the appropriate layer based on your need for rapid development versus API contract stability.

## Frequently Asked Questions

### Can I mix v1 and v2 endpoints in the same CasaOS build?

Yes, both routing layers run simultaneously. The v1 router mounts under `/v1` and the generated v2 router mounts under `/v2`, allowing gradual migration of functionality between versions without breaking existing clients.

### Do I need to regenerate code for every v2 API change?

You only need to regenerate code when you modify the OpenAPI specification in [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml). If you are only changing the implementation logic within the existing interface methods, a standard `go build` suffices.

### Which API version should I use for new features?

Use **v2** for production-grade features that require API contract stability and external client support. Use **v1** only for internal tooling, rapid prototypes, or when integrating with legacy CasaOS UI components that exclusively consume v1 routes.

### Where is the OpenAPI specification located for v2 routes?

The specification is located at [`codegen/openapi.yaml`](https://github.com/IceWhaleTech/CasaOS/blob/main/codegen/openapi.yaml) (or the specific YAML file referenced by the `codegen` package in your CasaOS checkout), which serves as the single source of truth for the v2 API contract.