Skip to content

Latest commit

 

History

History
886 lines (708 loc) · 16.7 KB

File metadata and controls

886 lines (708 loc) · 16.7 KB

Submittal Review Assistant - API Documentation

Comprehensive API reference for the Submittal Review Assistant backend

Table of Contents


Overview

The Submittal Review Assistant API is a RESTful API built with FastAPI that provides endpoints for managing construction projects, specifications, submittals, and AI-powered cross-reference analysis.

Key Features:

  • Multi-tenant architecture with company isolation
  • Role-based access control (Admin, Project Manager, Contractor, Viewer)
  • JWT-based authentication via Supabase
  • AI-powered document analysis using OpenAI GPT-4o
  • Async document processing with Redis job queue
  • Real-time cost tracking and budgeting

Authentication

All API endpoints (except health checks) require authentication via Supabase JWT tokens.

Getting a Token

  1. Sign in via Supabase:
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password'
});
const token = data.session.access_token;
  1. Include token in requests:
Authorization: Bearer <token>

Registering a New User

After creating a user in Supabase, register them in the system:

POST /api/v1/users/register
Content-Type: application/json
Authorization: Bearer <token>

{
  "company_id": "uuid-of-company",
  "full_name": "John Doe",
  "role": "project_manager"
}

Base URL

Development: http://localhost:8000

Production: https://your-domain.com

API Version: All endpoints are prefixed with /api/v1 except health checks.


Common Response Formats

Success Response

{
  "id": "uuid",
  "name": "Project Name",
  "created_at": "2026-01-31T12:00:00Z",
  ...
}

List Response

{
  "items": [...],
  "total": 100,
  "page": 1,
  "page_size": 20
}

Error Response

{
  "detail": "Error message describing what went wrong"
}

Error Handling

The API uses standard HTTP status codes:

Code Meaning Description
200 OK Request succeeded
201 Created Resource created successfully
400 Bad Request Invalid request data
401 Unauthorized Missing or invalid authentication
403 Forbidden Insufficient permissions
404 Not Found Resource not found
409 Conflict Resource already exists
422 Unprocessable Entity Validation error
500 Internal Server Error Server error

Endpoints by Category

Health Endpoints

Get Health Status

Check if the API is running.

GET /health

Response:

{
  "status": "healthy",
  "timestamp": "2026-01-31T12:00:00Z"
}

Get Readiness Status

Check if the API is ready to serve requests (database connected).

GET /health/ready

Response:

{
  "status": "ready",
  "database": "connected",
  "timestamp": "2026-01-31T12:00:00Z"
}

Get Liveness Status

Check if the API is alive (for Kubernetes probes).

GET /health/live

Response:

{
  "status": "alive"
}

User Endpoints

Get Current User

Get the authenticated user's profile.

GET /api/v1/users/me
Authorization: Bearer <token>

Response:

{
  "id": "uuid",
  "supabase_user_id": "uuid",
  "company_id": "uuid",
  "full_name": "John Doe",
  "email": "john@example.com",
  "role": "project_manager",
  "is_active": true,
  "created_at": "2026-01-31T12:00:00Z",
  "updated_at": "2026-01-31T12:00:00Z"
}

List Users (Admin Only)

List all users in the company.

GET /api/v1/users?skip=0&limit=20
Authorization: Bearer <token>

Query Parameters:

  • skip (optional): Number of records to skip (default: 0)
  • limit (optional): Number of records to return (default: 20, max: 100)

Response:

[
  {
    "id": "uuid",
    "full_name": "John Doe",
    "email": "john@example.com",
    "role": "project_manager",
    "is_active": true
  },
  ...
]

Create User (Admin Only)

Create a new user in the system.

POST /api/v1/users
Authorization: Bearer <token>
Content-Type: application/json

{
  "supabase_user_id": "uuid-from-supabase",
  "company_id": "uuid",
  "full_name": "Jane Smith",
  "email": "jane@example.com",
  "role": "contractor"
}

