Client Integration Guide¶
This guide shows the stable pull-based integration for CRMs, data warehouses, and internal reporting systems across an entire search profile.
Profile sync is not order reconciliation
The delivery and company endpoints can contain companies from several
historical orders. To retrieve one order, poll its status and read only
GET /api/v1/orders/{order_id}/results until has_more is false.
Integration Flow¶
- Validate the API key.
- List visible prospect searches.
- Pull delivered companies for each prospect search.
- Store the latest successful delivery timestamp.
- Repeat with
delivered_sincefor incremental sync.
Required Scopes¶
| Operation | Scopes |
|---|---|
| Validate key | Any active API key |
| List prospect searches | prospect_searches:read |
| Pull delivered companies | companies:read, prospects:read |
Validate the Key¶
GET /api/v1/auth/validate
curl -sS https://api.openprospect.io/api/v1/auth/validate \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Expected response:
List Prospect Searches¶
GET /api/v1/prospect-searches
const url = new URL("https://api.openprospect.io/api/v1/prospect-searches");
url.searchParams.set("limit", "10");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OPENPROSPECT_API_KEY}` },
});
if (!response.ok) {
throw new Error(`Prospect search list failed: ${response.status}`);
}
console.log((await response.json()).items);
interface ProspectSearchList {
items: Array<{ id: string; name: string; status: string }>;
total: number;
limit: number;
offset: number;
}
const url = new URL("https://api.openprospect.io/api/v1/prospect-searches");
url.searchParams.set("limit", "10");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OPENPROSPECT_API_KEY}` },
});
if (!response.ok) {
throw new Error(`Prospect search list failed: ${response.status}`);
}
const searches = (await response.json()) as ProspectSearchList;
console.log(searches.items);
using System.Net.Http.Headers;
var apiKey = Environment.GetEnvironmentVariable("OPENPROSPECT_API_KEY")
?? throw new InvalidOperationException("OPENPROSPECT_API_KEY is not set.");
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
var response = await client.GetAsync("https://api.openprospect.io/api/v1/prospect-searches?limit=10");
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
Pull Delivered Companies¶
GET /api/v1/deliveries/{prospect_search_id}/companies
Use this endpoint only for legacy profile-wide CRM sync / drip. It is not
how you read an order. For one order, use
GET /api/v1/orders/{order_id}/results.
It returns companies with embedded prospects.
curl -sS \
"https://api.openprospect.io/api/v1/deliveries/${PROSPECT_SEARCH_ID}/companies?limit=100" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Incremental Sync¶
After each successful run, store the newest delivered timestamp from your own
sync state. On the next run, send it as delivered_since.
curl -sS \
"https://api.openprospect.io/api/v1/deliveries/${PROSPECT_SEARCH_ID}/companies?delivered_since=2026-02-25T12:00:00Z&limit=100" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Process pages until has_more is false.
Minimal Python Sync¶
import os
from collections.abc import Iterator
from typing import Any
import httpx
api_key = os.environ["OPENPROSPECT_API_KEY"]
prospect_search_id = os.environ["PROSPECT_SEARCH_ID"]
def iter_delivered_companies(delivered_since: str | None = None) -> Iterator[dict[str, Any]]:
offset = 0
headers = {"Authorization": f"Bearer {api_key}"}
while True:
response = httpx.get(
f"https://api.openprospect.io/api/v1/deliveries/{prospect_search_id}/companies",
headers=headers,
params={"limit": 100, "offset": offset, "delivered_since": delivered_since},
timeout=30.0,
)
response.raise_for_status()
page = response.json()
yield from page["items"]
if not page["has_more"]:
break
offset += len(page["items"])
for company in iter_delivered_companies():
print(company["id"], company["name"])