Skip to main content

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.

Overview

This example shows how to fetch all matching profiles from a search query by combining searchByQuery with scrollSearch. Each batch is saved to the database immediately as it arrives — rather than collecting everything in memory first — to minimize memory usage and avoid data loss if the process is interrupted. The pattern is:
  1. Send the initial searchByQuery request — save the first batch, get a scrollId
  2. Loop: save each batch, send scrollSearch with the new scrollId
  3. Stop when no scrollId is returned in the response
The next scrollSearch request must be sent within 15 seconds of the previous response. Do not perform slow operations (heavy processing, external API calls) between scroll requests — save to the database and immediately request the next batch.
import requests
import psycopg2
import json

API_KEY = "your_secret_api_key"
BASE_URL = "https://www.signalhire.com/api/v1/candidate"
HEADERS = {"apikey": API_KEY, "Content-Type": "application/json"}

def save_batch(cur, profiles: list):
for profile in profiles:
cur.execute(
"""
INSERT INTO candidates (uid, full_name, location, skills, open_to_work, raw_data)
VALUES (%s, %s, %s, %s, %s, %s)
ON CONFLICT (uid) DO UPDATE SET
full_name = EXCLUDED.full_name,
location = EXCLUDED.location,
skills = EXCLUDED.skills,
open_to_work = EXCLUDED.open_to_work,
raw_data = EXCLUDED.raw_data
""",
(
profile["uid"],
profile.get("fullName"),
profile.get("location"),
json.dumps(profile.get("skills", [])),
profile.get("openToWork", False),
json.dumps(profile),
)
)

def search_and_save(query: dict):
conn = psycopg2.connect("postgresql://user:password@localhost/mydb")
cur = conn.cursor()
total_saved = 0

# Initial search
response = requests.post(f"{BASE_URL}/searchByQuery", headers=HEADERS, json=query)
response.raise_for_status()
data = response.json()

request_id = data["requestId"]
scroll_id = data.get("scrollId")
total = data["total"]
print(f"Total profiles found: {total}")

save_batch(cur, data.get("profiles", []))
conn.commit()
total_saved += len(data.get("profiles", []))
print(f"Saved {total_saved} / {total}")

# Scroll through remaining batches
while scroll_id:
response = requests.post(
f"{BASE_URL}/scrollSearch/{request_id}",
headers=HEADERS,
json={"scrollId": scroll_id}
)
response.raise_for_status()
data = response.json()

save_batch(cur, data.get("profiles", []))
conn.commit()
total_saved += len(data.get("profiles", []))
scroll_id = data.get("scrollId")
print(f"Saved {total_saved} / {total}")

cur.close()
conn.close()
print("Done")

search_and_save({
"currentTitle": "(Software AND Engineer) OR Developer",
"location": "New York, New York, United States",
"keywords": "PHP AND JavaScript",
"size": 50
})