Interactive API documentation for the AI SaaS Starter Kit
{
"openapi": "3.0.0",
"info": {
"title": "AI SaaS Starter Kit API",
"version": "1.0.0",
"description": "Production-ready Next.js 15 AI SaaS API with authentication, billing, and AI integration. This comprehensive API provides endpoints for user management, blog content management, payment processing, subscription handling, and webhook integration.",
"contact": {
"name": "API Support",
"email": "support@example.com"
},
"license": {
"name": "MIT",
"url": "https://opensource.org/licenses/MIT"
}
},
"servers": [
{
"url": "http://localhost:3000",
"description": "Development server"
},
{
"url": "https://yourdomain.com",
"description": "Production server"
}
],
"tags": [
{
"name": "Authentication",
"description": "User authentication and registration endpoints. Handle user registration with email/password and OAuth providers (Google, GitHub)."
},
{
"name": "Users",
"description": "User management endpoints. Create, read, update, and delete users. Manage user roles and permissions. Requires ADMIN or SUPER_ADMIN role."
},
{
"name": "Blogs",
"description": "Blog content management endpoints. Create, read, update, and delete blog posts. Manage blog categories and publishing status. Public users can read published posts, admins can manage all posts."
},
{
"name": "Categories",
"description": "Blog category management endpoints. Create, read, update, and delete categories. Public endpoint for reading, admin role required for modifications."
},
{
"name": "Plans",
"description": "Subscription plan management endpoints. View available subscription plans with pricing and features. Public endpoint."
},
{
"name": "Subscriptions",
"description": "Subscription management endpoints. View and cancel subscriptions. Users can manage their own subscriptions, admins can manage all subscriptions."
},
{
"name": "Payments",
"description": "Payment history and transaction management. View payment records and transaction details. Users can view their own payments, admins can view all payments."
},
{
"name": "Billing",
"description": "Stripe checkout and subscription management. Create checkout sessions for plan purchases and manage subscriptions."
},
{
"name": "Webhooks",
"description": "External service webhooks. Receive and process events from Stripe for payment confirmations and subscription updates."
}
],
"components": {
"securitySchemes": {
"sessionAuth": {
"type": "apiKey",
"in": "cookie",
"name": "authjs.session-token",
"description": "Session-based authentication using NextAuth. After signing in, the session cookie will be automatically included in requests."
}
}
},
"security": [],
"paths": {
"/api/webhooks/stripe": {
"post": {
"tags": [
"Webhooks"
],
"summary": "Stripe webhook endpoint",
"description": "Receive and process Stripe webhook events for payment and subscription management.\nThis endpoint handles the following events:\n- checkout.session.completed: Creates subscription and adds credits\n- customer.subscription.updated: Updates subscription status and billing period\n- customer.subscription.deleted: Marks subscription as canceled\n- invoice.payment_succeeded: Records payment and refreshes credits\n- invoice.payment_failed: Records failed payment attempt\n\nThe request must include a valid Stripe webhook signature for security verification.\n",
"parameters": [
{
"in": "header",
"name": "stripe-signature",
"required": true,
"schema": {
"type": "string"
},
"description": "Stripe webhook signature for request verification",
"example": "t=1614556800,v1=abc123def456..."
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique event identifier",
"example": "evt_1OXd9KExample123456"
},
"type": {
"type": "string",
"description": "Type of Stripe event",
"enum": [
"checkout.session.completed",
"customer.subscription.updated",
"customer.subscription.deleted",
"invoice.payment_succeeded",
"invoice.payment_failed"
],
"example": "checkout.session.completed"
},
"data": {
"type": "object",
"description": "Event data containing the Stripe object",
"properties": {
"object": {
"type": "object",
"description": "The Stripe resource (session, subscription, or invoice)"
}
}
}
}
},
"examples": {
"checkoutCompleted": {
"summary": "Checkout session completed",
"value": {
"id": "evt_1OXd9KExample123456",
"type": "checkout.session.completed",
"data": {
"object": {
"id": "cs_test_a1B2c3D4e5F6g7H8i9J0",
"customer": "cus_Example123456",
"subscription": "sub_Example789012",
"metadata": {
"userId": "clx1234567890abcdef",
"planName": "Pro Plan"
}
}
}
}
},
"subscriptionUpdated": {
"summary": "Subscription updated",
"value": {
"id": "evt_1OXd9LExample789012",
"type": "customer.subscription.updated",
"data": {
"object": {
"id": "sub_Example789012",
"status": "active",
"current_period_start": 1705312800,
"current_period_end": 1707991200,
"cancel_at_period_end": false
}
}
}
},
"paymentSucceeded": {
"summary": "Invoice payment succeeded",
"value": {
"id": "evt_1OXd9MExample345678",
"type": "invoice.payment_succeeded",
"data": {
"object": {
"id": "in_Example123456",
"subscription": "sub_Example789012",
"amount_paid": 1900,
"currency": "usd",
"payment_intent": "pi_Example123456"
}
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Webhook event processed successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"received": {
"type": "boolean",
"example": true
}
}
}
}
}
},
"400": {
"description": "Missing or invalid webhook signature",
"content": {
"text/plain": {
"schema": {
"type": "string",
"example": "Invalid signature"
}
}
}
},
"500": {
"description": "Internal error processing webhook",
"content": {
"text/plain": {
"schema": {
"type": "string",
"example": "Webhook handler failed"
}
}
}
}
}
}
},
"/api/users": {
"get": {
"tags": [
"Users"
],
"summary": "List all users",
"description": "Get paginated list of all users with their roles and subscriptions. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "query",
"name": "page",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
},
"description": "Page number for pagination"
},
{
"in": "query",
"name": "perPage",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
},
"description": "Number of users per page"
},
{
"in": "query",
"name": "search",
"schema": {
"type": "string"
},
"description": "Search users by name or email"
},
{
"in": "query",
"name": "role",
"schema": {
"type": "string",
"enum": [
"USER",
"ADMIN",
"SUPER_ADMIN"
]
},
"description": "Filter by role"
}
],
"responses": {
"200": {
"description": "List of users retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "clx1234567890abcdef"
},
"name": {
"type": "string",
"example": "John Doe"
},
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"credits": {
"type": "integer",
"example": 100
},
"emailVerified": {
"type": "string",
"format": "date-time",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"roles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string",
"example": "USER"
}
}
}
},
"subscription": {
"type": "object",
"nullable": true,
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string"
},
"plan": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "number"
}
}
}
}
}
}
}
},
"pagination": {
"type": "object",
"properties": {
"total": {
"type": "integer",
"example": 42
},
"page": {
"type": "integer",
"example": 1
},
"perPage": {
"type": "integer",
"example": 10
},
"totalPages": {
"type": "integer",
"example": 5
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized (requires ADMIN or SUPER_ADMIN role)"
},
"500": {
"description": "Internal server error"
}
}
},
"post": {
"tags": [
"Users"
],
"summary": "Create a new user",
"description": "Create a new user account. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"email",
"password"
],
"properties": {
"name": {
"type": "string",
"minLength": 2,
"example": "Jane Smith"
},
"email": {
"type": "string",
"format": "email",
"example": "jane.smith@example.com"
},
"password": {
"type": "string",
"format": "password",
"minLength": 8,
"example": "SecurePass123!"
},
"credits": {
"type": "integer",
"minimum": 0,
"example": 100,
"description": "Initial credits (defaults to 100)"
}
}
}
}
}
},
"responses": {
"201": {
"description": "User created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "User created successfully"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"credits": {
"type": "integer"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or user already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/users/{id}": {
"get": {
"tags": [
"Users"
],
"summary": "Get user by ID",
"description": "Retrieve detailed information about a specific user. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "User ID",
"example": "clx1234567890abcdef"
}
],
"responses": {
"200": {
"description": "User details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"credits": {
"type": "integer"
},
"emailVerified": {
"type": "string",
"format": "date-time",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"roles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
},
"subscription": {
"type": "object",
"nullable": true,
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string"
},
"currentPeriodEnd": {
"type": "string",
"format": "date-time"
},
"plan": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"creditsPerMonth": {
"type": "integer"
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "User not found"
},
"500": {
"description": "Internal server error"
}
}
},
"put": {
"tags": [
"Users"
],
"summary": "Update user",
"description": "Update user details. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "User ID"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 2,
"example": "John Updated"
},
"email": {
"type": "string",
"format": "email",
"example": "john.updated@example.com"
},
"credits": {
"type": "integer",
"minimum": 0,
"example": 200
}
}
}
}
}
},
"responses": {
"200": {
"description": "User updated successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "User updated successfully"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"credits": {
"type": "integer"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or email already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "User not found"
},
"500": {
"description": "Internal server error"
}
}
},
"delete": {
"tags": [
"Users"
],
"summary": "Delete user",
"description": "Delete a user account. Requires ADMIN or SUPER_ADMIN role. Cannot delete yourself.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "User ID"
}
],
"responses": {
"200": {
"description": "User deleted successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "User deleted successfully"
}
}
}
}
}
},
"400": {
"description": "Cannot delete yourself"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "User not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/users/{id}/roles": {
"post": {
"tags": [
"Users"
],
"summary": "Assign role to user",
"description": "Assign a role to a user. Requires SUPER_ADMIN role. Cannot assign SUPER_ADMIN role to others unless you are SUPER_ADMIN.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "User ID"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"roleId"
],
"properties": {
"roleId": {
"type": "string",
"example": "clx0987654321fedcba",
"description": "ID of the role to assign"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Role assigned successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Role assigned successfully"
}
}
}
}
}
},
"400": {
"description": "Validation error or user already has this role"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized (requires SUPER_ADMIN)"
},
"404": {
"description": "User or role not found"
},
"500": {
"description": "Internal server error"
}
}
},
"delete": {
"tags": [
"Users"
],
"summary": "Remove role from user",
"description": "Remove a role from a user. Requires SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "User ID"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"roleId"
],
"properties": {
"roleId": {
"type": "string",
"example": "clx0987654321fedcba",
"description": "ID of the role to remove"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Role removed successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Role removed successfully"
}
}
}
}
}
},
"400": {
"description": "Validation error or user doesn't have this role"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "User or role not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/subscriptions": {
"get": {
"tags": [
"Subscriptions"
],
"summary": "List all subscriptions",
"description": "Get paginated list of all subscriptions. Requires ADMIN or SUPER_ADMIN role. Regular users can only see their own subscription.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "query",
"name": "page",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
},
"description": "Page number for pagination"
},
{
"in": "query",
"name": "perPage",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
},
"description": "Number of subscriptions per page"
},
{
"in": "query",
"name": "userId",
"schema": {
"type": "string"
},
"description": "Filter by user ID (admin only)"
},
{
"in": "query",
"name": "status",
"schema": {
"type": "string",
"enum": [
"active",
"canceled",
"incomplete",
"incomplete_expired",
"past_due",
"paused",
"trialing",
"unpaid"
]
},
"description": "Filter by subscription status"
},
{
"in": "query",
"name": "planId",
"schema": {
"type": "string"
},
"description": "Filter by plan ID (admin only)"
}
],
"responses": {
"200": {
"description": "List of subscriptions retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"subscriptions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"stripeSubscriptionId": {
"type": "string",
"example": "sub_Example789012"
},
"stripeCustomerId": {
"type": "string",
"example": "cus_Example123456"
},
"status": {
"type": "string",
"example": "active"
},
"billingCycle": {
"type": "string",
"enum": [
"month",
"year"
]
},
"currentPeriodStart": {
"type": "string",
"format": "date-time"
},
"currentPeriodEnd": {
"type": "string",
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
},
"plan": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"creditsPerMonth": {
"type": "integer"
}
}
}
}
}
},
"pagination": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"page": {
"type": "integer"
},
"perPage": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/subscriptions/{id}": {
"get": {
"tags": [
"Subscriptions"
],
"summary": "Get subscription by ID",
"description": "Retrieve detailed information about a specific subscription. Users can only view their own subscription unless they are admin.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Subscription ID"
}
],
"responses": {
"200": {
"description": "Subscription details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"stripeSubscriptionId": {
"type": "string"
},
"stripeCustomerId": {
"type": "string"
},
"status": {
"type": "string"
},
"billingCycle": {
"type": "string"
},
"currentPeriodStart": {
"type": "string",
"format": "date-time"
},
"currentPeriodEnd": {
"type": "string",
"format": "date-time"
},
"cancelAtPeriodEnd": {
"type": "boolean"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
},
"plan": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"price": {
"type": "number"
},
"creditsPerMonth": {
"type": "integer"
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized to view this subscription"
},
"404": {
"description": "Subscription not found"
},
"500": {
"description": "Internal server error"
}
}
},
"delete": {
"tags": [
"Subscriptions"
],
"summary": "Cancel subscription",
"description": "Cancel a subscription. Will cancel at the end of the billing period. Users can cancel their own subscription, admins can cancel any subscription.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Subscription ID"
}
],
"responses": {
"200": {
"description": "Subscription canceled successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Subscription canceled successfully"
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized to cancel this subscription"
},
"404": {
"description": "Subscription not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/plans": {
"get": {
"tags": [
"Plans"
],
"summary": "List all subscription plans",
"description": "Get list of all available subscription plans. Public endpoint.",
"responses": {
"200": {
"description": "List of plans retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"plans": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "clx1234567890abcdef"
},
"name": {
"type": "string",
"example": "Pro Plan"
},
"description": {
"type": "string",
"example": "Perfect for professionals"
},
"price": {
"type": "number",
"example": 19
},
"creditsPerMonth": {
"type": "integer",
"example": 1000
},
"features": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"1000 credits/month",
"Priority support",
"Advanced features"
]
},
"monthlyPrice": {
"type": "number",
"example": 19
},
"yearlyPrice": {
"type": "number",
"example": 190
},
"_count": {
"type": "object",
"properties": {
"subscriptions": {
"type": "integer",
"description": "Number of active subscriptions"
}
}
}
}
}
}
}
}
}
}
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/payments": {
"get": {
"tags": [
"Payments"
],
"summary": "List all payments",
"description": "Get paginated list of all payments. Requires ADMIN or SUPER_ADMIN role. Regular users can only see their own payments.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "query",
"name": "page",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
},
"description": "Page number for pagination"
},
{
"in": "query",
"name": "perPage",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
},
"description": "Number of payments per page"
},
{
"in": "query",
"name": "userId",
"schema": {
"type": "string"
},
"description": "Filter by user ID (admin only)"
},
{
"in": "query",
"name": "status",
"schema": {
"type": "string",
"enum": [
"succeeded",
"failed",
"pending",
"refunded"
]
},
"description": "Filter by payment status"
}
],
"responses": {
"200": {
"description": "List of payments retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"payments": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"stripePaymentId": {
"type": "string",
"example": "pi_1OXd9KExample123456"
},
"amount": {
"type": "number",
"example": 19
},
"currency": {
"type": "string",
"example": "usd"
},
"status": {
"type": "string",
"enum": [
"succeeded",
"failed",
"pending",
"refunded"
]
},
"description": {
"type": "string",
"nullable": true
},
"invoiceUrl": {
"type": "string",
"nullable": true
},
"receiptUrl": {
"type": "string",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
}
}
}
},
"pagination": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"page": {
"type": "integer"
},
"perPage": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/payments/{id}": {
"get": {
"tags": [
"Payments"
],
"summary": "Get payment by ID",
"description": "Retrieve detailed information about a specific payment. Users can only view their own payments unless they are admin.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Payment ID"
}
],
"responses": {
"200": {
"description": "Payment details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"stripePaymentId": {
"type": "string"
},
"amount": {
"type": "number"
},
"currency": {
"type": "string"
},
"status": {
"type": "string"
},
"description": {
"type": "string",
"nullable": true
},
"invoiceUrl": {
"type": "string",
"nullable": true
},
"receiptUrl": {
"type": "string",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized to view this payment"
},
"404": {
"description": "Payment not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/create-checkout": {
"post": {
"tags": [
"Billing"
],
"summary": "Create Stripe checkout session",
"description": "Create a Stripe checkout session for subscription purchase. User must be authenticated. Available plans - Pro ($19/month), Business ($49/month).",
"security": [
{
"sessionAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"priceId",
"planName"
],
"properties": {
"priceId": {
"type": "string",
"description": "Stripe price ID",
"example": "price_1OXd9KExample123456"
},
"planName": {
"type": "string",
"description": "Plan name (Pro Plan or Business Plan)",
"enum": [
"Pro Plan",
"Business Plan"
],
"example": "Pro Plan"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Checkout session created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Stripe checkout URL",
"example": "https://checkout.stripe.com/c/pay/cs_test_a1B2c3D4e5F6g7H8i9J0"
}
}
}
}
}
},
"400": {
"description": "Missing required fields",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Missing required fields"
}
}
}
}
}
},
"401": {
"description": "User not authenticated",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Unauthorized"
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Internal Server Error"
}
}
}
}
}
}
}
}
},
"/api/categories": {
"get": {
"tags": [
"Categories"
],
"summary": "List all categories",
"description": "Get list of all blog categories. Public endpoint.",
"parameters": [
{
"in": "query",
"name": "search",
"schema": {
"type": "string"
},
"description": "Search categories by name"
}
],
"responses": {
"200": {
"description": "List of categories retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"categories": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "clx1234567890abcdef"
},
"name": {
"type": "string",
"example": "Technology"
},
"slug": {
"type": "string",
"example": "technology"
},
"description": {
"type": "string",
"nullable": true,
"example": "Articles about technology and software"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"_count": {
"type": "object",
"properties": {
"blogs": {
"type": "integer",
"description": "Number of blog posts in this category",
"example": 15
}
}
}
}
}
}
}
}
}
}
},
"500": {
"description": "Internal server error"
}
}
},
"post": {
"tags": [
"Categories"
],
"summary": "Create a new category",
"description": "Create a new blog category. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"slug"
],
"properties": {
"name": {
"type": "string",
"example": "Artificial Intelligence"
},
"slug": {
"type": "string",
"example": "artificial-intelligence"
},
"description": {
"type": "string",
"example": "Articles about AI and machine learning"
}
}
}
}
}
},
"responses": {
"201": {
"description": "Category created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Category created successfully"
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or slug already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/categories/{id}": {
"get": {
"tags": [
"Categories"
],
"summary": "Get category by ID",
"description": "Retrieve detailed information about a specific category including blog count. Public endpoint.",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Category ID or slug"
}
],
"responses": {
"200": {
"description": "Category details retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
},
"description": {
"type": "string",
"nullable": true
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"_count": {
"type": "object",
"properties": {
"blogs": {
"type": "integer"
}
}
}
}
}
}
}
},
"404": {
"description": "Category not found"
},
"500": {
"description": "Internal server error"
}
}
},
"put": {
"tags": [
"Categories"
],
"summary": "Update category",
"description": "Update category details. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Category ID"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "Machine Learning"
},
"slug": {
"type": "string",
"example": "machine-learning"
},
"description": {
"type": "string",
"nullable": true,
"example": "Deep learning and neural networks"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Category updated successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Category updated successfully"
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or slug already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "Category not found"
},
"500": {
"description": "Internal server error"
}
}
},
"delete": {
"tags": [
"Categories"
],
"summary": "Delete category",
"description": "Delete a category. Requires ADMIN or SUPER_ADMIN role. Cannot delete if category has associated blog posts.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Category ID"
}
],
"responses": {
"200": {
"description": "Category deleted successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Category deleted successfully"
}
}
}
}
}
},
"400": {
"description": "Category has associated blog posts"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "Category not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/blogs": {
"get": {
"tags": [
"Blogs"
],
"summary": "List all blog posts",
"description": "Get paginated list of blog posts. Public endpoint returns only published posts. Authenticated admins can see all posts.",
"parameters": [
{
"in": "query",
"name": "page",
"schema": {
"type": "integer",
"minimum": 1,
"default": 1
},
"description": "Page number for pagination"
},
{
"in": "query",
"name": "perPage",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 10
},
"description": "Number of posts per page"
},
{
"in": "query",
"name": "search",
"schema": {
"type": "string"
},
"description": "Search posts by title or content"
},
{
"in": "query",
"name": "published",
"schema": {
"type": "boolean"
},
"description": "Filter by published status (admin only)"
},
{
"in": "query",
"name": "category",
"schema": {
"type": "string"
},
"description": "Filter by category ID"
}
],
"responses": {
"200": {
"description": "List of blog posts retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"blogs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"slug": {
"type": "string"
},
"excerpt": {
"type": "string"
},
"featuredImage": {
"type": "string",
"nullable": true
},
"published": {
"type": "boolean"
},
"views": {
"type": "integer"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"author": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
},
"categories": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
}
},
"pagination": {
"type": "object",
"properties": {
"total": {
"type": "integer"
},
"page": {
"type": "integer"
},
"perPage": {
"type": "integer"
},
"totalPages": {
"type": "integer"
}
}
}
}
}
}
}
},
"500": {
"description": "Internal server error"
}
}
},
"post": {
"tags": [
"Blogs"
],
"summary": "Create a new blog post",
"description": "Create a new blog post. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"title",
"slug",
"content"
],
"properties": {
"title": {
"type": "string",
"example": "Getting Started with Next.js 15"
},
"slug": {
"type": "string",
"example": "getting-started-nextjs-15"
},
"content": {
"type": "string",
"example": "Next.js 15 brings exciting new features..."
},
"excerpt": {
"type": "string",
"example": "A comprehensive guide to Next.js 15"
},
"featuredImage": {
"type": "string",
"format": "uri",
"example": "https://example.com/cover.jpg"
},
"published": {
"type": "boolean",
"default": false
},
"categoryIds": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"clx1234567890abcdef"
]
}
}
}
}
}
},
"responses": {
"201": {
"description": "Blog post created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Blog post created successfully"
},
"blog": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"slug": {
"type": "string"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or slug already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/blogs/{id}": {
"get": {
"tags": [
"Blogs"
],
"summary": "Get blog post by ID",
"description": "Retrieve detailed information about a specific blog post. Public users can only view published posts.",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Blog post ID or slug"
}
],
"responses": {
"200": {
"description": "Blog post retrieved successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"slug": {
"type": "string"
},
"content": {
"type": "string"
},
"excerpt": {
"type": "string"
},
"coverImage": {
"type": "string",
"nullable": true
},
"published": {
"type": "boolean"
},
"views": {
"type": "integer"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time"
},
"author": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"email": {
"type": "string"
}
}
},
"categories": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"slug": {
"type": "string"
}
}
}
}
}
}
}
}
},
"403": {
"description": "Blog post is not published (non-admin users)"
},
"404": {
"description": "Blog post not found"
},
"500": {
"description": "Internal server error"
}
}
},
"put": {
"tags": [
"Blogs"
],
"summary": "Update blog post",
"description": "Update an existing blog post. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Blog post ID"
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"slug": {
"type": "string"
},
"content": {
"type": "string"
},
"excerpt": {
"type": "string"
},
"coverImage": {
"type": "string",
"format": "uri",
"nullable": true
},
"published": {
"type": "boolean"
},
"categoryIds": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Blog post updated successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Blog post updated successfully"
},
"blog": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"slug": {
"type": "string"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or slug already exists"
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "Blog post not found"
},
"500": {
"description": "Internal server error"
}
}
},
"delete": {
"tags": [
"Blogs"
],
"summary": "Delete blog post",
"description": "Delete a blog post. Requires ADMIN or SUPER_ADMIN role.",
"security": [
{
"sessionAuth": []
}
],
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
},
"description": "Blog post ID"
}
],
"responses": {
"200": {
"description": "Blog post deleted successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Blog post deleted successfully"
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
},
"403": {
"description": "Not authorized"
},
"404": {
"description": "Blog post not found"
},
"500": {
"description": "Internal server error"
}
}
}
},
"/api/auth/register": {
"post": {
"tags": [
"Authentication"
],
"summary": "Register a new user",
"description": "Create a new user account with email and password. User gets 100 free credits and USER role.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"email",
"password"
],
"properties": {
"name": {
"type": "string",
"minLength": 2,
"example": "John Doe"
},
"email": {
"type": "string",
"format": "email",
"example": "john.doe@example.com"
},
"password": {
"type": "string",
"format": "password",
"minLength": 8,
"example": "SecurePass123!"
}
}
}
}
}
},
"responses": {
"201": {
"description": "User created successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "User created successfully"
},
"user": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "clx1234567890abcdef"
},
"name": {
"type": "string",
"example": "John Doe"
},
"email": {
"type": "string",
"example": "john.doe@example.com"
}
}
}
}
}
}
}
},
"400": {
"description": "Validation error or user already exists",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "User with this email already exists"
}
}
}
}
}
},
"500": {
"description": "Internal server error",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Something went wrong. Please try again."
}
}
}
}
}
}
}
}
},
"/api/auth/signin": {
"get": {
"tags": [
"Authentication"
],
"summary": "Sign in page",
"description": "Redirects to the sign-in page. This is handled by NextAuth.",
"responses": {
"302": {
"description": "Redirect to sign-in page"
}
}
},
"post": {
"tags": [
"Authentication"
],
"summary": "Sign in with credentials or OAuth",
"description": "Authenticate user with email/password or OAuth providers (Google, GitHub).\nThis endpoint is handled by NextAuth and supports multiple authentication methods.\n",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"example": "john.doe@example.com"
},
"password": {
"type": "string",
"format": "password",
"example": "SecurePass123!"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Authentication successful"
},
"401": {
"description": "Invalid credentials"
}
}
}
},
"/api/auth/signout": {
"post": {
"tags": [
"Authentication"
],
"summary": "Sign out",
"description": "Sign out the current user and destroy the session",
"responses": {
"200": {
"description": "Sign out successful"
}
}
}
},
"/api/auth/session": {
"get": {
"tags": [
"Authentication"
],
"summary": "Get current session",
"description": "Returns the current user session if authenticated",
"responses": {
"200": {
"description": "Current session data",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"id": {
"type": "string",
"example": "clx1234567890abcdef"
},
"name": {
"type": "string",
"example": "John Doe"
},
"email": {
"type": "string",
"example": "john.doe@example.com"
},
"credits": {
"type": "integer",
"example": 100
},
"roles": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"USER"
]
}
}
},
"expires": {
"type": "string",
"format": "date-time",
"example": "2024-02-15T10:30:00.000Z"
}
}
}
}
}
},
"401": {
"description": "Not authenticated"
}
}
}
},
"/api/auth/providers": {
"get": {
"tags": [
"Authentication"
],
"summary": "Get available auth providers",
"description": "Returns list of configured authentication providers (Google, GitHub, Credentials)",
"responses": {
"200": {
"description": "List of providers",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"type": {
"type": "string"
}
}
}
}
}
}
}
}
}
},
"/api/admin/marketing/send-email": {
"post": {
"tags": [
"Admin Marketing"
],
"summary": "Send promotional email (Admin/SuperAdmin only)",
"description": "Send promotional emails to users based on recipient type",
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"subject",
"content",
"recipientType"
],
"properties": {
"subject": {
"type": "string",
"example": "New Feature: AI Chat now supports PDFs!"
},
"content": {
"type": "string",
"example": "<p>We're excited to announce...</p>"
},
"preheader": {
"type": "string",
"example": "Check out our latest feature"
},
"recipientType": {
"type": "string",
"enum": [
"all",
"verified",
"free",
"pro",
"business",
"custom"
],
"example": "all"
},
"recipientEmails": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"user1@example.com",
"user2@example.com"
]
}
}
}
}
}
},
"responses": {
"200": {
"description": "Emails sent successfully"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden - Admin access required"
},
"500": {
"description": "Server error"
}
}
}
}
}
}💡 Tip: Copy this OpenAPI specification and import it into Postman, Insomnia, or Swagger Editor to test the APIs interactively.