Skip to main content

Overview

The Generate Report endpoint creates a new PDF report by processing analytics data from Google Search Console, Google Analytics 4, and PageSpeed Insights. The API generates AI-powered insights using Claude, creates a branded PDF using React-PDF, stores it in Vercel Blob storage, and saves metadata to the database. Key Features:
  • Multi-report type support (executive, standard, custom)
  • AI-powered insights with Claude API
  • White-label branding configuration
  • Plan-based access control and rate limiting
  • Automatic PDF storage and download
  • Comprehensive error handling

Endpoint

POST /api/generate-pdf

Authentication

Requires authentication via NextAuth.js session cookie. User must:
  • Be authenticated with a valid session
  • Have email verified (emailVerified: true)
  • Have available report quota based on plan

Request Body

clientId
string
required
The unique identifier of the client for whom the report is being generated. Must belong to the authenticated user.
clientName
string
required
Display name of the client for the report header and filename.
startDate
string
required
Start date of the reporting period in ISO 8601 format (e.g., 2024-01-01).
endDate
string
required
End date of the reporting period in ISO 8601 format (e.g., 2024-01-31).
reportType
enum
default:"standard"
Type of report to generate:
  • executive - Quick 2-3 page overview with key metrics
  • standard - Comprehensive 5-7 page report with detailed analytics
  • custom - Tailored report with user-selected metrics (requires STARTER plan or higher)

Analytics Data

gscData
object
required
Google Search Console metrics (required for all reports):
ga4Data
object
required
Google Analytics 4 metrics with flexible schema:Supports additional dynamic fields like newUsers, engagementRate, organicTraffic, etc.
pageSpeedData
object
PageSpeed Insights performance metrics (optional):

Custom Report Options

selectedMetrics
array
Array of metric identifiers to include in custom reports. Only used when reportType: "custom".
customFields
array
Array of custom content sections:
{
  title: string
  content: string
  type: 'insight' | 'recommendation' | 'metric'
}

Branding Override

agencyName
string
Override for agency name (defaults to user’s companyName)
Override for agency logo URL (defaults to user’s logo)

Response

Success Response (200 OK)

Returns the generated PDF file as binary data with metadata in headers: Headers:
Content-Type: application/pdf
Content-Disposition: attachment; filename="{clientName}_{reportType}_Report_{startDate}_to_{endDate}.pdf"
Content-Length: {pdfSizeInBytes}
X-Report-ID: {reportId}
X-Blob-URL: {vercelBlobUrl}
X-Processing-Time: {milliseconds}
X-Generator: react-pdf
X-Request-ID: {uuid}
Body: Binary PDF file

Error Responses

{
  "error": "Invalid request data",
  "details": [
    {
      "field": "gscData.clicks",
      "message": "Expected number, received string"
    }
  ]
}

Plan Limits

PlanReports/CycleCustom Reports
FREE5No
STARTER25Yes
PROFESSIONAL100Yes
AGENCYUnlimitedYes

Report Generation Process

  1. Authentication & Validation
    • Verify user session and email verification
    • Check plan limits and report quota
    • Validate request data against Zod schema
    • Verify client ownership
  2. AI Insights Generation
    • Sends analytics data to Claude API
    • Generates 4-6 strategic insights
    • Categorizes insights (keyword, technical, content, performance)
    • Estimates cost and tracks token usage
    • Falls back gracefully if AI generation fails
  3. PDF Creation
    • Merges GA4 data from multiple sources
    • Applies user’s white-label branding settings
    • Renders PDF using React-PDF templates
    • Includes AI insights, charts, and data tables
  4. Storage & Database
    • Uploads PDF to Vercel Blob storage
    • Saves report metadata to PostgreSQL
    • Updates client statistics
    • Tracks processing time and file size
  5. Response
    • Returns PDF file for immediate download
    • Provides metadata in response headers
    • Includes report ID for status tracking

Example Request

curl -X POST https://your-domain.com/api/generate-pdf \
  -H "Content-Type: application/json" \
  -H "Cookie: next-auth.session-token=..." \
  -d '{
    "clientId": "clx1234567890",
    "clientName": "Acme Corp",
    "startDate": "2024-01-01",
    "endDate": "2024-01-31",
    "reportType": "standard",
    "gscData": {
      "clicks": 12500,
      "impressions": 450000,
      "ctr": 0.0278,
      "position": 8.5,
      "topQueries": [
        {
          "query": "seo services",
          "clicks": 1250,
          "impressions": 45000,
          "ctr": 0.0278,
          "position": 5.2
        }
      ],
      "dailyData": [
        {
          "date": "2024-01-01",
          "clicks": 400,
          "impressions": 15000,
          "ctr": 0.0267,
          "position": 8.7
        }
      ]
    },
    "ga4Data": {
      "users": 8500,
      "sessions": 12000,
      "bounceRate": 0.42,
      "conversions": 150,
      "newUsers": 5200,
      "engagementRate": 0.68,
      "topLandingPages": [
        {
          "page": "/services",
          "sessions": 3200,
          "users": 2800,
          "bounceRate": 0.35,
          "conversions": 45
        }
      ],
      "deviceBreakdown": {
        "mobile": 5100,
        "desktop": 2800,
        "tablet": 600
      }
    },
    "pageSpeedData": {
      "mobile": {
        "score": 78,
        "lcp": 2.4,
        "fid": 85,
        "cls": 0.08
      },
      "desktop": {
        "score": 92,
        "lcp": 1.2,
        "fid": 45,
        "cls": 0.03
      },
      "opportunities": [
        {
          "title": "Reduce unused JavaScript",
          "description": "Reduce unused JavaScript and defer loading scripts until they are required to decrease bytes consumed by network activity.",
          "displayValue": "Potential savings of 125 KiB"
        }
      ],
      "fetchedAt": "2024-02-01T10:30:00Z"
    }
  }' \
  -o report.pdf

White-Label Branding

The API automatically applies the user’s white-label branding settings from the database:
  • Company Name: Falls back to “Reportr” if white-label disabled
  • Logo: Uses user’s uploaded logo or default Reportr logo
  • Primary Color: Applies to charts, headers, and accent elements
  • Website/Email: Displayed in report footer
  • Powered By: Hidden when white-label is enabled

Performance Characteristics

  • Typical generation time: 15-45 seconds
  • Maximum duration: 60 seconds (serverless timeout)
  • Average PDF size: 150KB - 2MB (depending on report type)
  • AI insights generation: 3-8 seconds
  • React-PDF rendering: 5-15 seconds
  • Blob storage upload: 1-3 seconds

Build docs developers (and LLMs) love