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

# Lookup Without Waterfall Mode

> Get results synchronously in a single request, without setting up a callback server.

By default, the Person API is asynchronous — a request is submitted and results arrive via a callback URL. The `withoutWaterfall` mode changes this to a **synchronous flow**: results are returned immediately in the response body.

## How It Differs

|                          | Standard (async)               | withoutWaterfall (sync)                              |
| ------------------------ | ------------------------------ | ---------------------------------------------------- |
| Response time            | Slower (queries external APIs) | **Fast, immediate**                                  |
| Requires callback server | Yes                            | **No**                                               |
| Callback Url             | Required                       | Not allowed                                          |
| External API enrichment  | **Yes**                        | No — only internal data                              |
| Contact coverage         | **Higher**                     | Lower                                                |
| Data freshness           | **Higher**                     | May be less current                                  |
| Without contacts mode    | Supported                      | **Supported** — combine with `withoutContacts: true` |

<Info>
  Use `withoutWaterfall` when a fast response is needed and fewer or slightly older contacts are acceptable. Use the standard async mode when completeness matters more than speed.
</Info>

## Request Parameters

The same parameters apply as in the standard [Retrieve Person Data](/person-api/retrieve-person#request-parameters) endpoint, with two differences:

* `withoutWaterfall` must be set to `true`
* `callbackUrl` must **not** be included

Optionally, `withoutContacts: true` can be added to retrieve profiles without contact details synchronously. This uses [without-contacts credits](/person-api/without-contacts#checking-credits) instead of standard credits.

## Request Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.signalhire.com/api/v1/candidate/search \
  -H 'apikey: your_secret_api_key' \
  --data '{
  "items": [
  "https://www.linkedin.com/in/jennwolf",
  "10000000000000000000000000001001",
  "+123 45 6777"
  ],
  "withoutWaterfall": true
  }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
  "https://www.signalhire.com/api/v1/candidate/search",
  headers={"apikey": "your_secret_api_key"},
  json={
  "items": [
  "https://www.linkedin.com/in/jennwolf",
  "10000000000000000000000000001001",
  "+123 45 6777"
  ],
  "withoutWaterfall": True
  }
  )
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const response = await axios.post(
  'https://www.signalhire.com/api/v1/candidate/search',
  {
      items: [
      'https://www.linkedin.com/in/jennwolf',
      '10000000000000000000000000001001',
      '+123 45 6777'
      ],
      withoutWaterfall: true
  },
  {
      headers: { apikey: 'your_secret_api_key' }
  }
  );
  ```

  ```java Java theme={null}
  import java.net.http.*;
  import java.net.URI;

  HttpClient client = HttpClient.newHttpClient();

  String body = """
  {
      "items": [
      "https://www.linkedin.com/in/jennwolf",
      "10000000000000000000000000001001",
      "+123 45 6777"
      ],
      "withoutWaterfall": true
  }
  """;

  HttpRequest request = HttpRequest.newBuilder()
  .uri(URI.create("https://www.signalhire.com/api/v1/candidate/search"))
  .header("apikey", "your_secret_api_key")
  .header("Content-Type", "application/json")
  .POST(HttpRequest.BodyPublishers.ofString(body))
  .build();

  HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```ruby Ruby theme={null}
  require 'net/http'
  require 'json'

  uri = URI('https://www.signalhire.com/api/v1/candidate/search')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  request = Net::HTTP::Post.new(uri)
  request['apikey'] = 'your_secret_api_key'
  request['Content-Type'] = 'application/json'
  request.body = {
      items: [
      'https://www.linkedin.com/in/jennwolf',
      '10000000000000000000000000001001',
      '+123 45 6777'
      ],
      withoutWaterfall: true
  }.to_json

  response = http.request(request)
  ```
</CodeGroup>

<Warning>
  `callbackUrl` cannot be used together with `withoutWaterfall`. Including both will return HTTP `406`.
</Warning>

## Response Example (HTTP 200)

The response format is identical to the callback payload in standard mode — an array of result objects returned directly. Each element contains `item`, `status`, and `candidate` when successful. See [Candidate Object](/person-api/candidate-object) for a complete field reference.

```http theme={null}
HTTP/2 200
Content-Type: application/json
X-Credits-Left: 241
```

```json theme={null}
[
{
    "item": "https://www.linkedin.com/in/jennwolf",
    "status": "success",
    "candidate": { "fullName": "Jenn Wolf", "contacts": [...], ... }
},
{
    "item": "10000000000000000000000000001001",
    "status": "success",
    "candidate": { "fullName": "John Dou", "contacts": [...], ... }
},
{
    "item": "+123 45 6777",
    "status": "failed"
}
]
```

For other possible response codes — such as `401`, `402`, `406`, `429` — see [Response Codes](/response-codes).

### Response Status Values

| Status             | Description                                             |
| ------------------ | ------------------------------------------------------- |
| `success`          | Profile found and returned in the `candidate` field.    |
| `failed`           | Item not found or could not be processed.               |
| `credits_are_over` | Credits ran out while processing this item.             |
| `duplicate_query`  | Same request was submitted again within a short period. |

## Rate Limits

For information on request limits and throttling, see [Rate Limits](/person-api/rate-limits).

## When to Use withoutWaterfall

Use `withoutWaterfall` when:

* A fast synchronous response is more important than maximum contact coverage
* Setting up a publicly accessible callback server is not feasible — for example, in local development, scripts, or environments without a public endpoint.

Use standard async mode with `callbackUrl` when completeness matters more than speed — it queries external APIs in real time and returns the most up-to-date contact data available.
