All API routes use NextAuth.js for authentication. Protected routes require a valid session.
Upload a PDF file and convert it to a blog post using AI.
Request:
Content-Type: multipart/form-data
{
file: File (PDF, max 50MB)
}Response:
{
success: boolean,
conversionId: string,
result: {
title: string,
content: string,
summary: string,
tags: string[],
imageUrls: string[],
thumbnailUrl?: string
},
metadata: {
title?: string,
author?: string,
pages: number,
creationDate?: string
},
imageCount: number
}Error Response:
{
error: string
}Status Codes:
- 200: Success
- 400: Invalid file type or size
- 500: Server error
Generate a presigned URL for uploading images to S3.
Request:
{
fileName: string,
fileType: string,
directory: "thumbnails" | "content",
authorId: string,
blogSlug?: string
}Response:
{
success: boolean,
uploadUrl: string,
key: string,
publicUrl: string,
directory: string,
fileType: string,
timestamp: string
}Error Response:
{
error: string,
details?: string
}Status Codes:
- 200: Success
- 400: Missing required fields
- 500: Server error
Sign in with credentials.
Request:
{
email: string,
password: string
}Register a new user.
Request:
{
email: string,
password: string,
name: string
}Sign out the current user.
Test DynamoDB connection and create sample data.
Response:
{
connection: {
success: boolean,
message: string,
table: string,
timestamp: string,
data?: any
},
sampleBlogs: {
success: boolean,
message: string,
blogs?: any[]
}
}interface BlogPost {
PK: string, // BLOG#<slug>
SK: string, // METADATA
GSI1PK: string, // AUTHOR#<author_id>
GSI1SK: string, // <created_at>
title: string,
content: string,
summary?: string,
author_id: string,
category?: string,
tags?: string[],
status: "draft" | "published",
created_at: string,
updated_at: string,
views: number,
ai_generated: boolean,
slug: string,
thumbnail_url?: string,
images?: Array<{
url: string,
alt: string,
caption?: string,
position: number
}>
}interface User {
PK: string, // USER#<email>
SK: string, // PROFILE
email: string,
name: string,
password: string, // Hashed
role: "visitor" | "author",
created_at: string
}interface PDFExtractionResult {
text: string,
images: ExtractedImage[],
metadata: {
title?: string,
author?: string,
pages: number,
creationDate?: string
},
layout: LayoutSection[]
}
interface ExtractedImage {
data: string, // Base64 encoded
alt: string,
page: number,
position: number,
mimeType: string,
width?: number,
height?: number
}
interface LayoutSection {
type: "heading" | "paragraph",
content: string,
level?: number,
pageNumber: number
}interface BlogConversionResult {
title: string,
content: string, // HTML formatted
summary: string,
tags: string[],
sections: BlogSection[],
thumbnailUrl?: string
}
interface BlogSection {
heading: string,
content: string, // HTML formatted
images?: number[] // Indices of images to display
}All API endpoints return consistent error responses:
{
error: string, // Error message
details?: string // Additional error details
}No rate limiting is currently implemented. Consider adding rate limiting for production use.
- User sends credentials to /api/auth/signin
- Server validates credentials against DynamoDB
- NextAuth creates a session with JWT token
- Client receives session cookie
- Subsequent requests include session cookie for authentication
- Protected routes verify session before processing
- Client requests presigned URL from /api/upload
- Server generates presigned URL with temporary credentials
- Client uploads file directly to S3 using presigned URL
- S3 returns success response
- Client uses public URL for displaying images
- Client uploads PDF to /api/pdf/upload
- Server extracts text and images from PDF
- Server uploads extracted images to S3
- Server sends text and images to Gemini AI for conversion
- Gemini AI generates blog post with structured content
- Gemini AI selects best thumbnail from extracted images
- Server returns formatted blog post with S3 image URLs