Tailor My Resume API

Complete backend API documentation for the resume optimization platform

AI-powered resume optimization with authentication, payments, and credit management

📋 Table of Contents

🔐 Authentication Endpoints

💳 Payment & Credit Endpoints

🤖 AI & Core Endpoints

🔒 Security & Rate Limiting

🔐 Authentication Endpoints

🔄 Token Rotation System

All authentication endpoints now use a secure token rotation system with short-lived access tokens (30 minutes) and long-lived refresh tokens (7 days). The frontend automatically handles token refresh to provide seamless user experience while maintaining security.

GET /auth/test-api-key

Tests Firebase API key validity and configuration

Parameters

No parameters required

Response Example

{
  "success": true,
  "message": "API key is valid",
  "projectId": "tailor-my-resume-c90bb"
}
POST /auth/signup

Creates a new user account with email verification

Request Body Parameters

Parameter Type Required Description
email string Required User's email address
password string Required User's password (min 6 characters)
displayName string Optional User's display name
marketingConsent boolean Optional Marketing email consent (default: false)

Response Example

{
  "success": true,
  "user": {
    "email": "user@example.com",
    "displayName": "John Doe",
    "emailVerified": false
  },
  "accessToken": "short_lived_access_token_30min",
  "refreshToken": "long_lived_refresh_token_7days",
  "expiresIn": 1800,
  "message": "Account created successfully! Please check your email..."
}

🔒 Security Enhancement

Token Rotation & User ID Protection:

  • Short-lived Access Tokens: 30-minute expiry for enhanced security
  • Refresh Token System: 7-day refresh tokens for seamless re-authentication
  • Automatic Rotation: Frontend automatically refreshes tokens before expiry
  • No UID Exposure: User ID is NOT included in response to prevent enumeration attacks
  • JWT Token Parsing: Frontend extracts UID securely from access token payload
POST /auth/signin

Authenticates user with email and password

Request Body Parameters

Parameter Type Required Description
email string Required User's email address
password string Required User's password

Response Example

{
  "success": true,
  "user": {
    "email": "user@example.com",
    "displayName": "John Doe"
  },
  "accessToken": "short_lived_access_token_30min",
  "refreshToken": "long_lived_refresh_token_7days",
  "expiresIn": 1800
}

🔒 Security Enhancement

Token Rotation & User ID Protection:

  • Short-lived Access Tokens: 30-minute expiry for enhanced security
  • Refresh Token System: 7-day refresh tokens for seamless re-authentication
  • Automatic Rotation: Frontend automatically refreshes tokens before expiry
  • No UID Exposure: User ID is NOT included in response to prevent enumeration attacks
  • JWT Token Parsing: Frontend extracts UID securely from access token payload
POST /auth/reset-password

Sends password reset email to user

Request Body Parameters

Parameter Type Required Description
email string Required User's email address

Response Example

{
  "success": true,
  "message": "Password reset email sent. Please check your inbox."
}
POST /auth/verify-email

Verifies user email using verification code from email link

Request Body Parameters

Parameter Type Required Description
oobCode string Required Verification code from email link

Response Example

{
  "success": true,
  "message": "Email verified successfully! You can now sign in.",
  "user": {
    "email": "user@example.com",
    "emailVerified": true
  }
}

🔒 Security Enhancement

User ID Protection:

  • No UID Exposure: User ID removed from response to prevent enumeration attacks
  • Verification Only: Response confirms email verification status without exposing sensitive IDs
POST /auth/resend-verification

Resends email verification to user

Request Body Parameters

Parameter Type Required Description
email string Required User's email address

Response Example

{
  "success": true,
  "message": "Verification email sent! Please check your inbox..."
}
GET /auth/verify-status/:email

Checks email verification status for a user

URL Parameters

Parameter Type Required Description
email string Required User's email address (URL encoded)

Response Example

{
  "success": true,
  "emailVerified": true
}

⚠️ Security Notice

This endpoint has been hardened for security:

  • No User Data Exposure: UID and email fields removed to prevent user enumeration attacks
  • Rate Limited: 20 requests per 15 minutes per IP address
GET /auth/user/:userId

Retrieves user data from Firebase Auth and Firestore

🔐 Authentication Required

Bearer Token: Must include valid Firebase ID token in Authorization header

Authorization: Users can only access their own data

Headers

Header Type Required Description
Authorization string Required Bearer {access_token}

URL Parameters

Parameter Type Required Description
userId string Required Firebase user ID (must match authenticated user)

Response Example

{
  "success": true,
  "user": {
    "email": "user@example.com",
    "displayName": "John Doe",
    "emailVerified": true,
    "subscription": {
      "status": "free",
      "creditsPurchased": 360,
      "stripeCustomerId": "cus_123"
    },
    "usage": {
      "creditsUsed": 30,
      "lastOptimization": "2024-01-15T10:30:00Z"
    }
  }
}

🔒 Security Enhancement

