API Comparison: Two Paths for Document Processing

Home Insight AI provides two different API paths for document analysis, each designed for specific use cases. Understanding which one to use is critical for optimal performance and user experience.

Quick Decision Guide

┌─────────────────────────────────────────┐
│ Need to upload 1 document?              │
│ Building a B2B API integration?         │
│ Want manual control over processing?    │
└─────────────────┬───────────────────────┘
                  ↓ YES
        Use /v1/analyses (Low-Level API)


┌─────────────────────────────────────────┐
│ Need to upload 5-50 documents?          │
│ Building a portal/UI for end users?     │
│ Want automatic smart categorization?    │
└─────────────────┬───────────────────────┘
                  ↓ YES
  Use /v1/properties/{id}/upload (High-Level API)

Path 1: Analyses API (Low-Level / B2B)

Endpoint: POST /v1/analyses

Use Cases

  • SDK/API Integrations: External developers embedding via API
  • Single-file uploads: One document at a time
  • Manual processing control: Trigger processing explicitly
  • Custom workflows: Full control over each step

Characteristics

  • ✅ Single file per request
  • ✅ Synchronous or manual processing trigger
  • ✅ Simple, straightforward workflow
  • ✅ Direct control over analysis timing
  • ❌ No automatic categorization
  • ❌ Slower for bulk uploads (sequential)
  • ❌ More API calls required

Summary Storage

Location: analyses.metadata.summary

JSON
{
  "metadata": {
    "summary": "This is a home inspection report for...",
    "key_points": ["Finding 1", "Finding 2"],
    "issues": [...],
    "document_type": "inspection_report"
  }
}

Example Workflow

Shell
# Step 1: Upload single document
curl -X POST https://api.homeinsightai.com/v1/analyses \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -F "file=@inspection.pdf" \
  -F "property_address=123 Main St"

# Response
{
  "analysis_id": "ana_abc123",
  "page_count": 25,
  "total_bytes": 2458923,
  "message": "Successfully processed 25 pages"
}

# Step 2: Get results (summary in metadata)
curl https://api.homeinsightai.com/v1/analyses/ana_abc123 \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

# Response
{
  "analysis_id": "ana_abc123",
  "status": "completed",
  "summary": "This is a home inspection...",  # Also in metadata.summary
  "total_issues": 12,
  "severity": "critical"
}

# Step 3: Get structured issues
curl https://api.homeinsightai.com/v1/analyses/ana_abc123/issues \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

When to use:

  • Building SDKs or API wrappers
  • Single-document processing
  • Need full control over timing
  • Simple integrations

Path 2: Properties API (High-Level / Portal)

Endpoint: POST /v1/properties/{property_id}/upload

Use Cases

  • Portal/UI Applications: End-user facing applications
  • Bulk document uploads: 5-50 documents at once
  • CRM integrations: Real estate platforms, MLS systems
  • Automatic workflows: Let the system handle everything

Characteristics

  • ✅ Multi-file batch upload (up to 50 PDFs)
  • ✅ Automatic smart categorization (critical/important/optional/noise)
  • ✅ Background parallel processing
  • ✅ 6-9x faster than sequential uploads
  • ✅ 74% fewer API calls
  • ✅ Property-based organization
  • ❌ More complex response structure
  • ❌ Requires property creation first

Summary Storage

Location: analyses.summary (top-level column)

JSON
{
  "id": "ana_abc123",
  "summary": "This is a home inspection report for...",  # Top-level column
  "document_type": "inspection_report",
  "metadata": {
    "filename": "inspection.pdf",
    "page_count": 25,
    "key_points": ["Finding 1", "Finding 2"]
  }
}

Example Workflow

Shell
# Step 1: Create property (one-time)
curl -X POST https://api.homeinsightai.com/v1/properties \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "listing_12345",
    "address": "123 Main St, San Francisco, CA 94102"
  }'

# Response
{
  "id": "prop_abc123",
  "external_id": "listing_12345",
  "address": "123 Main St",
  "city": "San Francisco",
  "state": "CA",
  "zip_code": "94102",
  "country": "US",
  "document_count": 0,
  "created_at": "2025-12-03T...",
  "updated_at": "2025-12-03T..."
}

# Step 2: Upload all documents in one batch
curl -X POST "https://api.homeinsightai.com/v1/properties/prop_abc123/upload" \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY" \
  -F "files=@Home_Inspection_Report.pdf" \
  -F "files=@Loan_Estimate.pdf" \
  -F "files=@Seller_Disclosure.pdf" \
  -F "files=@Purchase_Agreement.pdf" \
  -F "files=@Receipt_Earnest.pdf"

