Delivery System Integration¶
The core of OpenProspect: How we deliver qualified leads to your system.
📦 Overview¶
The Delivery System is the bridge between OpenProspect's data engine and your internal systems (CRM, Outreach tools, Database). It handles the reliable transfer of companies and prospects that match your specific criteria.
How It Works¶
graph LR
A[OpenProspect Engine] -->|Finds & Qualifies| B(Qualified Company)
B --> C{Delivery Mode}
C -->|Push| D[Webhook POST]
D -->|Real-time| E[Your Server]
C -->|Pull| F[Store in Database]
G[Your Server] -->|GET Request| F
- Discovery: Our engine finds companies matching your Ideal Customer Profile (ICP).
- Qualification: We apply your specific qualification rules (technographics, firmographics).
- Delivery: When a company is qualified, we deliver it to you immediately.
Choose Your Integration Pattern¶
| Pattern | Type | Best For | Pros | Cons |
|---|---|---|---|---|
| Push (Webhooks) | Real-time | CRMs, Slack/Teams, Zapier | Immediate data, event-driven | Requires public endpoint |
| Pull (API) | Batch | Data Warehouses, nightly syncs | Control over timing, bulk processing | Not real-time |
🚀 Push Model (Webhooks)¶
In the Push model, OpenProspect sends an HTTP POST request to your server the moment a company is qualified.
Tip: Use webhook.site to inspect payloads and test your integration before writing code.
1. Configure Your Destination¶
You can configure a webhook destination via the API:
curl -X POST "https://api.openprospect.io/api/v1/deliveries/123/destinations" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"type": "webhook",
"url": "https://your-api.com/webhooks/openprospect",
"auth_type": "bearer",
"auth_token": "your-secret-token"
}'
2. Webhook Payload¶
We send a JSON payload with the company and its prospects.
{
"event": "delivery.company_qualified",
"delivery_id": "del_123abc",
"timestamp": "2025-11-30T12:00:00Z",
"data": {
"company": {
"id": "comp_xyz789",
"name": "Acme Corp",
"domain": "acme.com",
"industry": "Software",
"size": "50-200",
"location": "San Francisco, CA",
"linkedin_url": "https://linkedin.com/company/acme-corp",
"technologies": ["HubSpot", "AWS", "React"]
},
"prospects": [
{
"id": "pros_456def",
"first_name": "Jane",
"last_name": "Doe",
"title": "CTO",
"email": "jane.doe@acme.com",
"linkedin_url": "https://linkedin.com/in/janedoe"
}
],
"qualification_score": 85,
"match_reasons": [
"Uses HubSpot",
"Revenue > $10M",
"Decision Maker found"
]
}
}
3. Handling Webhooks¶
Your server should:
- Accept
POSTrequests. - Return a
200 OKstatus code immediately. - Process the data asynchronously if possible.
Example Receiver¶
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.post("/webhooks/openprospect")
async def receive_webhook(request: Request):
# 1. Verify Authentication (Optional but recommended)
auth_header = request.headers.get("Authorization")
if auth_header != "Bearer your-secret-token":
raise HTTPException(status_code=401)
# 2. Parse Payload
payload = await request.json()
# 3. Process Data
company = payload["data"]["company"]
print(f"Received qualified lead: {company['name']}")
# 4. Return 200 OK
return {"status": "received"}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/openprospect', (req, res) => {
// 1. Verify Authentication
const authHeader = req.headers.authorization;
if (authHeader !== 'Bearer your-secret-token') {
return res.status(401).send('Unauthorized');
}
// 2. Process Data
const { company } = req.body.data;
console.log(`Received qualified lead: ${company.name}`);
// 3. Return 200 OK
res.status(200).json({ status: 'received' });
});
import express, { Request, Response } from 'express';
const app = express();
app.use(express.json());
interface WebhookPayload {
event: string;
data: {
company: { name: string; [key: string]: any };
prospects: any[];
};
}
app.post('/webhooks/openprospect', (req: Request, res: Response) => {
// 1. Verify Authentication
const authHeader = req.headers.authorization;
if (authHeader !== 'Bearer your-secret-token') {
return res.status(401).send('Unauthorized');
}
// 2. Process Data
const payload = req.body as WebhookPayload;
const { company } = payload.data;
console.log(`Received qualified lead: ${company.name}`);
// 3. Return 200 OK
res.status(200).json({ status: 'received' });
});
[HttpPost("webhooks/openprospect")]
public IActionResult ReceiveWebhook([FromBody] JsonElement payload, [FromHeader] string authorization)
{
// 1. Verify Authentication
if (authorization != "Bearer your-secret-token")
{
return Unauthorized();
}
// 2. Process Data
// Note: In a real app, define a class for the payload
var companyName = payload.GetProperty("data")
.GetProperty("company")
.GetProperty("name")
.GetString();
Console.WriteLine($"Received qualified lead: {companyName}");
// 3. Return 200 OK
return Ok(new { status = "received" });
}
4. Reliability & Retries¶
If your server returns an error (5xx) or times out:
- We retry 5 times with exponential backoff.
- Retry intervals: 1m, 5m, 15m, 1h, 6h.
- After 5 failures, the delivery is marked as
failed.
📥 Pull Model (API Access)¶
In the Pull model, you request data from our API on your own schedule.
1. Fetch Delivered Companies¶
Get all companies delivered for a specific prospect search, with optional time-based filtering for incremental syncs.
# Get all delivered companies
curl -X GET "https://api.openprospect.io/api/v1/deliveries/{prospect_search_id}/companies?limit=50" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
# Get only companies delivered since last sync (incremental)
curl -X GET "https://api.openprospect.io/api/v1/deliveries/{prospect_search_id}/companies?delivered_since=2025-01-15T00:00:00Z&limit=50" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
delivered_since |
ISO 8601 datetime | Only return companies delivered after this timestamp |
limit |
integer (1-100) | Number of results per page (default: 50) |
offset |
integer | Number of results to skip for pagination |
Tip: For CRM integrations, store the
delivered_attimestamp of the last synced company and use it asdelivered_sincein subsequent requests.
2. Pagination¶
We use standard limit/offset pagination.
limit: Number of items to return (default 20, max 100).offset: Number of items to skip.
Response:
🛡️ Best Practices¶
- Idempotency: Webhooks might be delivered more than once. Use
delivery_idorcompany.idto prevent duplicate processing. - Security: Always use authentication for your webhook endpoints.
- Rate Limiting: When using the Pull API, respect the rate limits headers (
RateLimit-Remaining).
🛠️ Managing Deliveries¶
You can programmatically manage your delivery configurations using the API.
List Deliveries¶
Get all your configured deliveries.
curl -X GET "https://api.openprospect.io/api/v1/deliveries" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Create a Delivery¶
Create a new delivery configuration.
curl -X POST "https://api.openprospect.io/api/v1/deliveries" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "CRM Sync",
"status": "active",
"schedule": "immediate"
}'
Add a Destination¶
Add a webhook or API destination to a delivery.
curl -X POST "https://api.openprospect.io/api/v1/deliveries/{id}/destinations" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"type": "webhook",
"url": "https://your-api.com/webhooks/openprospect",
"auth_type": "bearer",
"auth_token": "your-secret-token"
}'
Get Delivery Details¶
curl -X GET "https://api.openprospect.io/api/v1/deliveries/{id}" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"
Update a Delivery¶
curl -X PUT "https://api.openprospect.io/api/v1/deliveries/{id}" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "CRM Sync (Updated)",
"status": "paused"
}'
Delete a Delivery¶
curl -X DELETE "https://api.openprospect.io/api/v1/deliveries/{id}" \
-H "Authorization: Bearer ${OPENPROSPECT_API_KEY}"