Access Token & User ID Protection:

  • Access Token Required: Must provide valid short-lived access token (auto-refreshed)
  • No UID Exposure: User ID removed from response to prevent enumeration attacks
  • Authenticated Access: User can only access their own data via Bearer token validation
  • URL Parameter: UID in URL is validated against authenticated user's token
POST /auth/refresh

Refresh access token using a valid refresh token

Request Body Parameters

Parameter Type Required Description
refreshToken string Required Valid refresh token (7-day expiry)
userAgent string Optional Browser user agent for security tracking

Response Example

{
  "success": true,
  "accessToken": "new_short_lived_access_token",
  "refreshToken": "new_refresh_token",
  "expiresIn": 1800
}

🔒 Security Features

  • Token Rotation: Both access and refresh tokens are rotated on each refresh
  • Old Token Invalidation: Previous refresh token is immediately invalidated
  • Device Tracking: IP address and user agent logged for security
  • Expiry Validation: Expired refresh tokens are automatically cleaned up
POST /auth/logout

Logout user and invalidate refresh token

Request Body Parameters

Parameter Type Required Description
refreshToken string Required Refresh token to invalidate

Response Example

{
  "success": true,
  "message": "Logged out successfully"
}
POST /auth/revoke-all-tokens

Revoke all refresh tokens for a user (sign out from all devices)

🔐 Authentication Required

Bearer Token: Must include valid access token in Authorization header

Headers

Header Type Required Description
Authorization string Required Bearer {access_token}

Response Example

{
  "success": true,
  "message": "Signed out from 3 devices",
  "revokedTokens": 3
}

💳 Payment & Credit Endpoints

GET /api/user/:userId/credits

Retrieves current credit balance for a user

URL Parameters

Parameter Type Required Description
userId string Required Firebase user ID

Response Example

{
  "userId": "user123",
  "credits": 330,
  "timestamp": "2024-01-15T10:30:00.123Z"
}
POST /api/create-checkout-session

Creates Stripe checkout session for credit purchase

Request Body Parameters

Parameter Type Required Description
packageType string Required Package type: "starter", "professional", or "premium"
userId string Required Firebase user ID
userEmail string Required User's email address

Response Example

{
  "sessionId": "cs_test_123...",
  "url": "https://checkout.stripe.com/pay/cs_test_123..."
}
POST /api/verify-payment

Verifies payment success status for a checkout session

Request Body Parameters

Parameter Type Required Description
sessionId string Required Stripe checkout session ID

Response Example

{
  "success": true,
  "status": "paid",
  "userId": "user123",
  "credits": 360,
  "packageType": "starter"
}
POST /api/create-portal-session

Creates Stripe customer portal session for billing management

Request Body Parameters

Parameter Type Required Description
userEmail string Required User's email address

Response Example

{
  "url": "https://billing.stripe.com/p/session/..."
}
POST /webhook

Stripe webhook endpoint for payment events (checkout completion, payment failures)

Headers

Header Type Required Description
stripe-signature string Required Stripe webhook signature for verification

Supported Events

  • checkout.session.completed - Credits added to user account
  • payment_intent.succeeded - Payment confirmation
  • payment_intent.payment_failed - Payment failure logging

Response Example

{
  "received": true
}
GET /api/credit-packages

Retrieves available credit packages and pricing

Parameters

No parameters required

Response Example

{
  "starter": {
    "name": "Quick Glow",
    "credits": 360,
    "price": 499,
    "description": "Perfect for landing that dream job (Apply 1-20 jobs)"
  },
  "professional": {
    "name": "Job Hunter Pack",
    "credits": 1200,
    "price": 999,
    "description": "Dominate your job search (Apply 20-40 jobs)"
  },
  "premium": {
    "name": "Enterprise Pack",
    "credits": 0,
    "price": 0,
    "description": "Custom volume for your organization (Contact for pricing)"
  }
}
GET /api/stripe-config

Retrieves Stripe publishable key for client-side integration

Parameters

No parameters required

Response Example

{
  "publishableKey": "pk_test_..."
}

🤖 AI & Core Endpoints

GET /health

Health check endpoint that tests AI provider availability (DeepSeek API or Claude CLI)

Parameters

No parameters required

Response Example (DeepSeek)

{
  "status": "healthy",
  "provider": "deepseek",
  "message": "DeepSeek API is available",
  "timestamp": "2024-01-15T10:30:00.123Z"
}

Response Example (Claude CLI)

{
  "status": "healthy",
  "provider": "claude-cli",
  "message": "Claude CLI is available",
  "timestamp": "2024-01-15T10:30:00.123Z"
}
POST /claude

Main AI optimization endpoint - processes resume optimization requests using DeepSeek API or Claude CLI

🔐 Authentication Required

Bearer Token: Must include valid Firebase ID token in Authorization header

User ID: Extracted automatically from authenticated token

Headers

Header Type Required Description
Authorization string Required Bearer {access_token}

Request Body Parameters

Parameter Type Required Description
prompt string Required Resume and job description text for optimization

