POST https://api.pearch.ai/v2/search/sql
Search professional profiles using sql_filter, an optional ranking query, or both. Results use the same search_results[].profile structure as /v2/search.
Meaning versus constraintsPut what you want to rank by in
query, and conditions every result must satisfy insql_filter. Omitqueryfor a filters-only search.
Quick start
import os
import requests
response = requests.post(
"https://api.pearch.ai/v2/search/sql",
headers={"Authorization": f"Bearer {os.environ['PEARCH_API_KEY']}"},
json={
"query": "Python backend engineers building distributed systems",
"sql_filter": "location_country_code = 'US' AND total_experience_years >= 5",
"limit": 10,
},
timeout=60,
)
response.raise_for_status()
for result in response.json()["search_results"]:
print(result["docid"], result["profile"])curl --request POST \
--url https://api.pearch.ai/v2/search/sql \
--header "Authorization: Bearer $PEARCH_API_KEY" \
--header "Content-Type: application/json" \
--data "{\"query\":\"Python backend engineers\",\"sql_filter\":\"location_country_code = 'US'\",\"limit\":10}"Use your usual Pearch API key in the Authorization: Bearer <API_KEY> header.
Find profiles located in the United States with at least five years of experience, using only filters:
{
"sql_filter": "location_country_code = 'US' AND total_experience_years >= 5",
"limit": 10
}Request parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string or null | null | Optional text used to rank profiles. Omitted, null, or blank values select filters-only search. |
sql_filter | string | "" | SQL condition that results must satisfy, up to 16,384 characters. Omit or leave empty to apply no SQL filter. |
limit | integer | 10 | Maximum profiles to return, from 1 through 1000. Fewer profiles can be returned. |
Provide a nonempty query or sql_filter. Requests with neither return HTTP 400.
Write SQL filters
See the SQL language and complete schema for every field, type, supported filtering operation, repeated-record scope, and examples for company experience, education, skills, languages, geography, activity, and funding.
Use LOCATION('Athens, Greece', 'GR') for a named place, or LOCATION('New York, United States', 'US', 50, 'km') for a distance radius. Supported time zones can be filtered with location_timezone. See geographic filters for the full syntax.
Combine conditions with AND, OR, and parentheses in one string:
{
"query": "Infrastructure engineer",
"sql_filter": "(location_country_code = 'US' OR location_country_code = 'CA') AND total_experience_years BETWEEN 5 AND 10",
"limit": 20
}A leading WHERE is accepted. Send a SQL condition rather than a complete top-level SELECT, ORDER BY, or LIMIT. When supplied, query ranks results; limit controls the maximum result count. SELECT is valid inside supported EXISTS and aggregate subqueries.
SQL follows the grouped response structure. For example, require a current engineering role at Stripe:
EXISTS (
SELECT 1
FROM UNNEST(experiences) AS c
CROSS JOIN UNNEST(c.company_roles) AS r
WHERE c.company_info.domain = 'stripe.com'
AND SEARCH(r.title, 'engineer')
AND r.end_date IS NULL
)Response
HTTP 200 returns ranked profiles in the search response. Profiles that could not be retrieved are skipped. This example is shortened; profile fields depend on available data.
{
"uuid": "a4862482-9067-4acd-b229-74a44de26a99",
"query": "Python backend engineers",
"status": "Done",
"search_results": [
{
"docid": "example-engineer",
"profile": {
"linkedin_slug": "example-engineer",
"first_name": "Alex",
"title": "Backend Engineer",
"skills": ["Distributed systems"],
"canonical_skills": ["Python"],
"experiences": [
{
"company_info": {"name": "Example", "domain": "example.com"},
"company_roles": [{"title": "Backend Engineer", "start_date": "2022-01-01"}]
}
]
}
}
],
"credits_used": 1,
"credits_remaining": 99,
"credits_breakdown": {
"version": 1,
"total": 1,
"items": [{"component": "search", "data_point_type": "profile", "quantity": 1, "unit_cost": 0.2, "credits": 1}]
}
}search_results is ordered by relevance when query is supplied. Filters-only result order is unspecified, and the response query is an empty string. Additional response fields include created_at, duration, user, and parameters.
Profiles include grouped company_roles, free-text skills, and normalized canonical_skills. SQL exposes these skill names, grouped company and role paths, summary, and inferred_languages; filter-only extensions and field operations are documented in the schema reference.
Pricing and limits
The initial price is 0.2 credits per returned profile. Round up the total once per request:
credits_used = ceil(number_of_profiles_returned × 0.2)Balance checks require enough credits for the requested limit; the final charge covers only returned profiles.
The endpoint shares the actual-search rate-limit bucket with /v2/search; the default is 60 requests per user per 60 seconds, subject to organization configuration.
Errors
| HTTP status | Meaning |
|---|---|
| 400 | Invalid parameters, unsupported parameters, missing both query and filters, invalid SQL, or unsupported SQL fields or constructs. |
| 402 | Insufficient credits for the requested result limit. |
| 403 | Missing or invalid API credentials, or access denied by the existing authentication policy. |
| 429 | Shared search rate limit exceeded. |
| 500 | An internal failure. |
| 502 | The search service is unavailable or returned an error. |
{"http": 400, "status": "Invalid sql_filter"}