Roles: admin, project_manager, contractor, viewer

Response: 201 Created

{
  "id": "uuid",
  "supabase_user_id": "uuid",
  "company_id": "uuid",
  "full_name": "Jane Smith",
  "email": "jane@example.com",
  "role": "contractor",
  "is_active": true,
  "created_at": "2026-01-31T12:00:00Z"
}

Project Endpoints

List Projects

Get all projects the user has access to.

GET /api/v1/projects?skip=0&limit=20
Authorization: Bearer <token>

Response:

[
  {
    "id": "uuid",
    "company_id": "uuid",
    "name": "Downtown Office Building",
    "number": "PROJ-2026-001",
    "location": "123 Main St, City, State",
    "description": "New construction office building",
    "is_active": true,
    "created_at": "2026-01-15T10:00:00Z",
    "updated_at": "2026-01-31T12:00:00Z"
  },
  ...
]

Create Project

Create a new project.

POST /api/v1/projects
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Downtown Office Building",
  "number": "PROJ-2026-001",
  "location": "123 Main St, City, State",
  "description": "New construction office building"
}

Response: 201 Created

Get Project

Get a specific project by ID.

GET /api/v1/projects/{project_id}
Authorization: Bearer <token>

Update Project

Update project details.

PATCH /api/v1/projects/{project_id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Updated Project Name",
  "is_active": false
}

Delete Project

Delete a project (soft delete).

DELETE /api/v1/projects/{project_id}
Authorization: Bearer <token>

Response: 204 No Content


Spec Section Endpoints

List Spec Sections

Get all spec sections for a project.

GET /api/v1/spec-sections?project_id=<uuid>&skip=0&limit=20
Authorization: Bearer <token>

Query Parameters:

  • project_id (required): Filter by project
  • skip, limit: Pagination

Response:

[
  {
    "id": "uuid",
    "project_id": "uuid",
    "section_number": "23 05 00",
    "title": "Common Work Results for HVAC",
    "description": "General HVAC requirements",
    "created_at": "2026-01-20T10:00:00Z"
  },
  ...
]

Create Spec Section

Create a new specification section.

POST /api/v1/spec-sections
Authorization: Bearer <token>
Content-Type: application/json

{
  "project_id": "uuid",
  "section_number": "23 05 00",
  "title": "Common Work Results for HVAC",
  "description": "General HVAC requirements"
}

Upload Spec Document

Upload a specification document (PDF, Word, etc.).

POST /api/v1/documents/spec/{spec_section_id}
Authorization: Bearer <token>
Content-Type: multipart/form-data

file=@specification.pdf

Response: 201 Created

{
  "id": "uuid",
  "filename": "specification.pdf",
  "file_size": 1048576,
  "mime_type": "application/pdf",
  "storage_path": "specs/uuid/specification.pdf"
}

Download Spec Document

Download a specification document.

GET /api/v1/documents/spec/{spec_document_id}
Authorization: Bearer <token>

Response: Binary file with appropriate Content-Type header


Submittal Endpoints

List Submittals

Get all submittals for a project.

GET /api/v1/submittals?project_id=<uuid>&skip=0&limit=20
Authorization: Bearer <token>

Response:

[
  {
    "id": "uuid",
    "project_id": "uuid",
    "spec_section_id": "uuid",
    "submittal_number": "SUB-001",
    "title": "HVAC Equipment Schedule",
    "description": "Equipment data sheets",
    "status": "pending_review",
    "submitted_by": "uuid",
    "submitted_date": "2026-01-25T10:00:00Z",
    "created_at": "2026-01-25T10:00:00Z"
  },
  ...
]

Submittal Statuses:

  • draft
  • submitted
  • pending_review
  • under_review
  • reviewed
  • approved
  • approved_as_noted
  • rejected
  • revise_and_resubmit

Create Submittal

Create a new submittal.