Authentication & Credit Requirements

  • Authentication: Required - all requests must include valid userId
  • Credit Cost: 30 credits per optimization (deducted before processing)
  • Anonymous Access: Not allowed - users must sign in

Response Example (Success)

{
  "prompt": "System prompt + user input",
  "response": "{\"optimizedResume\": \"# John Doe\\n\\n## Professional Summary\\n...\", \"matchScore\": 85, \"keywordsAdded\": [\"Python\", \"React\"], \"missingSkills\": [\"Docker\"], \"atsTips\": [\"Use standard headings\"], \"recommendations\": [\"Add Docker experience\"], \"changes\": [{\"original\": \"Developed apps\", \"optimized\": \"Developed Python applications\", \"reason\": \"Added keyword specificity\"}]}",
  "provider": "deepseek"
}

Error Response Examples

// Missing Bearer token
{
  "success": false,
  "error": "Access token required. Please provide Bearer token in Authorization header."
}

// Invalid/expired token
{
  "success": false,
  "error": "Token has expired. Please sign in again."
}

// Insufficient credits
{
  "error": "Insufficient credits",
  "required": 30,
  "available": 15
}

// API configuration error
{
  "error": "Configuration error: DeepSeek API key not set",
  "response": "Execution error",
  "provider": "deepseek"
}

// User not found
{
  "error": "User not found"
}

AI Response Format

The AI response is a JSON string containing:

  • optimizedResume: Complete optimized resume in Markdown format
  • matchScore: ATS match score (0-100)
  • keywordsAdded: Array of keywords incorporated from job description
  • missingSkills: Array of skills missing from resume
  • atsTips: Array of ATS optimization tips
  • recommendations: Array of improvement recommendations
  • changes: Array of specific changes made with explanations

🔒 Security & Rate Limiting

🛡️ Security Hardening Notice

This API has been hardened against common security vulnerabilities including user enumeration attacks, brute force attempts, and abuse. All authentication endpoints are protected with rate limiting.

SECURITY Rate Limiting Implementation

All authentication and user management endpoints are protected by IP-based rate limiting to prevent abuse and attacks.

Rate Limiting by Endpoint Tier

Endpoint Limit Window Protection Level
POST /auth/signup 5 requests 15 minutes Strict - Anti-spam
POST /auth/signin 10 requests 15 minutes Strict - Anti-brute force
POST /auth/reset-password 3 requests 15 minutes Very Strict - Anti-flooding
POST /auth/resend-verification 5 requests 15 minutes Strict - Anti-flooding
POST /auth/verify-email 10 requests 5 minutes Moderate - Short window
GET /auth/verify-status/:email 20 requests 15 minutes Moderate - Anti-enumeration
GET /auth/user/:userId 30 requests 15 minutes Light - User data access
GET /api/user/:userId/credits 30 requests 15 minutes Light - Credit balance
POST /api/verify-payment 20 requests 15 minutes Moderate - Payment verification
GET /auth/test-api-key 10 requests 15 minutes Light - API testing

Rate Limiting Headers

When rate limiting is active, the following headers are included in responses:

  • X-RateLimit-Limit: Maximum requests allowed in the window
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Timestamp when the window resets

Security Features

  • IP-based tracking: Limits applied per client IP address
  • In-memory storage: Fast rate limit checking with automatic cleanup
  • Progressive enforcement: Different limits for different threat levels
  • Memory leak prevention: Automatic cleanup of old entries every 5 minutes
  • Token Rotation: Short-lived access tokens (30min) with automatic refresh
  • Session Management: Secure refresh token storage with device tracking
ERROR Security Error Responses

Security-related error responses you may encounter when rate limits are exceeded or security violations are detected.

Rate Limit Exceeded (429)

{
  "success": false,
  "error": "Too many authentication attempts. Please try again in 15 minutes.",
  "retryAfter": 900
}

User Enumeration Prevention

The /auth/verify-status/:email endpoint has been hardened to prevent user enumeration attacks:

  • Before: Returned user ID and email (security vulnerability)
  • After: Returns only email verification status
  • Protection: Prevents attackers from mapping email addresses to user IDs
// Secure response (current implementation)
{
  "success": true,
  "emailVerified": true
}

// ❌ Previous vulnerable response (removed)
{
  "success": true,
  "emailVerified": true,
  "uid": "user123",     // REMOVED - security risk
  "email": "user@..."   // REMOVED - security risk
}

Common Security Error Codes

Status Code Error Type Description Action Required
429 Rate Limited Too many requests in time window Wait for window to reset
400 Bad Request Invalid or missing parameters Check request format
404 Not Found User/resource not found (minimal info) Verify user exists
401 Unauthorized Authentication required or failed Provide valid credentials

📊 Server Configuration

Default Port: 5000 (configurable via PORT environment variable)

AI Provider: DeepSeek API (fallback to Claude CLI)

Authentication: Firebase Auth with custom REST API integration

Database: Firestore for user data and credit management

Payments: Stripe Checkout with webhook processing

Logging: JSON lines format to claude_logs.jsonl

✅ Environment Variables Required