> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitsearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Deep Search run status

> Poll the status of an async Deep Search run until it completes, then read generated profiles by ID.

Poll the status endpoint until `status` is `completed` or `failed`. A few seconds between polls with backoff is appropriate. Status polling has its own rate-limit bucket and is free — it does not consume credits. For single-profile run shapes, `generating_sections` means Deep Search has a profile ID, but generated profile sections are still being written. Keep polling until `completed` before treating the generated profile as ready to read.

For profile-generation run shapes, completion means profile section generation has finished and returns the durable profile resource `id` plus a `section_generation` summary when available. The generated profile contains whichever public sections were produced; individual sections may be skipped or fail. Check `section_generation.sections_ready` and `section_generation.materialized_section_count` to distinguish a completed run with readable generated content from a completed run where no public sections were materialized. If `sections_ready` is `false` and `materialized_section_count` is `0`, a subsequent profile-read request may return only basic profile data with no generated public sections; treat that as the final output for the run, not a transient pending state. For `candidate_discovery`, `result` can appear while the run is still `running` and includes candidate profile IDs as they are created. When `candidate_discovery` reaches `completed`, source discovery, clustering, candidate child profile generation, and partial profile publication are terminal for the returned candidate profiles. Read each generated profile body with [`GET /v2/developer/profiles/{id}`](/api/search/profile-read).

When the run reaches `failed`, the response may include a sanitized `failure` object with a stable public code and retry guidance. For example, `identity_not_corroborated` means Deep Search could not verify the person strongly enough from the supplied signals; retry with stronger identity signals such as a LinkedIn URL, email, public URLs, usernames, or structured intent.

Some `failed` responses can still include `result.id`. This means Deep Search produced and saved a profile id, but generated profile sections were not ready before the readiness timeout. Treat `failed` as terminal; you may retry the run if `failure.retryable` is `true`.

Requests authenticate with a developer API key that has the `search:read` scope. See [Authentication](/authentication).

