FastAPI API Reference
Overview
The Blogify backend is powered by a FastAPI service that interfaces with Supabase PostgreSQL. It provides a RESTful interface for managing blog content and user profiles.
Base URL
In a local development environment, the API is available at:
http://127.0.0.1:8000
Authentication
Protected routes require a valid Supabase JWT. This token should be passed in the HTTP headers of your request.
| Header | Value |
| :--- | :--- |
| Authorization | Bearer <access_token> |
Data Models
Post Object
| Field | Type | Description |
| :--- | :--- | :--- |
| id | string (UUID) | Unique identifier for the post. |
| title | string | The title of the blog post. |
| content | string | Markdown-formatted content (supports KaTeX). |
| user_id | string | The UUID of the author. |
| tags | string[] | Array of strings for categorization. |
| image_url | string? | Optional URL to a hosted header image. |
| created_at | string | ISO 8601 timestamp. |
| updated_at | string? | ISO 8601 timestamp of last edit. |
User Object
| Field | Type | Description |
| :--- | :--- | :--- |
| id | string | Unique identifier (matches Supabase Auth ID). |
| name | string | Display name of the user. |
| email | string | User's email address. |
| profile_picture_url | string? | Optional URL to the user's avatar. |
| created_at | string | ISO 8601 timestamp. |
Posts Endpoints
List Posts
GET /posts
Retrieves a list of blog posts, ordered by creation date (newest first).
Query Parameters:
skip(int, default: 0): Number of records to skip for pagination.limit(int, default: 20): Maximum number of records to return.user_id(string, optional): Filter posts by a specific author.
Example Request:
curl "http://127.0.0.1:8000/posts?limit=5&skip=0"
Get Post Count
GET /posts/count
Returns the total number of posts in the database. Useful for calculating pagination.
Response:
{ "count": 142 }
Get Single Post
GET /posts/{id}
Retrieves detailed information for a specific post.
Create Post
POST /posts (Protected)
Creates a new blog entry.
Body (JSON):
{
"title": "My New Story",
"content": "Writing in **Markdown**...",
"user_id": "user-uuid-here",
"tags": ["tech", "coding"],
"image_url": "https://..."
}
Update Post
PUT /posts/{id} (Protected)
Updates an existing post. Only the author of the post can perform this action.
Delete Post
DELETE /posts/{id} (Protected)
Permanently removes a post. Only the author of the post can perform this action.
Users Endpoints
Get User Profile
GET /users/{id}
Fetches public profile information for a specific user.
Example Response:
{
"id": "7f8b...",
"name": "Jane Doe",
"email": "jane@example.com",
"profile_picture_url": "https://...",
"created_at": "2023-10-01T12:00:00Z"
}
Update User Profile
PUT /users/{id} (Protected)
Updates the profile information (e.g., display name or avatar) for the authenticated user.
Body (JSON):
{
"name": "Jane D.",
"profile_picture_url": "https://new-avatar-link.png"
}
Delete User
DELETE /users/{id} (Protected)
Deletes the user profile from the database. Note that this typically triggers a cleanup of the user's posts depending on database constraints.
Tags
Filter by Tag
While there is no dedicated /tags endpoint for listing all unique tags, posts can be filtered by specific tags using the general list endpoint if supported by the query logic, or via the frontend route /tags/[tag] which typically interacts with the GET /posts endpoint using query filtering.
Error Handling
The API returns standard HTTP status codes:
| Status Code | Description |
| :--- | :--- |
| 200 | Success. |
| 201 | Created successfully. |
| 401 | Unauthorized. Missing or invalid JWT. |
| 403 | Forbidden. You do not own the resource you are trying to modify. |
| 404 | Not Found. The resource does not exist. |
| 500 | Internal Server Error. |
Errors follow a consistent JSON structure:
{
"detail": "Error message describing what went wrong."
}