# API Specification

## Overview

QuickNotes provides a RESTful API for communication between the frontend and backend. The API is built using the Gin web framework and follows REST principles.

## Base URL

All API endpoints are prefixed with `/api`.

## Authentication

The API does not currently implement authentication as it is designed for local use.

## Response Format

API responses are formatted as JSON with the following structure:

- For successful responses returning data:
  ```json
  {
    "field1": "value1",
    "field2": "value2",
    ...
  }
  ```

- For successful responses returning arrays:
  ```json
  [
    {
      "field1": "value1",
      "field2": "value2",
      ...
    },
    ...
  ]
  ```

- For error responses:
  ```json
  {
    "error": "Error message"
  }
  ```

## Status Codes

The API uses standard HTTP status codes:

- `200 OK`: The request was successful
- `400 Bad Request`: The request was invalid
- `404 Not Found`: The requested resource was not found
- `500 Internal Server Error`: An error occurred on the server

## Endpoints

### Notes

#### List Notes

- **URL**: `/api/notes`
- **Method**: `GET`
- **Description**: Get a list of all notes
- **Response**: Array of Note objects
  ```json
  [
    {
      "id": "note-id",
      "title": "Note Title",
      "content": "Note content in Markdown",
      "createdAt": "2023-01-01T12:00:00Z",
      "updatedAt": "2023-01-01T12:00:00Z"
    },
    ...
  ]
  ```

#### Create Note

- **URL**: `/api/notes`
- **Method**: `POST`
- **Description**: Create a new note
- **Request Body**: Note object without ID
  ```json
  {
    "title": "Note Title",
    "content": "Note content in Markdown"
  }
  ```
- **Response**: Created Note object with ID
  ```json
  {
    "id": "note-id",
    "title": "Note Title",
    "content": "Note content in Markdown",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2023-01-01T12:00:00Z"
  }
  ```

#### Get Note

- **URL**: `/api/notes/:id`
- **Method**: `GET`
- **Description**: Get a specific note by ID
- **URL Parameters**: `id` - ID of the note
- **Response**: Note object
  ```json
  {
    "id": "note-id",
    "title": "Note Title",
    "content": "Note content in Markdown",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2023-01-01T12:00:00Z",
    "linksTo": [
      {
        "id": "linked-note-id",
        "title": "Linked Note Title"
      }
    ],
    "linkedBy": [
      {
        "id": "linking-note-id",
        "title": "Linking Note Title"
      }
    ]
  }
  ```

#### Update Note

- **URL**: `/api/notes/:id`
- **Method**: `PUT`
- **Description**: Update a specific note
- **URL Parameters**: `id` - ID of the note
- **Request Body**: Note object with updated fields
  ```json
  {
    "title": "Updated Title",
    "content": "Updated content"
  }
  ```
- **Response**: Updated Note object
  ```json
  {
    "id": "note-id",
    "title": "Updated Title",
    "content": "Updated content",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2023-01-02T12:00:00Z"
  }
  ```

#### Delete Note

- **URL**: `/api/notes/:id`
- **Method**: `DELETE`
- **Description**: Delete a specific note
- **URL Parameters**: `id` - ID of the note
- **Response**: Empty response with status code 200

#### Import Obsidian Vault

- **URL**: `/api/notes/import`
- **Method**: `POST`
- **Description**: Import notes from an Obsidian vault
- **Request Body**: Multipart form with a `file` field containing the zip file
- **Response**: Import result
  ```json
  {
    "imported": 42
  }
  ```

### Readlist

#### List Read Later Items

- **URL**: `/api/readlist`
- **Method**: `GET`
- **Description**: Get a list of all read later items
- **Query Parameters**:
  - `status` - Filter by status (`read`, `unread`, `archived`, `unarchived`)
- **Response**: Array of ReadLaterItem objects
  ```json
  [
    {
      "id": "item-id",
      "url": "https://example.com/article",
      "title": "Article Title",
      "description": "Article description",
      "createdAt": "2023-01-01T12:00:00Z",
      "updatedAt": "2023-01-01T12:00:00Z",
      "readAt": null,
      "archivedAt": null
    },
    ...
  ]
  ```

#### Save Article

- **URL**: `/api/readlist`
- **Method**: `POST`
- **Description**: Save a new article
- **Request Body**: ReadLaterItem object with URL
  ```json
  {
    "url": "https://example.com/article"
  }
  ```
