Floreal Logo
SearchSearch Groups

List all search groups for your organization

Browse your organization's search history and monitor active searches

This endpoint returns a paginated list of all search groups in your organization, allowing you to view search history, monitor ongoing searches, and access past results.


What Are Search Groups?

A search group contains one or more related searches. Each group in the list represents:

  • A single search (when using one algorithm)
  • An algorithm comparison (when multiple algorithms share the same searchGroupId)
  • A historical search that can be referenced later

Use Cases

Search History

Browse past searches and their results to:

  • Find previous candidate searches
  • Review what queries were used
  • Access historical results

Monitoring Dashboard

Track active searches across your organization:

  • See which searches are currently running
  • Monitor search completion status
  • Build real-time dashboards

Analytics & Reporting

Analyze search patterns:

  • Identify most common search queries
  • Track search usage over time
  • Generate usage statistics

Result Archives

Access past search results:

  • Retrieve old candidate lists
  • Compare searches across time periods
  • Audit search activity

Query Parameters

Pagination

ParameterTypeDefaultRangeDescription
limitinteger201 to 100Number of groups to return per page
offsetinteger00 or greaterNumber of groups to skip

Calculate page number: page = Math.floor(offset / limit) + 1

Filtering

ParameterTypeOptionsDescription
statusstringinitiated, processing, completed, failedFilter groups by search status

Note: Status filtering applies to individual searches within groups. A group appears in results if ANY search in it matches the status filter.


Response Structure

Example Response

