Skip to Content
Docs are evolving — expect frequent updates.
CompanySearch Companies

Search Companies

Search for companies across your portfolio using keywords. Filter by project name, company, status, and other criteria with full pagination support.

Endpoint

GET https://api.kruncher.ai/api/integration/project/search

Headers

HeaderRequiredDescription
AuthorizationYesYour API key (format: YOUR_API_KEY)
Content-TypeNoOptional application/json

Query Parameters

ParameterTypeRequiredDescription
keywordsstringYesSearch terms to filter projects (space-separated, supports partial matching)
pageintegerNoPage number for pagination (defaults to 0, zero-indexed)
limitintegerNoResults per page (defaults to 20, max 100)
statusstringNoFilter by project status (e.g., screening, diligence, invested)
sortBystringNoSort field (e.g., name, createdAt, updatedAt)
sortOrderstringNoSort order: asc or desc (defaults to asc)

Use Cases

  • Portfolio Search: Find specific projects in your portfolio
  • Quick Lookup: Search by company name or project identifier
  • Status Filtering: Find projects in specific stages
  • Bulk Review: Paginate through search results
  • Reporting: Extract project data for analysis
  • Integration: Sync projects with external systems

Quick Start

cURL

CODE
# Basic search
curl -X GET "https://api.kruncher.ai/api/integration/project/search?keywords=tesla" \
  -H "Authorization: YOUR_API_KEY_HERE"
 
# Search with pagination
curl -X GET "https://api.kruncher.ai/api/integration/project/search?keywords=tech&page=1&limit=50" \
  -H "Authorization: YOUR_API_KEY_HERE"
 
# Search with status filter
curl -X GET "https://api.kruncher.ai/api/integration/project/search?keywords=startup&status=diligence" \
  -H "Authorization: YOUR_API_KEY_HERE"
 
# Search with sorting
curl -X GET "https://api.kruncher.ai/api/integration/project/search?keywords=market&sortBy=updatedAt&sortOrder=desc" \
  -H "Authorization: YOUR_API_KEY_HERE"

Response:

CODE
{
  "success": true,
  "data": {
    "results": [
      {
        "id": "proj_abc123",
        "name": "Tesla Energy",
        "company": "Tesla Inc",
        "status": "diligence",
        "stage": "Series C",
        "createdAt": "2024-01-10T14:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z"
      },
      {
        "id": "proj_def456",
        "name": "Tesla Motors Alternative",
        "company": "TeslaTech",
        "status": "screening",
        "stage": "Seed",
        "createdAt": "2024-01-12T09:15:00Z",
        "updatedAt": "2024-01-14T16:45:00Z"
      }
    ],
    "pagination": {
      "page": 0,
      "limit": 20,
      "total": 2,
      "totalPages": 1,
      "hasNext": false,
      "hasPrev": false
    }
  }
}

Code Examples

JavaScript/Node.js

CODE
const API_KEY = "YOUR_API_KEY_HERE";
const BASE_URL = "https://api.kruncher.ai/api";
 
async function searchProjects(keywords, page = 0, limit = 20) {
  const params = new URLSearchParams({
    keywords,
    page,
    limit
  });
 
  const response = await fetch(
    `${BASE_URL}/integration/project/search?${params}`,
    {
      method: "GET",
      headers: {
        "Authorization": `${API_KEY}`,
        "Content-Type": "application/json"
      }
    }
  );
 
  if (!response.ok) {
    throw new Error(`Search failed: ${response.statusText}`);
  }
 
  return await response.json();
}
 
// Usage - basic search
async function main() {
  try {
    const result = await searchProjects("tesla");
    console.log(`Found ${result.data.pagination.total} projects`);
    
    result.data.results.forEach(project => {
      console.log(`- ${project.name} (${project.status})`);
    });
  } catch (error) {
    console.error("Error:", error.message);
  }
}
 
main();

Advanced Search with Filtering

CODE
class ProjectSearch {
  constructor(apiKey, baseUrl = "https://api.kruncher.ai/api") {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }
 
  async search(options = {}) {
    const {
      keywords,
      page = 0,
      limit = 20,
      status = null,
      sortBy = "name",
      sortOrder = "asc"
    } = options;
 
    if (!keywords) {
      throw new Error("keywords parameter is required");
    }
 
    const params = new URLSearchParams({
      keywords,
      page,
      limit,
      sortBy,
      sortOrder
    });
 
    if (status) {
      params.append("status", status);
    }
 
    const response = await fetch(
      `${this.baseUrl}/integration/project/search?${params}`,
      {
        method: "GET",
        headers: {
          "Authorization": `${this.apiKey}`,
          "Content-Type": "application/json"
        }
      }
    );
 
    if (!response.ok) {
      throw new Error(`Search failed: ${response.statusText}`);
    }
 
    return await response.json();
  }
 