- **Response**: Created ReadLaterItem object
  ```json
  {
    "id": "item-id",
    "url": "https://example.com/article",
    "title": "Article Title",
    "content": "Article content in HTML",
    "description": "Article description",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2023-01-01T12:00:00Z",
    "readAt": null,
    "archivedAt": null
  }
  ```

#### Get Article

- **URL**: `/api/readlist/:id`
- **Method**: `GET`
- **Description**: Get a specific article by ID
- **URL Parameters**: `id` - ID of the article
- **Response**: ReadLaterItem object
  ```json
  {
    "id": "item-id",
    "url": "https://example.com/article",
    "title": "Article Title",
    "content": "Article content in HTML",
    "description": "Article description",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2023-01-01T12:00:00Z",
    "readAt": null,
    "archivedAt": null
  }
  ```

#### Mark as Read/Unread

- **URL**: `/api/readlist/:id/read` or `/api/readlist/:id/unread`
- **Method**: `PUT`
- **Description**: Mark an article as read or unread
- **URL Parameters**: `id` - ID of the article
- **Response**: Updated ReadLaterItem object

#### Archive/Unarchive

- **URL**: `/api/readlist/:id/archive` or `/api/readlist/:id/unarchive`
- **Method**: `PUT`
- **Description**: Archive or unarchive an article
- **URL Parameters**: `id` - ID of the article
- **Response**: Updated ReadLaterItem object

### Feeds

#### List Feeds

- **URL**: `/api/feeds`
- **Method**: `GET`
- **Description**: Get a list of all feeds
- **Response**: Array of Feed objects
  ```json
  [
    {
      "id": "feed-id",
      "title": "Feed Title",
      "url": "https://example.com/feed.xml",
      "description": "Feed description",
      "siteUrl": "https://example.com",
      "imageUrl": "https://example.com/logo.png",
      "lastFetched": "2023-01-01T12:00:00Z",
      "createdAt": "2023-01-01T12:00:00Z",
      "updatedAt": "2023-01-01T12:00:00Z"
    },
    ...
  ]
  ```

#### Subscribe to Feed

- **URL**: `/api/feeds`
- **Method**: `POST`
- **Description**: Subscribe to a new feed
- **Request Body**: Feed object with URL
  ```json
  {
    "url": "https://example.com/feed.xml"
  }
  ```
- **Response**: Created Feed object

#### List Entries

- **URL**: `/api/feeds/entries` or `/api/feeds/:id/entries`
- **Method**: `GET`
- **Description**: Get a list of entries from all feeds or a specific feed
- **URL Parameters**: `id` (optional) - ID of the feed
- **Query Parameters**:
  - `status` - Filter by status (`read`, `unread`)
  - `limit` - Maximum number of entries to return
  - `offset` - Offset for pagination
- **Response**: Array of Entry objects
  ```json
  [
    {
      "id": "entry-id",
      "feedId": "feed-id",
      "title": "Entry Title",
      "url": "https://example.com/article",
      "content": "Entry content in HTML",
      "summary": "Entry summary",
      "author": "Author Name",
      "published": "2023-01-01T12:00:00Z",
      "updated": "2023-01-01T12:00:00Z",
      "readAt": null,
      "createdAt": "2023-01-01T12:00:00Z",
      "updatedAt": "2023-01-01T12:00:00Z"
    },
    ...
  ]
  ```

#### Refresh Feeds

- **URL**: `/api/feeds/refresh` or `/api/feeds/:id/refresh`
- **Method**: `POST`
- **Description**: Refresh all feeds or a specific feed
- **URL Parameters**: `id` (optional) - ID of the feed
- **Response**: Refresh result
  ```json
  {
    "newEntries": 5
  }
  ```

## Error Handling

The API handles errors by returning appropriate HTTP status codes and error messages:

```json
{
  "error": "Detailed error message"
}
```

Common error scenarios:

1. **Invalid Input**: Returns 400 Bad Request
2. **Resource Not Found**: Returns 404 Not Found
3. **Server Error**: Returns 500 Internal Server Error

## Rate Limiting

The API does not currently implement rate limiting as it is designed for local use.

## Versioning

The API does not currently implement versioning. Future versions may include a version prefix in the URL path (e.g., `/api/v1/notes`).