# Contract: Books API **Base path**: `/api/v1/books` **Auth**: HTTP Basic (shared credential) required on all endpoints. --- ## POST /api/v1/books Upload a new book for embedding. **Request**: `multipart/form-data` | Field | Type | Required | Notes | |-------|------|----------|-------| | file | File | Yes | PDF only; max 100 MB | **Response 202 Accepted**: ```json { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Principles of Neurosurgery", "fileName": "principles-of-neurosurgery.pdf", "status": "PENDING", "uploadedAt": "2026-03-31T10:00:00Z" } ``` **Response 400 Bad Request** (unsupported format): ```json { "error": "Only PDF files are accepted." } ``` **Response 413 Payload Too Large**: ```json { "error": "File exceeds maximum size of 100 MB." } ``` --- ## GET /api/v1/books List all uploaded books with their current processing status. **Response 200 OK**: ```json [ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "title": "Principles of Neurosurgery", "fileName": "principles-of-neurosurgery.pdf", "fileSizeBytes": 45234567, "pageCount": 842, "status": "READY", "uploadedAt": "2026-03-31T10:00:00Z", "processedAt": "2026-03-31T10:07:23Z" } ] ``` --- ## GET /api/v1/books/{id} Get status and metadata for a single book. **Path param**: `id` — UUID **Response 200 OK**: Same shape as a single item in the list above, plus optional `errorMessage` field when `status = FAILED`. **Response 404 Not Found**: ```json { "error": "Book not found." } ``` --- ## DELETE /api/v1/books/{id} Delete a book and all its embedding chunks. **Response 204 No Content**: Book deleted. **Response 404 Not Found**: ```json { "error": "Book not found." } ``` **Response 409 Conflict** (book currently processing): ```json { "error": "Cannot delete a book that is currently being processed." } ``` --- ## Status Lifecycle ``` PENDING → returned immediately after upload PROCESSING → set when embedding pipeline starts READY → set when all chunks are embedded FAILED → set on any unrecoverable error; errorMessage populated ```