  async searchAll(keywords, status = null) {
    /**
     * Paginate through all results for a search
     */
    const allResults = [];
    let page = 0;
    let hasNext = true;
 
    while (hasNext) {
      const result = await this.search({
        keywords,
        page,
        limit: 100, // Max allowed
        status
      });
 
      allResults.push(...result.data.results);
      hasNext = result.data.pagination.hasNext;
      page++;
    }
 
    return allResults;
  }
 
  async findByName(projectName) {
    /**
     * Find a specific project by exact or partial name
     */
    const result = await this.search({
      keywords: projectName,
      limit: 10,
      sortBy: "name"
    });
 
    return result.data.results;
  }
 
  async findByStatus(status, keywords = null) {
    /**
     * Find all projects with a specific status
     */
    return await this.search({
      keywords: keywords || "*",
      status,
      limit: 100,
      sortBy: "updatedAt",
      sortOrder: "desc"
    });
  }
 
  async getStats(keywords) {
    /**
     * Get statistics about search results
     */
    const allResults = await this.searchAll(keywords);
 
    const stats = {
      total: allResults.length,
      byStatus: {},
      byStage: {},
      mostRecent: allResults.sort(
        (a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)
      )[0],
      oldestActive: allResults.sort(
        (a, b) => new Date(a.createdAt) - new Date(b.createdAt)
      )[0]
    };
 
    // Group by status
    allResults.forEach(project => {
      stats.byStatus[project.status] = (stats.byStatus[project.status] || 0) + 1;
      stats.byStage[project.stage] = (stats.byStage[project.stage] || 0) + 1;
    });
 
    return stats;
  }
}
 
// Usage
async function advancedSearch() {
  const search = new ProjectSearch("YOUR_API_KEY_HERE");
 
  try {
    // Find projects by name
    const projects = await search.findByName("Tesla");
    console.log("Projects:", projects);
 
    // Find all screening stage projects
    const screening = await search.findByStatus("screening");
    console.log(`Screening projects: ${screening.data.results.length}`);
 
    // Get all results (paginated automatically)
    const all = await search.searchAll("market");
    console.log(`Total market-related projects: ${all.length}`);
 
    // Get statistics
    const stats = await search.getStats("tech");
    console.log("Statistics:", stats);
  } catch (error) {
    console.error("Error:", error.message);
  }
}
 
advancedSearch();

Python

CODE
import requests
from typing import Optional, Dict, List
from urllib.parse import urlencode
 
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "https://api.kruncher.ai/api"
 
def search_projects(
    keywords: str,
    page: int = 0,
    limit: int = 20,
    status: Optional[str] = None,
    sort_by: str = "name",
    sort_order: str = "asc"
) -> Dict:
    """Search for projects with optional filtering."""
    
    headers = {
        "Authorization": f"{API_KEY}",
        "Content-Type": "application/json"
    }
    
    params = {
        "keywords": keywords,
        "page": page,
        "limit": limit,
        "sortBy": sort_by,
        "sortOrder": sort_order
    }
    
    if status:
        params["status"] = status
    
    response = requests.get(
        f"{BASE_URL}/integration/project/search",
        params=params,
        headers=headers
    )
    response.raise_for_status()
    
    return response.json()
 
# Usage
def main():
    try:
        result = search_projects("tesla")
        total = result['data']['pagination']['total']
        print(f"✓ Found {total} projects")
        
        for project in result['data']['results']:
            print(f"  - {project['name']} ({project['status']})")
    except Exception as error:
        print(f"✗ Error: {error}")
 
if __name__ == "__main__":
    main()

Python - Advanced Search Manager

CODE
import requests
from typing import Optional, Dict, List
from collections import defaultdict
 
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "https://api.kruncher.ai/api"
 