{
  "data": [
    {
      "searchGroupId": "e1de299b-8cb3-4d56-9f9b-fc58c8c59841",
      "query": "senior python developer",
      "createdAt": "2025-11-04T14:21:55.139Z",
      "groupUrl": "/v1/public/searches/groups/e1de299b-8cb3-4d56-9f9b-fc58c8c59841",
      "resultsUrl": "/v1/public/searches/groups/e1de299b-8cb3-4d56-9f9b-fc58c8c59841/results"
    },
    {
      "searchGroupId": "a2bc567d-1234-5678-90ab-cdef12345678",
      "query": "ai engineer with machine learning experience",
      "createdAt": "2025-11-03T10:15:30.000Z",
      "groupUrl": "/v1/public/searches/groups/a2bc567d-1234-5678-90ab-cdef12345678",
      "resultsUrl": "/v1/public/searches/groups/a2bc567d-1234-5678-90ab-cdef12345678/results"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total": 156
  }
}

Field Descriptions

data[] - Array of Search Groups

FieldTypeDescription
searchGroupIdUUIDUnique identifier for this group
querystringThe search query used
createdAtdatetimeWhen the first search in this group was created
groupUrlstringEndpoint to get detailed group status (all searches)
resultsUrlstringEndpoint to get complete results from all searches

pagination - Navigation Metadata

FieldTypeDescription
limitintegerNumber of results per page (your request value)
offsetintegerNumber of results skipped (your request value)
totalintegerTotal number of search groups matching your filters

Calculate if more pages exist: hasMore = (offset + limit) < total


Sorting

Results are sorted by creation time, newest first (createdAt DESC).


Common Usage Patterns

1. Basic Pagination

Fetch groups page by page:

async function fetchPage(page, pageSize = 20, apiKey) {
  const offset = (page - 1) * pageSize;

  const response = await fetch(
    '/v1/public/searches/groups?limit=' + pageSize + '&offset=' + offset,
    { headers: { 'X-API-Key': apiKey } }
  );

  const data = await response.json();

  const totalPages = Math.ceil(data.pagination.total / pageSize);
  const hasNextPage = page < totalPages;

  return { ...data, hasNextPage, totalPages, currentPage: page };
}

// Usage
const page1 = await fetchPage(1, 20, 'your-api-key');
console.log('Page 1 of ' + page1.totalPages);
console.log('Showing ' + page1.data.length + ' groups');

2. Infinite Scroll

Load more results as user scrolls:

async function loadMoreGroups(apiKey) {
  let allGroups = [];
  let offset = 0;
  const limit = 20;

  while (true) {
    const response = await fetch(
      '/v1/public/searches/groups?limit=' + limit + '&offset=' + offset,
      { headers: { 'X-API-Key': apiKey } }
    );

    const { data, pagination } = await response.json();

    // Add to collection
    allGroups = allGroups.concat(data);

    // Display in UI
    displayGroups(data);

    // Check if more exist
    if (offset + limit >= pagination.total) {
      break; // No more results
    }

    offset += limit;

    // Optional: wait for user to scroll or click "Load More"
    await waitForUserAction();
  }

  return allGroups;
}

3. Monitor Active Searches

Build a real-time monitoring dashboard:

async function monitorActiveSearches(apiKey) {
  const response = await fetch(
    '/v1/public/searches/groups?status=processing&limit=50',
    { headers: { 'X-API-Key': apiKey } }
  );

  const { data, pagination } = await response.json();

  console.log(pagination.total + ' searches currently processing');

  data.forEach(group => {
    console.log('- "' + group.query + '" (started ' + new Date(group.createdAt).toLocaleString() + ')');
  });

  return data;
}

// Refresh every 5 seconds
setInterval(() => monitorActiveSearches('your-api-key'), 5000);

4. Search History Display

Show recent search history to users:

async function displaySearchHistory(apiKey) {
  const response = await fetch(
    '/v1/public/searches/groups?status=completed&limit=20',
    { headers: { 'X-API-Key': apiKey } }
  );

  const { data } = await response.json();

  console.log('Recent Searches:');
  data.forEach((group, index) => {
    const date = new Date(group.createdAt).toLocaleDateString();
    console.log((index + 1) + '. "' + group.query + '" - ' + date);
    console.log('   View results: ' + group.resultsUrl);
    console.log();
  });
}

5. Fetch All Groups for Analytics

Retrieve complete search history for analysis:

async function fetchAllGroups(apiKey) {
  let allGroups = [];
  let offset = 0;
  const limit = 100; // Use max limit for efficiency

  while (true) {
    const response = await fetch(
      '/v1/public/searches/groups?limit=' + limit + '&offset=' + offset,
      { headers: { 'X-API-Key': apiKey } }
    );

    const { data, pagination } = await response.json();

    allGroups = allGroups.concat(data);

    if (offset + limit >= pagination.total) {
      break;
    }

    offset += limit;
  }

  return allGroups;
}

// Analyze search patterns
async function analyzeSearchPatterns(apiKey) {
  const allGroups = await fetchAllGroups(apiKey);

  // Find most common queries
  const queryFrequency = allGroups.reduce((acc, group) => {
    acc[group.query] = (acc[group.query] || 0) + 1;
    return acc;
  }, {});

  const topQueries = Object.entries(queryFrequency)
    .sort(([, a], [, b]) => b - a)
    .slice(0, 10);

  console.log('Top 10 Most Common Searches:');
  topQueries.forEach(([query, count], index) => {
    console.log((index + 1) + '. "' + query + '" - ' + count + ' times');
  });

  return { allGroups, queryFrequency, topQueries };
}

6. Filter by Status

Get searches by their current status:

async function getSearchesByStatus(status, apiKey) {
  const response = await fetch(
    '/v1/public/searches/groups?status=' + status + '&limit=100',
    { headers: { 'X-API-Key': apiKey } }
  );

  const { data, pagination } = await response.json();

  console.log('Found ' + pagination.total + ' ' + status + ' searches');
  return data;
}

// Examples
const processing = await getSearchesByStatus('processing', apiKey);
const completed = await getSearchesByStatus('completed', apiKey);
const failed = await getSearchesByStatus('failed', apiKey);

Pagination Examples

// Page 1 (first 20 groups)
const page1 = await fetch(
  '/v1/public/searches/groups?limit=20&offset=0',
  { headers: { 'X-API-Key': 'your-key' } }
);

// Page 2 (next 20 groups)
const page2 = await fetch(
  '/v1/public/searches/groups?limit=20&offset=20',
  { headers: { 'X-API-Key': 'your-key' } }
);

// Page 3 (next 20 groups)
const page3 = await fetch(
  '/v1/public/searches/groups?limit=20&offset=40',
  { headers: { 'X-API-Key': 'your-key' } }
);

Calculate Total Pages

const response = await fetch('/v1/public/searches/groups?limit=20');
const { pagination } = await response.json();

const totalPages = Math.ceil(pagination.total / pagination.limit);
const currentPage = Math.floor(pagination.offset / pagination.limit) + 1;

console.log('Page ' + currentPage + ' of ' + totalPages);

Check for More Results

const { data, pagination } = await response.json();

const hasMore = (pagination.offset + pagination.limit) < pagination.total;

if (hasMore) {
  console.log('More results available');
  const nextOffset = pagination.offset + pagination.limit;
  // Fetch next page using nextOffset
}

Performance Notes

Optimization Tips:

  • Use limit=20 (default) for UI pagination
  • Use limit=100 for analytics and bulk operations
  • Cache results for search history displays
  • Use status filters to reduce result sets

Error Handling

400 - Bad Request

{
  "error": "Invalid query parameters",
  "message": "limit must be between 1 and 100"
}

Common causes:

  • limit outside range 1 to 100
  • offset is negative
  • Invalid status value

401 - Unauthorized

{
  "error": "Unauthorized"
}

Cause: Missing or invalid API key

500 - Server Error

{
  "error": "Failed to list search groups",
  "message": "Error details"
}

Action: Retry request or contact support


Next Steps

After listing groups:

  1. View group details: Use groupUrl to see all searches in a group
  2. Fetch results: Use resultsUrl to get complete candidate results
  3. Check status: For processing groups, poll groupUrl until complete

  • GET /v1/public/searches/groups/{searchGroupId} - Get status of all searches in a specific group
  • GET /v1/public/searches/groups/{searchGroupId}/results - Get complete results from all searches in a group
  • POST /v1/public/searches/{type} - Create new searches (with optional searchGroupId)

Pro Tips

💡 History & Discovery:

  • Build "Recent Searches" feature using this endpoint
  • Extract unique queries for autocomplete/suggestions
  • Show search frequency to identify common queries
  • Cache recent groups for faster UI loading

💡 Monitoring:

  • Filter by status=processing for active search dashboard
  • Refresh periodically to track completion
  • Alert on failed searches for troubleshooting
GET
/v1/public/searches/groups
X-API-Key<token>

API key for public API access. Get yours at https://app.floreal.ai?tab=api

In: header

Query Parameters

limit?string
Default"20"
offset?string
Default"0"
status?string
Value in"initiated" | "processing" | "completed" | "failed"

Response Body

curl -X GET "https://api.floreal.ai/v1/public/searches/groups?limit=20&offset=0&status=initiated"
{
  "data": [
    {
      "searchGroupId": "6057d3c7-e3bb-4624-80c0-432d9633004b",
      "query": "string",
      "createdAt": "2019-08-24T14:15:22Z",
      "groupUrl": "/v1/public/searches/groups/550e8400-e29b-41d4-a716-446655440000",
      "resultsUrl": "/v1/public/searches/groups/550e8400-e29b-41d4-a716-446655440000/results"
    }
  ],
  "pagination": {
    "limit": 1,
    "offset": 0,
    "total": 0
  }
}
{
  "error": "string",
  "message": "string"
}
{
  "error": "string"
}
{
  "error": "string",
  "message": "string"
}