Floreal Logo
SearchSearch Methods

Get Search Status

Check if your search is complete and ready to retrieve results.

Poll this endpoint to monitor search progress. When status changes to "completed", fetch your results.


Search Status Flow

Your search moves through these states:

  1. initiated → Search created, queued for processing (0-1s)
  2. processing → Search actively running (5-30s depending on algorithm)
  3. completed → Results ready! ✅ Fetch from /results endpoint
  4. failed → Something went wrong ❌ Check error message

Polling Strategy

Recommended approach:

async function waitForResults(searchId) {
  const maxAttempts = 20;  // ~60 seconds timeout

  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(`/v1/public/searches/${searchId}`);
    const data = await response.json();

    if (data.status === 'completed') {
      // Success! Get results
      return await fetch(`/v1/public/searches/${searchId}/results`);
    }

    if (data.status === 'failed') {
      throw new Error(data.error);
    }

    // Still processing, wait and retry with backoff
    await new Promise(r => setTimeout(r, 2000 + (i * 500)));
  }

  throw new Error('Search timeout after 60 seconds');
}

Response Fields

Always returned:

  • searchId - Your search identifier
  • searchGroupId - Group ID if part of comparison
  • status - Current state: "initiated" | "processing" | "completed" | "failed"
  • query - Your original search query
  • searchType - Algorithm used: "dense" | "sparse" | "hybrid" | "builtin-rerank"
  • createdAt - When search was initiated

When status is "completed":

  • resultsCount - Number of candidates found
  • processingTimeMs - How long the search took (milliseconds)
  • completedAt - When search finished
  • resultsUrl - Endpoint to fetch results

When status is "failed":

  • error - What went wrong
  • errorRetryable - true if you should retry, false if it won't help

When status is "processing":

  • estimatedCompletion - Rough time remaining

Rate limit

For rate limit, please check the rate limit in the dedicated API documentation section.

GET /v1/public/searches/550e8400-e29b-41d4-a716-446655440000

{
  "searchId": "550e8400-e29b-41d4-a716-446655440000",
  "searchGroupId": "660e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "query": "senior Python developer",
  "searchType": "dense",
  "createdAt": "2025-01-15T10:30:00Z",
  "resultsCount": 42,
  "processingTimeMs": 7834,
  "completedAt": "2025-01-15T10:30:08Z",
  "resultsUrl": "/v1/public/searches/550e8400-e29b-41d4-a716-446655440000/results"
}

GET /v1/public/searches/550e8400-e29b-41d4-a716-446655440000

{
  "searchId": "550e8400-e29b-41d4-a716-446655440000",
  "searchGroupId": "660e8400-e29b-41d4-a716-446655440000",
  "status": "failed",
  "query": "senior Python developer",
  "searchType": "dense",
  "createdAt": "2025-01-15T10:30:00Z",
  "error": "No documents found in company database",
  "errorRetryable": false
}

Processing Times by Algorithm

AlgorithmTypical TimeMaximum Expected
Dense5-10 seconds30 seconds
Sparse5-10 seconds30 seconds
Builtin-Rerank10-20 seconds30 seconds
Hybrid15-30 seconds45 seconds

If your search exceeds maximum time: Something likely went wrong. Check the status for error details.


Error Handling

Retryable errors (errorRetryable: true):

  • Temporary service issues
  • Lambda timeout (rare, system under load)
  • Network connectivity problems
  • Rate limiting

Non-retryable errors (errorRetryable: false):

  • Invalid query format
  • No documents in your database
  • Malformed parameters
  • Configuration issues

What to do:

  • If errorRetryable: true → Wait 5-10 seconds and create a new search
  • If errorRetryable: false → Fix the issue (query, params) before retrying

Complete Integration Example

// Step 1: Start search
const searchResponse = await fetch('/v1/public/searches/dense', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    query: 'senior backend engineer',
    top_k: 20
  })
});

const { searchId } = await searchResponse.json();

// Step 2: Poll for completion
let completed = false;
let attempts = 0;

while (!completed && attempts < 20) {
  const statusResponse = await fetch(
    `/v1/public/searches/${searchId}`
  );
  const status = await statusResponse.json();

  if (status.status === 'completed') {
    // Step 3: Get results
    const resultsResponse = await fetch(
      `/v1/public/searches/${searchId}/results`
    );
    const results = await resultsResponse.json();

    console.log(`Found ${results.totalResults} candidates`);
    return results;
  }

  if (status.status === 'failed') {
    throw new Error(`Search failed: ${status.error}`);
  }

  // Wait before next poll
  await new Promise(r => setTimeout(r, 3000));
  attempts++;
}

throw new Error('Search timeout');

Best Practices

Polling:

  • ✅ Use exponential backoff to reduce server load

  • ✅ Set reasonable timeout (60 seconds recommended)

  • ✅ Handle both completed and failed states

  • ❌ Don't poll more than once per second

  • Status responses are not cached - always current


Error Responses

Status CodeReasonSolution
404Search not foundCheck searchId is correct and belongs to your company
401Invalid API keyVerify Authorization header
500Server errorRetry after a few seconds

Security

  • Only returns searches belonging to your company
  • Requires valid API key
  • Search results are private to your organization
GET
/v1/public/searches/{searchId}
X-API-Key<token>

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

In: header

Path Parameters

searchIdstring
Formatuuid

Response Body

curl -X GET "https://api.floreal.ai/v1/public/searches/497f6eca-6276-4993-bfeb-53cbbbba6f08"
{
  "searchId": "550e8400-e29b-41d4-a716-446655440000",
  "searchGroupId": "660e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "query": "senior Python developer",
  "searchType": "dense",
  "createdAt": "2025-01-15T10:30:00Z",
  "resultsCount": 42,
  "processingTimeMs": 7834,
  "completedAt": "2025-01-15T10:30:08Z",
  "resultsUrl": "/v1/public/searches/550e8400-e29b-41d4-a716-446655440000/results",
  "error": "No documents found in company database",
  "errorRetryable": false,
  "estimatedCompletion": "5-10 seconds"
}
{
  "error": "string",
  "message": "string"
}
{
  "error": "string"
}
{
  "error": "string",
  "message": "string"
}