Implement Sprint 1: Notebook Management CRUD
- Add NotebookService with full CRUD operations
- Add POST /api/v1/notebooks (create notebook)
- Add GET /api/v1/notebooks (list with pagination)
- Add GET /api/v1/notebooks/{id} (get by ID)
- Add PATCH /api/v1/notebooks/{id} (partial update)
- Add DELETE /api/v1/notebooks/{id} (delete)
- Add Pydantic models for requests/responses
- Add custom exceptions (ValidationError, NotFoundError, NotebookLMError)
- Add comprehensive unit tests (31 tests, 97% coverage)
- Add API integration tests (26 tests)
- Fix router prefix duplication
- Fix JSON serialization in error responses
BREAKING CHANGE: None
9.8 KiB
API Endpoints Documentation
NotebookLM Agent API - Endpoint Reference
Version: 0.1.0
Base URL: http://localhost:8000
OpenAPI: /docs (Swagger UI)
Authentication
All API requests require an API key in the X-API-Key header:
X-API-Key: your-api-key-here
Example
curl http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-api-key"
Error Response (401 Unauthorized)
{
"success": false,
"error": {
"code": "AUTH_ERROR",
"message": "API key required",
"details": null
},
"meta": {
"timestamp": "2026-04-06T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Notebooks
Create Notebook
Create a new notebook.
Endpoint: POST /api/v1/notebooks
Request
curl -X POST http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "My Research Notebook",
"description": "A collection of AI research papers"
}'
Request Body:
{
"title": "string (required, min: 3, max: 100)",
"description": "string (optional, max: 500)"
}
Success Response (201 Created)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Research Notebook",
"description": "A collection of AI research papers",
"created_at": "2026-04-06T10:30:00Z",
"updated_at": "2026-04-06T10:30:00Z"
},
"meta": {
"timestamp": "2026-04-06T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Error Responses
400 Bad Request - Validation Error
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{
"field": "title",
"error": "Title must be at least 3 characters"
}
]
},
"meta": {
"timestamp": "2026-04-06T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
401 Unauthorized - Missing/Invalid API Key
{
"success": false,
"error": {
"code": "AUTH_ERROR",
"message": "API key required"
},
"meta": { ... }
}
502 Bad Gateway - NotebookLM API Error
{
"success": false,
"error": {
"code": "NOTEBOOKLM_ERROR",
"message": "External API error: rate limit exceeded"
},
"meta": { ... }
}
List Notebooks
List all notebooks with pagination.
Endpoint: GET /api/v1/notebooks
Request
# Basic request
curl http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-api-key"
# With pagination
curl "http://localhost:8000/api/v1/notebooks?limit=10&offset=0&sort=created_at&order=desc" \
-H "X-API-Key: your-api-key"
# Sort by title ascending
curl "http://localhost:8000/api/v1/notebooks?sort=title&order=asc" \
-H "X-API-Key: your-api-key"
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit |
integer | 20 | Max items per page (1-100) |
offset |
integer | 0 | Items to skip |
sort |
string | "created_at" | Sort field: created_at, updated_at, title |
order |
string | "desc" | Sort order: asc, desc |
Success Response (200 OK)
{
"success": true,
"data": {
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Research Notebook",
"description": "A collection of AI research papers",
"created_at": "2026-04-06T10:00:00Z",
"updated_at": "2026-04-06T10:30:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"title": "Another Notebook",
"description": null,
"created_at": "2026-04-06T09:00:00Z",
"updated_at": "2026-04-06T09:00:00Z"
}
],
"pagination": {
"total": 100,
"limit": 20,
"offset": 0,
"has_more": true
}
},
"meta": {
"timestamp": "2026-04-06T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Error Responses
401 Unauthorized - Missing/Invalid API Key
{
"success": false,
"error": {
"code": "AUTH_ERROR",
"message": "API key required"
},
"meta": { ... }
}
Get Notebook
Get a single notebook by ID.
Endpoint: GET /api/v1/notebooks/{notebook_id}
Request
curl http://localhost:8000/api/v1/notebooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: your-api-key"
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
notebook_id |
UUID | Notebook unique identifier |
Success Response (200 OK)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Research Notebook",
"description": "A collection of AI research papers",
"created_at": "2026-04-06T10:00:00Z",
"updated_at": "2026-04-06T10:30:00Z"
},
"meta": {
"timestamp": "2026-04-06T10:30:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Error Responses
404 Not Found - Notebook doesn't exist
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Notebook with id '550e8400-e29b-41d4-a716-446655440000' not found"
},
"meta": { ... }
}
400 Bad Request - Invalid UUID format
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid notebook ID format"
},
"meta": { ... }
}
Update Notebook
Update an existing notebook (partial update).
Endpoint: PATCH /api/v1/notebooks/{notebook_id}
Request
# Update title only
curl -X PATCH http://localhost:8000/api/v1/notebooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title"
}'
# Update description only
curl -X PATCH http://localhost:8000/api/v1/notebooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"description": "Updated description"
}'
# Update both
curl -X PATCH http://localhost:8000/api/v1/notebooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"description": "Updated description"
}'
Request Body:
{
"title": "string (optional, min: 3, max: 100)",
"description": "string (optional, max: 500)"
}
Note: Only provided fields are updated. At least one field must be provided.
Success Response (200 OK)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Title",
"description": "Updated description",
"created_at": "2026-04-06T10:00:00Z",
"updated_at": "2026-04-06T11:00:00Z"
},
"meta": {
"timestamp": "2026-04-06T11:00:00Z",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Error Responses
400 Bad Request - Validation Error
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{
"field": "title",
"error": "Title must be at least 3 characters"
}
]
},
"meta": { ... }
}
404 Not Found - Notebook doesn't exist
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Notebook with id '...' not found"
},
"meta": { ... }
}
Delete Notebook
Delete a notebook permanently.
Endpoint: DELETE /api/v1/notebooks/{notebook_id}
Request
curl -X DELETE http://localhost:8000/api/v1/notebooks/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: your-api-key"
Success Response (204 No Content)
Empty body.
Error Responses
404 Not Found - Notebook doesn't exist
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Notebook with id '...' not found"
},
"meta": { ... }
}
Note: This operation is idempotent. Deleting the same notebook twice returns 404 on the second attempt.
Common Workflows
Create and List Notebooks
# 1. Create a notebook
NOTEBOOK=$(curl -s -X POST http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "AI Research"}' | jq -r '.data.id')
# 2. List all notebooks
curl http://localhost:8000/api/v1/notebooks \
-H "X-API-Key: your-key"
# 3. Get specific notebook
curl http://localhost:8000/api/v1/notebooks/$NOTEBOOK \
-H "X-API-Key: your-key"
Update and Delete
NOTEBOOK_ID="550e8400-e29b-41d4-a716-446655440000"
# Update title
curl -X PATCH http://localhost:8000/api/v1/notebooks/$NOTEBOOK_ID \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"title": "New Title"}'
# Delete notebook
curl -X DELETE http://localhost:8000/api/v1/notebooks/$NOTEBOOK_ID \
-H "X-API-Key: your-key"
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
VALIDATION_ERROR |
400 | Input validation failed |
AUTH_ERROR |
401 | Authentication failed (missing/invalid API key) |
NOT_FOUND |
404 | Resource not found |
RATE_LIMITED |
429 | Rate limit exceeded |
NOTEBOOKLM_ERROR |
502 | External NotebookLM API error |
Rate Limiting
API requests are rate-limited to prevent abuse. Rate limit headers are included in responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1712400000
If you exceed the rate limit, you'll receive a 429 Too Many Requests response:
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 60 seconds.",
"details": [{"retry_after": 60}]
},
"meta": { ... }
}
Documentazione generata automaticamente da @api-designer
Data: 2026-04-06
Versione API: 0.1.0