class ProjectSearchManager:
    """Manage project search with advanced features."""
    
    def __init__(self, api_key: str = API_KEY):
        self.api_key = api_key
        self.base_url = BASE_URL
        self.session = requests.Session()
        self.session.headers.update({
            "Authorization": f"{api_key}",
            "Content-Type": "application/json"
        })
    
    def search(
        self,
        keywords: str,
        page: int = 0,
        limit: int = 20,
        status: Optional[str] = None,
        sort_by: str = "name",
        sort_order: str = "asc"
    ) -> Dict:
        """Search companies with filtering options."""
        
        params = {
            "keywords": keywords,
            "page": page,
            "limit": limit,
            "sortBy": sort_by,
            "sortOrder": sort_order
        }
        
        if status:
            params["status"] = status
        
        response = self.session.get(
            f"{self.base_url}/integration/project/search",
            params=params
        )
        response.raise_for_status()
        
        return response.json()
    
    def search_all(self, keywords: str, status: Optional[str] = None) -> List[Dict]:
        """Get all results by paginating automatically."""
        
        all_results = []
        page = 0
        has_next = True
        
        while has_next:
            result = self.search(
                keywords=keywords,
                page=page,
                limit=100,
                status=status
            )
            
            all_results.extend(result['data']['results'])
            has_next = result['data']['pagination']['hasNext']
            page += 1
        
        return all_results
    
    def find_by_name(self, name: str) -> List[Dict]:
        """Find projects by name."""
        result = self.search(keywords=name, limit=10)
        return result['data']['results']
    
    def find_by_status(self, status: str, keywords: str = "*") -> List[Dict]:
        """Find all projects with specific status."""
        result = self.search(
            keywords=keywords,
            status=status,
            limit=100,
            sort_by="updatedAt",
            sort_order="desc"
        )
        return result['data']['results']
    
    def get_statistics(self, keywords: str) -> Dict:
        """Generate statistics for search results."""
        
        all_results = self.search_all(keywords)
        
        # Group by status and stage
        by_status = defaultdict(int)
        by_stage = defaultdict(int)
        
        for project in all_results:
            by_status[project['status']] += 1
            by_stage[project['stage']] += 1
        
        # Sort by date
        sorted_by_date = sorted(
            all_results,
            key=lambda x: x['updatedAt'],
            reverse=True
        )
        
        return {
            'total': len(all_results),
            'by_status': dict(by_status),
            'by_stage': dict(by_stage),
            'most_recent': sorted_by_date[0] if sorted_by_date else None,
            'oldest': sorted_by_date[-1] if sorted_by_date else None
        }
    
    def export_to_csv(self, keywords: str, filename: str = "projects.csv"):
        """Export search results to CSV."""
        import csv
        
        results = self.search_all(keywords)
        
        if not results:
            print("No results to export")
            return
        
        with open(filename, 'w', newline='') as f:
            writer = csv.DictWriter(
                f,
                fieldnames=['id', 'name', 'company', 'status', 'stage', 'createdAt']
            )
            writer.writeheader()
            writer.writerows(results)
        
        print(f"✓ Exported {len(results)} projects to {filename}")
 
# Usage
def main():
    manager = ProjectSearchManager()
    
    try:
        # Simple search
        projects = manager.find_by_name("Tesla")
        print(f"Found {len(projects)} projects named Tesla")
        
        # Get statistics
        stats = manager.get_statistics("market")
        print(f"Market projects: {stats['total']}")
        print(f"  By status: {stats['by_status']}")
        
        # Export results
        manager.export_to_csv("tech", "tech_projects.csv")
    
    except Exception as error:
        print(f"❌ Error: {error}")
 
if __name__ == "__main__":
    main()

Response Structure

Success Response (200 OK)

CODE
{
  "success": true,
  "data": {
    "results": [
      {
        "id": "proj_abc123",
        "name": "Tesla Energy",
        "company": "Tesla Inc",
        "status": "diligence",
        "stage": "Series C",
        "createdAt": "2024-01-10T14:30:00Z",
        "updatedAt": "2024-01-15T10:30:00Z",
        "description": "Energy storage solutions"
      }
    ],
    "pagination": {
      "page": 0,
      "limit": 20,
      "total": 42,
      "totalPages": 3,
      "hasNext": true,
      "hasPrev": false
    }
  }
}

Response Fields

FieldTypeDescription
resultsarrayArray of matching projects
idstringProject UUID
namestringProject name
companystringCompany name
statusstringCurrent project status
stagestringInvestment stage (Seed, Series A, etc.)
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last update timestamp

Pagination Fields

FieldTypeDescription
pageintegerCurrent page number
limitintegerResults per page
totalintegerTotal matching results
totalPagesintegerTotal number of pages
hasNextbooleanWhether next page exists
hasPrevbooleanWhether previous page exists

Error Responses