# Response (instant - processing happens in background)
{
  "property_id": "prop_abc123",
  "documents_uploaded": 5,
  "documents_categorized": 5,
  "queued_for_analysis": 3,  # Only critical/important
  "documents": [
    {
      "id": "ana_1a2b3c",
      "filename": "Home_Inspection_Report.pdf",
      "category": "critical",  # Auto-detected
      "is_analyzed": false,
      "confidence": 0.95
    },
    {
      "id": "ana_2b3c4d",
      "filename": "Loan_Estimate.pdf",
      "category": "important",  # Auto-detected
      "is_analyzed": false,
      "confidence": 0.90
    },
    {
      "id": "ana_3c4d5e",
      "filename": "Seller_Disclosure.pdf",
      "category": "critical",  # Auto-detected
      "is_analyzed": false,
      "confidence": 0.95
    },
    {
      "id": "ana_4d5e6f",
      "filename": "Purchase_Agreement.pdf",
      "category": "optional",  # Will analyze on-demand
      "is_analyzed": false,
      "confidence": 0.80
    },
    {
      "id": "ana_5e6f7g",
      "filename": "Receipt_Earnest.pdf",
      "category": "noise",  # Skipped
      "is_analyzed": false,
      "confidence": 0.92
    }
  ]
}

# Step 3: Poll document status (check every 5-10 seconds)
curl https://api.homeinsightai.com/v1/properties/prop_abc123/documents \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

# Response
{
  "property_id": "prop_abc123",
  "documents": [
    {
      "id": "ana_1a2b3c",
      "status": "completed",  # Analysis finished
      "filename": "Home_Inspection_Report.pdf"
    },
    {
      "id": "ana_2b3c4d",
      "status": "processing",  # Still analyzing
      "filename": "Loan_Estimate.pdf"
    }
  ],
  "total": 5
}

# Step 4: Get combined summary (all documents)
curl https://api.homeinsightai.com/v1/properties/prop_abc123/summary \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

# Step 5: Get issues with page numbers
curl https://api.homeinsightai.com/v1/analyses/ana_1a2b3c/issues \
  -H "Authorization: Bearer hi_live_YOUR_API_KEY"

When to use:

  • Building end-user portals
  • Real estate platforms
  • Bulk document processing
  • CRM integrations
  • Need automatic categorization

Side-by-Side Comparison

FeatureAnalyses APIProperties API
EndpointPOST /v1/analysesPOST /v1/properties/{id}/upload
Files per request1 PDF1-50 PDFs
ProcessingSynchronous or manual triggerAutomatic background
CategorizationNone (manual)Automatic (60+ patterns)
Analysis timingImmediateSmart (critical/important only)
Response time15-30s (blocking)2-5s (instant, bg processing)
Summary locationmetadata.summarysummary (top-level)
Use caseB2B API integrationsPortal/UI applications
Speed (50 docs)1500-3000s (sequential)150-300s (parallel)
API efficiency500 calls130 calls (74% reduction)

Key Differences Explained

1. Summary Data Location

This is the most confusing difference:

Analyses API:

JSON
{
  "id": "ana_abc123",
  "metadata": {
    "summary": "Home inspection report identifying 12 issues...",
    "issues": [...]
  }
}

Properties API:

JSON
{
  "id": "ana_abc123",
  "summary": "Home inspection report identifying 12 issues...",  // Top-level
  "metadata": {
    "filename": "inspection.pdf",
    "page_count": 25
  }
}

Why the difference?

  • Analyses API evolved from single-document design
  • Properties API standardized on top-level summary for consistency
  • Both work correctly, just different schema

Accessing summary in code:

JavaScript
// Analyses API
const summary = analysis.metadata?.summary || analysis.summary;

// Properties API
const summary = analysis.summary;  // Always top-level

2. Processing Model

Analyses API (Blocking):

Upload → Process → Return results (15-30s)

Properties API (Non-blocking):

Upload → Return immediately (2s)
      ↓
Background: Categorize → Queue critical/important → Process (15-30s each)

3. Categorization

Analyses API:

  • No categorization
  • All documents analyzed immediately
  • User decides what to upload

Properties API:

  • Automatic categorization based on 60+ filename patterns
  • Only critical/important analyzed automatically
  • Optional documents analyzed on-demand
  • Noise documents skipped

Categories:

  • critical: Inspection reports, disclosures (must analyze)
  • important: Loan docs, appraisals (should analyze)
  • optional: Purchase agreements (analyze if asked)
  • noise: Receipts, HOA rules (skip analysis)

Migration Guide

Upgrading from Analyses to Properties API

If you're currently using the Analyses API and want bulk upload:

Before (Sequential):

JavaScript
// Upload 10 documents one-by-one (slow)
for (const file of files) {
  await fetch('/v1/analyses', {
    method: 'POST',
    body: createFormData(file)
  });
}
// Total time: 150-300 seconds
// API calls: 10

After (Parallel):

JavaScript
// Upload all documents at once (fast)
const formData = new FormData();
files.forEach(f => formData.append('files', f));

await fetch(`/v1/properties/${propertyId}/upload`, {
  method: 'POST',
  body: formData
});
// Total time: 2-5 seconds (instant)
// API calls: 1
// Background processing: 15-30 seconds per critical doc

