# API Documentation — Recipe Manager

**Base URL:** `/api`

---

## Authentication

No authentication required for MVP (local/private use). Consider adding in v1.0.

---

## Endpoints

### Recipe Endpoints

#### List Recipes
- **GET `/api/recipes`**
  - Query params:
    - `search` *(string, optional)*: Filter recipes by title, description, or ingredients substring
    - `offset` *(integer, optional)*: Pagination offset (default: 0)
    - `limit` *(integer, optional)*: Pagination limit (default: 20)
  - Returns: `{ recipes: Recipe[], total: number }`

#### Get Single Recipe
- **GET `/api/recipes/:id`**
  - Path param: `id` (number)
  - Returns: `{ recipe: Recipe }`

#### Create Recipe
- **POST `/api/recipes`**
  - Body:
    ```json
    {
      "title": "Chocolate Cake",
      "ingredients": ["2 cups flour", "1 cup sugar"],
      "instructions": ["Mix dry ingredients", "Bake at 350°F for 30 min"],
      "tags": [1, 2], // optional tag IDs
      "servings": 8,  // optional
      "sourceUrl": "https://foosite.com/recipe", // optional
      "notes": "Best with dark chocolate"
    }
    ```
  - Returns: `{ recipe: Recipe }`

#### Update Recipe
- **PUT `/api/recipes/:id`**
  - Body: Same as POST
  - Returns: `{ recipe: Recipe }`

#### Delete Recipe
- **DELETE `/api/recipes/:id`**
  - Returns: `{ success: true }`

---

### Tag Endpoints

#### List Tags
- **GET `/api/tags`**
  - Returns: `{ tags: Tag[] }`

#### Create Tag
- **POST `/api/tags`**
  - Body:
    ```json
    { "name": "Dessert" }
    ```
  - Returns: `{ tag: Tag }`

#### Update Tag
- **PUT `/api/tags/:id`**
  - Body: `{ "name": "Lunch" }`
  - Returns: `{ tag: Tag }`

#### Delete Tag
- **DELETE `/api/tags/:id`**
  - Returns: `{ success: true }`

#### Assign Tag to Recipe
- **POST `/api/tags/recipes/:id/tags`
  - Body: `{ "tagId": 1 }`
  - Returns: `{ success: true }`

#### Remove Tag from Recipe
- **DELETE `/api/tags/recipes/:id/tags`
  - Body: `{ "tagId": 1 }`
  - Returns: `{ success: true }`

---

## Data Models

### Recipe
```ts
interface Recipe {
  id: number;
  title: string;
  description?: string;
  ingredients: string[];
  instructions: string[];
  servings?: number;
  tags?: Tag[];
  sourceUrl?: string;
  notes?: string;
  createdAt: string; // ISO date
  updatedAt: string; // ISO date
}
```

### Tag
```ts
interface Tag {
  id: number;
  name: string;
}
```

---

## Errors

Responses follow the pattern:
```json
{
  "success": false,
  "error": "Description of error"
}
```

Validation errors will return HTTP 400 with detailed messages.

---

## Versioning

Current version: MVP v0.1 (2026-03-24)
Future versions may introduce breaking API changes (see ROADMAP.md).

---

_Last updated: 2026-03-24_