<RequestExample>
  ```bash curl theme={"dark"}
  curl "https://api.orbitsearch.com/v2/developer/deep-search/8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10" \
    -H "Authorization: Bearer sk_orb_REDACTED"
  ```

  ```javascript JavaScript theme={"dark"}
  const TERMINAL = new Set(["completed", "failed"]);

  let status;
  do {
    await new Promise((resolve) => setTimeout(resolve, 5000));
    const response = await fetch(
      `https://api.orbitsearch.com/v2/developer/deep-search/${requestId}`,
      { headers: { "Authorization": "Bearer sk_orb_REDACTED" } },
    );
    status = await response.json();
  } while (!TERMINAL.has(status.status));

  console.log(status.status, status.result);
  ```

  ```python Python theme={"dark"}
  import time
  import requests

  TERMINAL = {"completed", "failed"}

  while True:
      response = requests.get(
          f"https://api.orbitsearch.com/v2/developer/deep-search/{request_id}",
          headers={"Authorization": "Bearer sk_orb_REDACTED"},
      )
      status = response.json()
      if status["status"] in TERMINAL:
          break
      time.sleep(5)

  print(status["status"], status["result"])
  ```
</RequestExample>

<ResponseExample>
  ```json 200 (running) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "running",
    "result": null
  }
  ```

  ```json 200 (completed) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "completed",
    "result": {
      "id": "ORBIT_PROFILE_ID",
      "section_generation": {
        "status": "completed",
        "sections_ready": true,
        "materialized_section_count": 3,
        "failed_count": 0
      }
    }
  }
  ```

  ```json 200 (generating sections) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "generating_sections",
    "result": {
      "id": "ORBIT_PROFILE_ID",
      "section_generation": {
        "status": "started",
        "sections_ready": false,
        "materialized_section_count": 0,
        "failed_count": 0
      }
    }
  }
  ```

  ```json 200 (candidate_discovery running) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "running",
    "result": {
      "candidate_profile_ids": ["ORBIT_PROFILE_ID_1", "ORBIT_PROFILE_ID_2"],
      "profile_ids": ["ORBIT_PROFILE_ID_1", "ORBIT_PROFILE_ID_2"],
      "candidate_count": 4,
      "dispatched_candidate_count": 2,
      "persisted_candidate_count": 2,
      "failed_candidate_count": 0,
      "skipped_candidate_count": 2,
      "current_phase": "candidate_child_fanout_completed",
      "metrics": {
        "candidate_source_discovery_elapsed_seconds": 12.4,
        "candidate_clustering_elapsed_seconds": 3.1,
        "child_search_engine_query_count": 0,
        "web_search_stopped_before_segments": true
      }
    }
  }
  ```

  ```json 200 (candidate_discovery completed) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "completed",
    "result": {
      "candidate_profile_ids": ["ORBIT_PROFILE_ID_1", "ORBIT_PROFILE_ID_2"],
      "profile_ids": ["ORBIT_PROFILE_ID_1", "ORBIT_PROFILE_ID_2"],
      "candidate_count": 4,
      "dispatched_candidate_count": 2,
      "persisted_candidate_count": 2,
      "failed_candidate_count": 0,
      "skipped_candidate_count": 2,
      "current_phase": "completed",
      "metrics": {
        "candidate_source_discovery_elapsed_seconds": 12.4,
        "candidate_clustering_elapsed_seconds": 3.1,
        "candidate_child_profile_elapsed_seconds": 8.7,
        "total_elapsed_seconds": 24.2,
        "child_search_engine_query_count": 0,
        "web_search_stopped_before_segments": true
      }
    }
  }
  ```

  ```json 200 (failed) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "failed",
    "result": null,
    "failure": {
      "code": "identity_not_corroborated",
      "message": "We could not verify the person strongly enough to generate a profile.",
      "retryable": true,
      "suggested_inputs": ["linkedinUrl", "email", "urls", "usernames", "structuredIntent"]
    }
  }
  ```

  ```json 200 (section readiness timeout) theme={"dark"}
  {
    "request_id": "8f6f2a1e-4b6d-4f3a-9d2c-1a7e5c3b9f10",
    "run_id": "RUN_ID",
    "status": "failed",
    "result": {
      "id": "ORBIT_PROFILE_ID",
      "section_generation": {
        "status": "started",
        "sections_ready": false,
        "materialized_section_count": 0,
        "failed_count": 0
      }
    },
    "failure": {
      "code": "deep_search_failed",
      "message": "The profile was generated, but section generation did not finish in time.",
      "retryable": true
    }
  }
  ```
</ResponseExample>

## Path parameters

<ParamField path="requestId" type="string" required>
  The run's durable id — the `request_id` returned by [`POST /v2/developer/deep-search`](/api/search/deep-search).
</ParamField>

## Response

<ResponseField name="request_id" type="string" required>
  The run's durable id.
</ResponseField>

<ResponseField name="run_id" type="string | null" required>
  An opaque tracking id for the run, or `null` if not available.
</ResponseField>

<ResponseField name="status" type="string" required>
  `"running"`, `"generating_sections"`, `"completed"`, `"failed"`, or `"not_found"`. Treat `completed` and `failed` as terminal and stop polling. `generating_sections` means a single-profile run has a profile ID, but generated profile sections are still being written. `completed` means profile section generation has finished for profile-generation run shapes; individual sections may be skipped or fail. `candidate_discovery` is terminal when it reports `completed`. `not_found` is returned with a `404`.
</ResponseField>

<ResponseField name="result" type="object | null" required>
  For profile-generation run shapes, `null` until the run has a profile id. During `generating_sections` or `completed`, it contains the durable Orbit profile resource id as `id`, plus `section_generation` when available. A `failed` response may also include `result.id` when a profile was saved but generated profile sections were not ready before the readiness timeout. For `candidate_discovery`, it may be present while running and contains `candidate_profile_ids`, `profile_ids`, candidate counts, `current_phase`, and `metrics`.
</ResponseField>

<ResponseField name="result.section_generation" type="object">
  Section-generation status for single-profile run shapes. `completed` means generated profile section work has finished; inspect `sections_ready`, `materialized_section_count`, and `failed_count` to see whether generated public sections were actually produced. If no sections were materialized, the profile-read response may contain only basic profile data.
</ResponseField>

<ResponseField name="failure" type="object">
  Present when `status` is `failed` and a public failure reason is available.
</ResponseField>

<ResponseField name="failure.code" type="string">
  Stable public reason code. `identity_not_corroborated` means the supplied identity signals could not be corroborated strongly enough to generate a profile. `deep_search_failed` is a generic completion failure.
</ResponseField>

<ResponseField name="failure.message" type="string">
  Human-readable failure summary safe to show in logs or UI.
</ResponseField>

<ResponseField name="failure.retryable" type="boolean">
  Whether the request can be retried. For `identity_not_corroborated`, retry with stronger or more specific identity signals.
</ResponseField>

<ResponseField name="failure.suggested_inputs" type="string[]">
  Optional input fields that may help a retry, such as `linkedinUrl`, `email`, `urls`, `usernames`, or `structuredIntent`.
</ResponseField>

### Candidate discovery result fields

When `runShape` is `candidate_discovery`, `result` is an object with these fields:

| Field                        | Description                                                                                                                                                                                                                                |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `candidate_profile_ids`      | Candidate Orbit profile IDs created so far. Completed responses contain the terminal set of candidate profiles generated by this run.                                                                                                      |
| `profile_ids`                | Same IDs as `candidate_profile_ids`, provided for consistency with multi-profile consumers.                                                                                                                                                |
| `candidate_count`            | Number of candidate clusters discovered and eligible for candidate discovery. This can be higher than the number generated immediately.                                                                                                    |
| `dispatched_candidate_count` | Number of candidate child workflows started to generate partial profiles.                                                                                                                                                                  |
| `persisted_candidate_count`  | Number of candidate profiles saved so far.                                                                                                                                                                                                 |
| `failed_candidate_count`     | Number of candidate child profile writes that failed.                                                                                                                                                                                      |
| `skipped_candidate_count`    | Number of candidate clusters not dispatched for partial-profile generation, usually because of fanout limits or guardrails.                                                                                                                |
| `current_phase`              | Current candidate discovery phase, such as `candidate_source_discovery`, `candidate_clustering`, `candidate_child_fanout`, `candidate_profile_persistence`, or `completed`.                                                                |
| `metrics`                    | Timing and guardrail metrics, including parent source/clustering elapsed time and `child_search_engine_query_count`. Candidate child workflows should report `child_search_engine_query_count: 0` because they use clustered sources only. |

<Note>
  The SSE events route (`GET /v2/developer/deep-search/{requestId}/events`) has been removed. Poll the status endpoint instead.
</Note>

## Rate limits

Deep Search status polling has its own rate-limit bucket: **25 requests per second** per API key, with bursts up to **150 requests**. Starting new Deep Search runs uses a separate start bucket. Status polling is free, and a `429` response does not consume credits.

## Error responses

| Status | Code                                  | Description                                |
| ------ | ------------------------------------- | ------------------------------------------ |
| `404`  | `developer_deep_search_run_not_found` | The `requestId` does not match a known run |
| `429`  | `developer_api_key_rate_limited`      | The API key exceeded the search rate limit |
