Get status for all searches in a SearchGroup
Check the status of all searches within a search group
This endpoint returns the status and metadata for every search that belongs to a search group. Use it to monitor completion progress, check for errors, and get links to retrieve results for each completed search.
What is a Search Group?
A search group is a collection of searches that share the same searchGroupId. You can group multiple searches together to:
- Track multiple related searches in one request
- Monitor completion of parallel searches
- Compare different algorithm results (dense vs sparse vs hybrid)
- Organize searches by query or session
When to Use This Endpoint
Use this endpoint to:
- ✅ Check if all searches in a group have completed
- ✅ Monitor progress of multiple parallel searches
- ✅ Get
resultsUrllinks for all completed searches - ✅ Identify failed searches and error messages
- ✅ Track processing times across searches
Don't use this for:
- ❌ Getting actual search results (use
/searches/\{searchId\}/resultsinstead) - ❌ Comparing result content (this only shows status, not results)
Response Structure
Example Response
{
"searchGroupId": "e1de299b-8cb3-4d56-9f9b-fc58c8c59841",
"groupStatus": "completed",
"query": "ai engineer",
"totalSearches": 2,
"searches": [
{
"searchId": "4c4b15e0-032d-43e9-b41b-ef3a2efa2e84",
"searchType": "dense",
"status": "completed",
"resultsCount": 2,
"processingTimeMs": 1763,
"error": null,
"createdAt": "2025-11-04T14:21:55.139Z",
"completedAt": "2025-11-04T14:21:58.018Z",
"statusUrl": "/v1/public/searches/4c4b15e0-032d-43e9-b41b-ef3a2efa2e84",
"resultsUrl": "/v1/public/searches/4c4b15e0-032d-43e9-b41b-ef3a2efa2e84/results"
},
{
"searchId": "54153a24-c8e5-4eb6-997c-9a8d0f1216e2",
"searchType": "dense",
"status": "completed",
"resultsCount": 2,
"processingTimeMs": 351,
"error": null,
"createdAt": "2025-11-04T14:22:07.223Z",
"completedAt": "2025-11-04T14:22:07.957Z",
"statusUrl": "/v1/public/searches/54153a24-c8e5-4eb6-997c-9a8d0f1216e2",
"resultsUrl": "/v1/public/searches/54153a24-c8e5-4eb6-997c-9a8d0f1216e2/results"
}
],
"summary": {
"completed": 2,
"processing": 0,
"failed": 0
}
}Field Descriptions
Top-Level Fields
| Field | Type | Description |
|---|---|---|
searchGroupId | UUID | The group identifier |
groupStatus | string | Overall status of all searches in the group |
query | string | The search query (same across all searches in group) |
totalSearches | integer | Total number of searches in this group |
searches | array | Array of individual search status objects |
summary | object | Count of searches by status |
Group Status Values
| Status | Meaning | Action |
|---|---|---|
| initiated | All searches are queued, none processing yet | Wait before polling |
| processing | At least one search is still running | Poll again until completed or partial |
| completed | All searches finished successfully | Fetch results from each search |
| partial | Some searches completed, others failed | Check individual search errors |
Individual Search Object
Each search in the searches array contains:
| Field | Type | Description |
|---|---|---|
searchId | UUID | Unique identifier for this specific search |
searchType | string | Algorithm used: dense, sparse, hybrid, or builtin-rerank |
status | string | Search status: initiated, processing, completed, or failed |
resultsCount | integer/null | Number of results found (null if not completed) |
processingTimeMs | integer/null | Processing time in milliseconds (null if not completed) |
error | string/null | Error message if search failed (null if successful) |
createdAt | datetime | When the search was initiated |
completedAt | datetime/null | When the search finished (null if still running) |
statusUrl | string | Direct link to check this search's detailed status |
resultsUrl | string | Direct link to fetch this search's results |
Summary Object
Aggregated counts across all searches in the group:
| Field | Type | Description |
|---|---|---|
completed | integer | Number of successfully completed searches |
processing | integer | Number of searches still running or initiated |
failed | integer | Number of searches that failed |
Common Usage Patterns
1. Poll Until All Searches Complete
async function waitForGroupCompletion(searchGroupId, apiKey) {
const maxAttempts = 30;
const pollInterval = 2000; // 2 seconds
for (let i = 0; i < maxAttempts; i++) {
const response = await fetch(
`/v1/public/searches/groups/${searchGroupId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const data = await response.json();
console.log(`Group status: ${data.groupStatus}`);
console.log(`Progress: ${data.summary.completed}/${data.totalSearches} completed`);
// Check if done
if (data.groupStatus === 'completed' || data.groupStatus === 'partial') {
return data;
}
// Wait before next poll
await new Promise(resolve => setTimeout(resolve, pollInterval));
}
throw new Error('Timeout waiting for search group completion');
}
// Usage
const group = await waitForGroupCompletion('group-uuid', 'your-api-key');
console.log('All searches done!');2. Fetch Results from Completed Searches
async function fetchAllGroupResults(searchGroupId, apiKey) {
// Get group status
const groupResponse = await fetch(
`/v1/public/searches/groups/${searchGroupId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const group = await groupResponse.json();
// Fetch results from all completed searches
const completedSearches = group.searches.filter(
s => s.status === 'completed'
);
const results = await Promise.all(
completedSearches.map(async (search) => {
const res = await fetch(search.resultsUrl, {
headers: { 'X-API-Key': apiKey }
});
return {
searchId: search.searchId,
searchType: search.searchType,
processingTimeMs: search.processingTimeMs,
data: await res.json()
};
})
);
return results;
}
// Usage
const allResults = await fetchAllGroupResults('group-uuid', 'your-api-key');
allResults.forEach(r => {
console.log(`${r.searchType}: ${r.data.totalResults} results in ${r.processingTimeMs}ms`);
});3. Handle Partial Completion (Some Failures)
async function handleGroupResults(searchGroupId, apiKey) {
const response = await fetch(
`/v1/public/searches/groups/${searchGroupId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const group = await response.json();
if (group.groupStatus === 'partial') {
console.warn('Some searches failed:');
const failed = group.searches.filter(s => s.status === 'failed');
failed.forEach(s => {
console.error(`${s.searchType}: ${s.error}`);
});
}
// Get results from successful searches
const successful = group.searches.filter(s => s.status === 'completed');
console.log(`${successful.length} searches succeeded`);
return successful;
}4. Compare Processing Times
async function comparePerformance(searchGroupId, apiKey) {
const response = await fetch(
`/v1/public/searches/groups/${searchGroupId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const group = await response.json();
// Sort by processing time
const performance = group.searches
.filter(s => s.status === 'completed')
.map(s => ({
type: s.searchType,
time: s.processingTimeMs,
results: s.resultsCount
}))
.sort((a, b) => a.time - b.time);
console.table(performance);
// Find fastest
const fastest = performance[0];
console.log(`Fastest: ${fastest.type} (${fastest.time}ms)`);
}5. Monitor Long-Running Searches
async function monitorProgress(searchGroupId, apiKey) {
const response = await fetch(
`/v1/public/searches/groups/${searchGroupId}`,
{ headers: { 'X-API-Key': apiKey } }
);
const group = await response.json();
// Show progress for each search
group.searches.forEach(search => {
const elapsed = search.completedAt
? new Date(search.completedAt) - new Date(search.createdAt)
: Date.now() - new Date(search.createdAt);
console.log(`${search.searchType}: ${search.status} (${elapsed}ms elapsed)`);
});
// Calculate estimated remaining time
const processing = group.searches.filter(
s => s.status === 'processing' || s.status === 'initiated'
);
if (processing.length > 0) {
console.log(`${processing.length} searches still running...`);
}
}Use Cases
Parallel Search Execution
Launch multiple searches with the same searchGroupId to track them together:
const groupId = crypto.randomUUID();
// Launch 3 searches in parallel
await Promise.all([
fetch('/v1/public/searches/dense', {
method: 'POST',
body: JSON.stringify({ query: 'software engineer', searchGroupId: groupId })
}),
fetch('/v1/public/searches/sparse', {
method: 'POST',
body: JSON.stringify({ query: 'software engineer', searchGroupId: groupId })
}),
fetch('/v1/public/searches/hybrid', {
method: 'POST',
body: JSON.stringify({ query: 'software engineer', searchGroupId: groupId })
})
]);
// Monitor all 3 at once
const group = await fetch(`/v1/public/searches/groups/${groupId}`);Algorithm Comparison
Compare different search algorithms on the same query:
// After all searches complete
const group = await fetchGroupStatus(groupId);
group.searches.forEach(search => {
console.log(`${search.searchType}:`);
console.log(` - Results: ${search.resultsCount}`);
console.log(` - Time: ${search.processingTimeMs}ms`);
});Error Handling
404 - Group Not Found
{
"error": "Search group not found",
"searchGroupId": "uuid"
}Possible reasons:
- Invalid
searchGroupId - Group doesn't belong to your company
- No searches have been created with this group ID yet
500 - Server Error
{
"error": "Failed to get search group",
"message": "Error details"
}Action: Retry request or contact support
Performance Notes
- Response size: ~0.5-1KB per search in group
- Typical groups: 2-4 searches
- No rate limits: Safe to poll frequently
- Data retention: Group data persists indefinitely
Related Endpoints
- GET /v1/public/searches/{searchId} - Get status of a single search
- GET /v1/public/searches/{searchId}/results - Fetch results for a completed search
- GET /v1/public/searches/groups/{searchGroupId}/results - Compare results across all searches in group (if available)
Quick Reference
// 1. Create searches with same groupId
const groupId = crypto.randomUUID();
await createSearchWithGroup(query, 'dense', groupId);
await createSearchWithGroup(query, 'sparse', groupId);
// 2. Check group status
const group = await fetch(`/v1/public/searches/groups/${groupId}`);
// 3. Wait for completion
while (group.groupStatus === 'processing') {
await sleep(2000);
group = await fetch(`/v1/public/searches/groups/${groupId}`);
}
// 4. Fetch all results
const results = await Promise.all(
group.searches
.filter(s => s.status === 'completed')
.map(s => fetch(s.resultsUrl))
);API key for public API access. Get yours at https://app.floreal.ai?tab=api
In: header
Path Parameters
uuidResponse Body
curl -X GET "https://api.floreal.ai/v1/public/searches/groups/497f6eca-6276-4993-bfeb-53cbbbba6f08"{
"searchGroupId": "6057d3c7-e3bb-4624-80c0-432d9633004b",
"groupStatus": "initiated",
"query": "string",
"totalSearches": 0,
"searches": [
{
"searchId": "9b1a67f9-9477-48e5-8a6c-11b70245e1d9",
"searchType": "dense",
"status": "initiated",
"resultsCount": 0,
"processingTimeMs": 0,
"error": "string",
"createdAt": "2019-08-24T14:15:22Z",
"completedAt": "2019-08-24T14:15:22Z",
"statusUrl": "string",
"resultsUrl": "string"
}
],
"summary": {
"completed": 0,
"processing": 0,
"failed": 0
}
}{
"error": "string",
"message": "string"
}{
"error": "string"
}{
"error": "string",
"message": "string"
}