# API Contracts - keep-notes (Memento Web App) ## Overview The keep-notes web application exposes REST API endpoints via Next.js App Router. All endpoints return JSON responses with a consistent format. **Base URL:** `/api` **Authentication:** NextAuth session-based (required for most endpoints) **Response Format:** ```json { "success": true|false, "data": any, "error": string // only present when success: false } ``` --- ## Notes Endpoints ### GET /api/notes Get all notes with optional filtering. **Authentication:** Not required (currently) **Query Parameters:** - `archived` (boolean, optional): Include archived notes. Default: `false` - `search` (string, optional): Search in title and content (case-insensitive) **Response (200 OK):** ```json { "success": true, "data": [ { "id": "clxxxxxxx", "title": "string or null", "content": "string", "color": "default|red|orange|yellow|green|teal|blue|purple|pink|gray", "isPinned": boolean, "isArchived": boolean, "type": "text|checklist", "checkItems": [ { "id": "string", "text": "string", "checked": boolean } ] | null, "labels": ["string"] | null, "images": ["string"] | null, "reminder": "ISO8601 datetime" | null, "isReminderDone": boolean, "reminderRecurrence": "none|daily|weekly|monthly|custom" | null, "reminderLocation": "string" | null, "isMarkdown": boolean, "size": "small|medium|large", "embedding": "JSON string" | null, "order": number, "createdAt": "ISO8601 datetime", "updatedAt": "ISO8601 datetime" } ] } ``` **Error Response (500):** ```json { "success": false, "error": "Failed to fetch notes" } ``` --- ### POST /api/notes Create a new note. **Authentication:** Not required (currently) **Request Body:** ```json { "title": "string (optional)", "content": "string (required unless type=checklist)", "color": "string (optional, default: 'default')", "type": "text|checklist (optional, default: 'text')", "checkItems": [ { "id": "string", "text": "string", "checked": boolean } ] (optional), "labels": ["string"] (optional), "images": ["string"] (optional, base64 encoded) } ``` **Response (201 Created):** ```json { "success": true, "data": { /* note object */ } } ``` **Error Responses:** - `400 Bad Request`: Content is required - `500 Internal Server Error`: Failed to create note --- ### PUT /api/notes Update an existing note. **Authentication:** Not required (currently) **Request Body:** ```json { "id": "string (required)", "title": "string (optional)", "content": "string (optional)", "color": "string (optional)", "type": "text|checklist (optional)", "checkItems": [...] (optional), "labels": ["string"] (optional), "isPinned": boolean (optional), "isArchived": boolean (optional), "images": ["string"] (optional) } ``` **Response (200 OK):** ```json { "success": true, "data": { /* updated note object */ } } ``` **Error Responses:** - `400 Bad Request`: Note ID is required - `500 Internal Server Error`: Failed to update note --- ### DELETE /api/notes?id=xxx Delete a note by ID. **Authentication:** Not required (currently) **Query Parameters:** - `id` (string, required): Note ID **Response (200 OK):** ```json { "success": true, "message": "Note deleted successfully" } ``` **Error Responses:** - `400 Bad Request`: Note ID is required - `500 Internal Server Error`: Failed to delete note --- ## Labels Endpoints ### GET /api/labels Get all labels for the authenticated user. **Authentication:** Required (NextAuth session) **Response (200 OK):** ```json { "success": true, "data": [ { "id": "clxxxxxxx", "name": "string", "color": "red|orange|yellow|green|teal|blue|purple|pink|gray", "userId": "string", "createdAt": "ISO8601 datetime", "updatedAt": "ISO8601 datetime" } ] } ``` **Error Response (401 Unauthorized):** ```json { "error": "Unauthorized" } ``` --- ### POST /api/labels Create a new label. **Authentication:** Required (NextAuth session) **Request Body:** ```json { "name": "string (required)", "color": "string (optional, random color if not provided)" } ``` **Response (200 OK):** ```json { "success": true, "data": { /* label object */ } } ``` **Error Responses:** - `400 Bad Request`: Label name is required - `401 Unauthorized`: Not authenticated - `409 Conflict`: Label already exists for this user - `500 Internal Server Error`: Failed to create label --- ### DELETE /api/labels/{id} Delete a label by ID. **Authentication:** Required (NextAuth session) **URL Parameters:** - `id` (string): Label ID **Response (200 OK):** ```json { "success": true, "message": "Label deleted successfully" } ``` **Error Responses:** - `401 Unauthorized`: Not authenticated - `500 Internal Server Error`: Failed to delete label --- ## Authentication Endpoints ### GET/POST /api/auth/[...nextauth] NextAuth.js authentication handler. **Authentication:** Not required (this is the auth endpoint) All NextAuth operations are handled by this route: - Sign in - Sign out - Session management - OAuth callbacks - Email verification **Implementation:** Delegates to `@/auth` configuration --- ## AI Endpoints ### POST /api/ai/tags Generate intelligent tags for a note using AI. **Authentication:** Not specified (likely required) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ### POST /api/ai/test Test AI integration. **Authentication:** Not specified (likely required) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ## Admin Endpoints ### POST /api/admin/randomize-labels Randomize label colors (admin functionality). **Authentication:** Required (admin role) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ### POST /api/admin/sync-labels Synchronize labels across the system (admin functionality). **Authentication:** Required (admin role) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ## Upload Endpoint ### POST /api/upload Upload files (e.g., images for notes). **Authentication:** Not specified **Request Body:** multipart/form-data **Response:** (to be determined from implementation) --- ## Cron/Reminder Endpoint ### POST /api/cron/reminders Scheduled job for handling reminders. **Authentication:** Not required (cron job) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ## Debug Endpoints ### POST /api/debug/search Debug search functionality. **Authentication:** Not specified (admin/debug only) **Request Body:** (to be determined from implementation) **Response:** (to be determined from implementation) --- ## Data Models ### Note Model (Prisma) ```prisma model Note { id String @id @default(cuid()) title String? content String color String @default("default") isPinned Boolean @default(false) isArchived Boolean @default(false) type String @default("text") checkItems String? // JSON array labels String? // JSON array images String? // JSON array links String? // JSON array reminder DateTime? isReminderDone Boolean @default(false) reminderRecurrence String? reminderLocation String? isMarkdown Boolean @default(false) size String @default("small") embedding String? // JSON vector userId String? user User? @relation(fields: [userId], references: [id]) order Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([isPinned]) @@index([isArchived]) @@index([order]) @@index([reminder]) @@index([userId]) } ``` ### Label Model (Prisma) ```prisma model Label { id String @id @default(cuid()) name String color String @default("gray") userId String? user User? @relation(fields: [userId], references: [id]) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([name, userId]) @@index([userId]) } ``` ### User Model (Prisma) ```prisma model User { id String @id @default(cuid()) name String? email String @unique emailVerified DateTime? password String? role String @default("USER") image String? theme String @default("light") resetToken String? @unique resetTokenExpiry DateTime? accounts Account[] sessions Session[] notes Note[] labels Label[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } ``` --- ## Notes - **State Management**: Server actions and API routes (no dedicated state management library detected) - **Database**: SQLite via Prisma ORM with better-sqlite3 adapter - **Authentication**: NextAuth.js v5 with Prisma adapter - **Error Handling**: All endpoints return consistent error format - **JSON Parsing**: Arrays (checkItems, labels, images) stored as JSON strings in DB, parsed in API layer - **Ordering**: Notes sorted by `isPinned DESC`, then `order ASC`, then `updatedAt DESC` - **Search**: Case-insensitive search across title and content fields