POST /api/v1/submittals
Authorization: Bearer <token>
Content-Type: application/json

{
  "project_id": "uuid",
  "spec_section_id": "uuid",
  "submittal_number": "SUB-001",
  "title": "HVAC Equipment Schedule",
  "description": "Equipment data sheets",
  "status": "submitted"
}

Upload Submittal Document

Upload a submittal document.

POST /api/v1/documents/submittal/{submittal_revision_id}
Authorization: Bearer <token>
Content-Type: multipart/form-data

file=@submittal.pdf

Processing Endpoints

Process Document (Sync)

Process a document synchronously and return extracted text.

POST /api/v1/processing/upload
Authorization: Bearer <token>
Content-Type: multipart/form-data

file=@document.pdf

Response:

{
  "text": "Extracted text content...",
  "page_count": 10,
  "processing_time": 2.5,
  "method": "pymupdf"
}

Process Document (Async)

Queue a document for background processing.

POST /api/v1/processing/upload/async
Authorization: Bearer <token>
Content-Type: multipart/form-data

file=@document.pdf

Response:

{
  "job_id": "uuid",
  "status": "queued",
  "message": "Document processing job queued"
}

Get Job Status

Check the status of a processing job.

GET /api/v1/processing/status/{job_id}
Authorization: Bearer <token>

Response:

{
  "job_id": "uuid",
  "status": "completed",
  "progress": 100,
  "message": "Processing completed successfully",
  "created_at": "2026-01-31T12:00:00Z",
  "completed_at": "2026-01-31T12:01:30Z"
}

Job Statuses: queued, processing, completed, failed

Get Processing Result

Get the result of a completed processing job.

GET /api/v1/processing/result/{job_id}
Authorization: Bearer <token>

Response:

{
  "text": "Extracted text...",
  "page_count": 10,
  "processing_time": 90.5
}

AI Review Endpoints

Start AI Review

Start an AI-powered cross-reference review.

POST /api/v1/reviews
Authorization: Bearer <token>
Content-Type: application/json

{
  "submittal_id": "uuid",
  "spec_section_ids": ["uuid1", "uuid2"],
  "review_mode": "standard"
}

Review Modes:

  • quick: Fast review with GPT-4o-mini
  • standard: Balanced review with mixed models
  • thorough: Detailed review with GPT-4o

Response: 201 Created

{
  "id": "uuid",
  "submittal_id": "uuid",
  "status": "completed",
  "total_findings": 15,
  "compliant": 12,
  "non_compliant": 2,
  "missing": 1,
  "ambiguous": 0,
  "total_cost_usd": 0.45,
  "created_at": "2026-01-31T12:00:00Z",
  "completed_at": "2026-01-31T12:02:30Z"
}

Get Review Details

Get a review with all findings.

GET /api/v1/reviews/{review_id}
Authorization: Bearer <token>

Response:

{
  "id": "uuid",
  "submittal_id": "uuid",
  "status": "completed",
  "findings": [
    {
      "id": "uuid",
      "requirement_text": "Equipment shall meet ASHRAE 90.1 efficiency standards",
      "submittal_data": "EER: 12.5, meets ASHRAE 90.1-2019",
      "compliance_status": "compliant",
      "confidence_score": 0.95,
      "ai_explanation": "The submittal clearly states compliance...",
      "severity": "medium"
    },
    ...
  ],
  "summary": {
    "total_findings": 15,
    "compliant": 12,
    "non_compliant": 2,
    "missing": 1
  }
}

Get Review Findings

List findings for a review with filtering.

GET /api/v1/reviews/{review_id}/findings?status=non_compliant&severity=high
Authorization: Bearer <token>

Query Parameters:

  • status: Filter by compliance status (compliant, non_compliant, missing, ambiguous)
  • severity: Filter by severity (low, medium, high, critical)
  • skip, limit: Pagination

Update Finding

Update a finding (human review/override).

