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/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/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/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/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/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/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/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/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"
}
}
}
}
}
}💡 Tip: Copy this OpenAPI specification and import it into Postman, Insomnia, or Swagger Editor to test the APIs interactively.