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
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Your API key (format: YOUR_API_KEY) |
Content-Type | No | Optional application/json |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
keywords | string | Yes | Search terms to filter projects (space-separated, supports partial matching) |
page | integer | No | Page number for pagination (defaults to 0, zero-indexed) |
limit | integer | No | Results per page (defaults to 20, max 100) |
status | string | No | Filter by project status (e.g., screening, diligence, invested) |
sortBy | string | No | Sort field (e.g., name, createdAt, updatedAt) |
sortOrder | string | No | Sort 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
# 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:
{
"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
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
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
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
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)
{
"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
| Field | Type | Description |
|---|---|---|
results | array | Array of matching projects |
id | string | Project UUID |
name | string | Project name |
company | string | Company name |
status | string | Current project status |
stage | string | Investment stage (Seed, Series A, etc.) |
createdAt | string | ISO 8601 creation timestamp |
updatedAt | string | ISO 8601 last update timestamp |
Pagination Fields
| Field | Type | Description |
|---|---|---|
page | integer | Current page number |
limit | integer | Results per page |
total | integer | Total matching results |
totalPages | integer | Total number of pages |
hasNext | boolean | Whether next page exists |
hasPrev | boolean | Whether previous page exists |
Error Responses
400 Bad Request - Missing Keywords
{
"success": false,
"error": "keywords parameter is required"
}404 Not Found - No Results
{
"success": true,
"data": {
"results": [],
"pagination": {
"page": 0,
"limit": 20,
"total": 0,
"totalPages": 0,
"hasNext": false,
"hasPrev": false
}
}
}Common Patterns
Pattern 1: Simple Search
async function searchProjects(keywords) {
const result = await searchProjects(keywords);
return result.data.results;
}
// Usage
const projects = await searchProjects("market");Pattern 2: Paginated Results
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;
}Pattern 3: Filtered Search
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 projectsPattern 4: Search and Analyze
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 Field | Description |
|---|---|
name | Project name (alphabetical) |
createdAt | Date created |
updatedAt | Last updated |
status | Project status |
Status Values
| Status | Description |
|---|---|
screening | Initial screening phase |
diligence | Due diligence phase |
invested | Active investment |
passed | Passed to later stage |
rejected | Rejected |
archived | Archived |
Best Practices
Search Strategy
- Start with broad keywords, then narrow down
- Use status filters to focus on specific stages
- Sort by
updatedAtto 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
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
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_resultsRelated Endpoints
- Get Project Details - View full project information
- List Projects - Get all projects
- Project Status - Update project status
- Add Comment - Add project notes
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