PATCH /api/v1/reviews/findings/{finding_id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "human_review_status": "confirmed",
  "human_review_notes": "Verified with engineer",
  "compliance_status": "compliant"
}

Get Cost Dashboard

Get real-time cost tracking dashboard.

GET /api/v1/reviews/costs/dashboard
Authorization: Bearer <token>

Response:

{
  "today_cost_usd": 12.50,
  "month_cost_usd": 450.75,
  "daily_budget_usd": 50.00,
  "monthly_budget_usd": 1000.00,
  "daily_budget_remaining": 37.50,
  "monthly_budget_remaining": 549.25,
  "total_reviews_today": 25,
  "total_reviews_month": 450
}

Notification Endpoints

Get Notification Status

Check if email notifications are configured.

GET /api/v1/notifications/status
Authorization: Bearer <token>

Response:

{
  "configured": true,
  "email_provider": "resend",
  "from_address": "noreply@example.com"
}

Send Test Email (Admin Only)

Send a test email to verify configuration.

POST /api/v1/notifications/test
Authorization: Bearer <token>
Content-Type: application/json

{
  "to": "test@example.com"
}

Response:

{
  "success": true,
  "message": "Test email sent successfully",
  "email_id": "re_abc123xyz"
}

Send Review Completion Notification

Send an email notification when a review is complete.

POST /api/v1/notifications/review-complete
Authorization: Bearer <token>
Content-Type: application/json

{
  "to": "pm@example.com",
  "project_name": "Downtown Office Building",
  "submittal_number": "SUB-001",
  "submittal_title": "HVAC Equipment",
  "compliance_status": "compliant",
  "compliant_count": 12,
  "noncompliant_count": 2,
  "missing_count": 1,
  "ambiguous_count": 0,
  "review_url": "https://app.example.com/reviews/uuid"
}

Rate Limits

To ensure fair usage and system stability, the following rate limits apply:

Endpoint Category Limit Window
Document Processing 100 requests 1 hour
AI Reviews 50 reviews 24 hours
General API 1000 requests 1 hour

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1706716800

Interactive Documentation

Swagger UI: Visit /docs for interactive API documentation where you can test endpoints directly.

ReDoc: Visit /redoc for alternative API documentation with a cleaner reading experience.


SDK Examples

Python Example

import requests

BASE_URL = "http://localhost:8000"
TOKEN = "your-jwt-token"

headers = {
    "Authorization": f"Bearer {TOKEN}",
    "Content-Type": "application/json"
}

# Create a project
response = requests.post(
    f"{BASE_URL}/api/v1/projects",
    headers=headers,
    json={
        "name": "Test Project",
        "number": "PROJ-001",
        "location": "New York, NY"
    }
)
project = response.json()
print(f"Created project: {project['id']}")

# Start an AI review
response = requests.post(
    f"{BASE_URL}/api/v1/reviews",
    headers=headers,
    json={
        "submittal_id": "uuid",
        "spec_section_ids": ["uuid1"],
        "review_mode": "standard"
    }
)
review = response.json()
print(f"Review status: {review['status']}")

JavaScript/TypeScript Example

const BASE_URL = 'http://localhost:8000';
const TOKEN = 'your-jwt-token';

const headers = {
  'Authorization': `Bearer ${TOKEN}`,
  'Content-Type': 'application/json'
};

// Get current user
const response = await fetch(`${BASE_URL}/api/v1/users/me`, { headers });
const user = await response.json();
console.log(`Logged in as: ${user.full_name}`);

// List projects
const projectsResponse = await fetch(`${BASE_URL}/api/v1/projects`, { headers });
const projects = await projectsResponse.json();
console.log(`Found ${projects.length} projects`);

Webhooks (Future)

Webhook support is planned for future releases to enable real-time notifications for:

  • Review completion
  • Document processing completion
  • Cost threshold alerts

Support & Resources


Last updated: January 31, 2026