400 Bad Request - Missing Keywords

CODE
{
  "success": false,
  "error": "keywords parameter is required"
}

404 Not Found - No Results

CODE
{
  "success": true,
  "data": {
    "results": [],
    "pagination": {
      "page": 0,
      "limit": 20,
      "total": 0,
      "totalPages": 0,
      "hasNext": false,
      "hasPrev": false
    }
  }
}

Common Patterns

CODE
async function searchProjects(keywords) {
  const result = await searchProjects(keywords);
  return result.data.results;
}
 
// Usage
const projects = await searchProjects("market");

Pattern 2: Paginated Results

CODE
async function getPaginatedResults(keywords, pageSize = 50) {
  const allResults = [];
  let page = 0;
  let hasMore = true;
 
  while (hasMore) {
    const result = await searchProjects(keywords, page, pageSize);
    allResults.push(...result.data.results);
    hasMore = result.data.pagination.hasNext;
    page++;
  }
 
  return allResults;
}
CODE
def find_screening_projects():
    """Find all projects in screening stage."""
    manager = ProjectSearchManager()
    
    # Get all projects with screening status
    projects = manager.find_by_status("screening")
    
    # Sort by most recent
    projects.sort(key=lambda x: x['updatedAt'], reverse=True)
    
    return projects

Pattern 4: Search and Analyze

CODE
class ProjectAnalyzer {
  constructor(search) {
    this.search = search;
  }
 
  async analyzeKeyword(keyword) {
    const stats = await this.search.getStats(keyword);
    
    return {
      keyword,
      totalProjects: stats.total,
      byStatus: stats.byStatus,
      byStage: stats.byStage,
      recentActivity: stats.mostRecent.updatedAt
    };
  }
 
  async compareKeywords(keywords) {
    const comparisons = {};
    
    for (const keyword of keywords) {
      comparisons[keyword] = await this.analyzeKeyword(keyword);
    }
    
    return comparisons;
  }
}

Search Tips

Keyword Matching

  • Partial matching: “tes” will match “Tesla”
  • Multiple keywords: “market tech” searches for both
  • Exact phrases: Use quotes if supported: "Tesla Motors"

Sorting Options

Sort FieldDescription
nameProject name (alphabetical)
createdAtDate created
updatedAtLast updated
statusProject status

Status Values

StatusDescription
screeningInitial screening phase
diligenceDue diligence phase
investedActive investment
passedPassed to later stage
rejectedRejected
archivedArchived

Best Practices

Search Strategy

  • Start with broad keywords, then narrow down
  • Use status filters to focus on specific stages
  • Sort by updatedAt to find recent activity
  • Implement caching for repeated searches

Pagination

  • Use maximum limit (100) for bulk operations
  • Implement auto-pagination for large result sets
  • Cache pagination info for resume capability
  • Monitor total pages to estimate completion

Performance

  • Limit results per page (20-100)
  • Batch multiple searches if possible
  • Cache search results with TTL
  • Implement rate limiting on client side

Error Handling

Handling No Results

CODE
async function safeSearch(keywords) {
  try {
    const result = await searchProjects(keywords);
    
    if (result.data.results.length === 0) {
      console.log("No projects found. Try different keywords.");
      return [];
    }
    
    return result.data.results;
  } catch (error) {
    console.error("Search failed:", error.message);
    return [];
  }
}

Handling Pagination

CODE
def get_all_results_safely(keywords, max_pages=50):
    """Get all results with safety limits."""
    manager = ProjectSearchManager()
    all_results = []
    page = 0
    
    while page < max_pages:
        try:
            result = manager.search(keywords, page=page, limit=100)
            all_results.extend(result['data']['results'])
            
            if not result['data']['pagination']['hasNext']:
                break
            
            page += 1
        except Exception as error:
            print(f"Error on page {page}: {error}")
            break
    
    return all_results

Troubleshooting

No Results Found

  • Verify keyword spelling
  • Try partial keywords
  • Check project exists with different status
  • Try broader search terms

Pagination Issues

  • Verify page number is valid
  • Check limit parameter (max 100)
  • Confirm hasNext/hasPrev values
  • Use automatic pagination helper

Slow Searches

  • Reduce result limit
  • Use status filtering
  • Try shorter keywords
  • Check API status page

Need Help?

  • Can’t find a project? Try List Projects for complete list
  • Want project details? Use Get Project Details
  • Need bulk operations? Use automatic pagination with export
  • Searching specific criteria? Use status and stage filters
Last updated on