Migration checklist:

  1. ✅ Create property before uploading
  2. ✅ Update endpoint from /v1/analyses to /v1/properties/{id}/upload
  3. ✅ Support multiple file selection
  4. ✅ Handle documents array in response
  5. ✅ Poll /v1/properties/{id}/documents for status
  6. ✅ Adjust summary access (summary vs metadata.summary)
  7. ✅ Handle categorization results

Error Handling

Handling 409 Conflict - Property Already Exists

When creating a property with an external_id or address that already exists, the API returns a 409 Conflict error:

JSON
{
  "detail": "Property with this external_id or address already exists"
}

Best practice: Check if the property exists before creating it:

JavaScript
// Check if property exists by external_id
const getPropertyByExternalId = async (externalId: string) => {
  const response = await fetch(
    `https://api.homeinsightai.com/v1/properties?external_id=${externalId}`,
    {
      headers: { 'Authorization': `Bearer ${API_KEY}` }
    }
  );

  if (response.ok) {
    const data = await response.json();
    return data.properties[0]; // Returns existing property or undefined
  }
  return null;
};

// Recommended flow: Check before create
const analyzeDocuments = async (address: string, externalId: string, files: File[]) => {
  let propertyId: string;

  // Step 1: Check if property exists
  const existingProperty = await getPropertyByExternalId(externalId);

  if (existingProperty) {
    propertyId = existingProperty.id;  // Use .id NOT .property_id ✅
    console.log('Using existing property:', propertyId);
  } else {
    // Step 2: Create new property
    const newProperty = await fetch('https://api.homeinsightai.com/v1/properties', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        external_id: externalId,
        address: address
      })
    }).then(r => r.json());

    propertyId = newProperty.id;  // Use .id NOT .property_id ✅
    console.log('Created new property:', propertyId);
  }

  // Step 3: Upload documents
  const formData = new FormData();
  files.forEach(f => formData.append('files', f));

  const uploadResult = await fetch(
    `https://api.homeinsightai.com/v1/properties/${propertyId}/upload`,
    {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${API_KEY}` },
      body: formData
    }
  ).then(r => r.json());

  console.log(`Uploaded ${uploadResult.documents_uploaded} documents`);

  // Step 4: Poll for completion
  // ... (see polling examples above)
};

Alternative: Handle 409 gracefully

JavaScript
const createOrGetProperty = async (externalId: string, address: string) => {
  try {
    // Try to create
    const response = await fetch('https://api.homeinsightai.com/v1/properties', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ external_id: externalId, address })
    });

    if (response.ok) {
      const property = await response.json();
      return property.id;  // ✅ Use .id field
    }

    // Handle 409 Conflict
    if (response.status === 409) {
      console.log('Property exists, fetching...');
      const existing = await getPropertyByExternalId(externalId);
      return existing.id;  // ✅ Use .id field
    }

    throw new Error(`Failed to create property: ${response.status}`);
  } catch (error) {
    console.error('Error creating/getting property:', error);
    throw error;
  }
};

Complete Endpoint Reference

| Action | Endpoint | Description | |--------|----------|-------------| | List/Search | GET /v1/properties?external_id=xxx | Check if property exists | | Get by ID | GET /v1/properties/{id} | Get property details | | Create | POST /v1/properties | Create new property (returns id field) | | Upload docs | POST /v1/properties/{id}/upload | Add documents (batch) | | Get docs | GET /v1/properties/{id}/documents | Poll document status |

IMPORTANT: The property creation response returns id, NOT property_id:

TypeScript
// ❌ WRONG
const propertyId = propertyResponse.property_id;  // undefined!

// ✅ CORRECT
const propertyId = propertyResponse.id;  // Works!

FAQ

Q: Which API should I use for my app?

Use Analyses API if:

  • Building an SDK or API wrapper
  • Single-document uploads only
  • Need immediate processing
  • Simple, straightforward workflow

Use Properties API if:

  • Building an end-user portal
  • Uploading 5+ documents at once
  • Want automatic categorization
  • Need best performance

Q: Can I use both APIs together?

Yes! Common pattern:

  • Use Properties API for bulk uploads
  • Use Analyses API for single-file additions later

Q: Why is summary in different locations?

Historical reasons. The Analyses API originally stored everything in metadata. The Properties API standardized on top-level summary. Both work, just access differently.

Q: How do I handle the summary difference in my code?

Use a fallback:

JavaScript
const summary = analysis.summary || analysis.metadata?.summary;

Q: Which API is faster?

Properties API is 6-9x faster for bulk uploads due to:

  • Parallel background processing
  • Automatic categorization (no wasted analysis)
  • Single HTTP request for multiple files

Q: Do both APIs cost the same?

Yes. Billing is property-based, not per-file. Each unique property counts once per month regardless of which API you use.


Next Steps


Need help deciding? Contact us at support@homeinsightai.com

API Comparison: Analyses vs Properties - Home Insight AI Documentation