UniDataHub Business Data API
Integrate fresh, high-intent business records directly into your CRM, lead enrichment pipeline, or SaaS platform. Submit asynchronous extraction jobs, poll progress, and retrieve structured results on demand.
curl -X POST https://unidatahub.com/api/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"queries": [
"dentists in Boston, MA",
"pediatricians in Cambridge, MA"
],
"depth": 20,
"email": true,
"json": false
}'
Submit Job
Send a batch of up to 100 search queries with scraper parameters (depth, email, json, zoom). Credits are deducted atomically.
Asynchronous Polling
Scraping runs on isolated cloud compute. Poll GET /api/v1/jobs/{jobId} every 3 to 5 seconds until the status reaches COMPLETED or FAILED.
Stream Results
Retrieve structured business listings formatted either as standard sanitized UTF-8 CSV or high-efficiency JSON Lines (one JSON object per line).
Supported Scraper Options
Configurable parameters supported by our data extraction engine.
| Parameter | Type | Default | Allowed Range / Format | Description |
|---|---|---|---|---|
| queries | array of string | Required | 1 – 100 items (max 300 chars each) | List of localized search query phrases (e.g. "coffee shops in Seattle, WA"). |
| depth | integer | 20 | 1 – 100 | Maximum listing depth to scrape per query. |
| boolean | false | true / false | When true, enables deep contact enrichment to extract business emails from websites. | |
| json | boolean | false | true / false | When true, results are delivered as JSON Lines (.jsonl) instead of CSV. |
| lang | string | "en" | ISO language code ("en", "es", "de", "hi") | Localization language code for listing titles and review fields. |
| zoom | integer | 15 | 0 – 21 | Map zoom viewport level for geospatial radius bounding. |
| geo | string | null | "latitude,longitude" | Optional center coordinates for localized boundary scraping (e.g. "37.7749,-122.4194"). |
Endpoint Reference
Base URL: https://unidatahub.com/api/v1
Submit an asynchronous batch extraction job. Deducts 1 credit per query from your shared account balance. Returns a 202 Accepted response with the new job_id.
{
"queries": [
"real estate agents in Austin, TX",
"property managers in Austin, TX"
],
"depth": 25,
"email": true,
"json": false
}
{
"success": true,
"job_id": "671e3b8a1c9d2f0012ab34cd",
"status": "QUEUED",
"query_count": 2,
"credits_used": 2,
"credit_balance": 48,
"format": "csv",
"status_url": "/api/v1/jobs/671e3b8a1c9d2f0012ab34cd",
"results_url": "/api/v1/jobs/671e3b8a1c9d2f0012ab34cd/results"
}
Check the current status and metadata of a submitted job. Terminal statuses are COMPLETED and FAILED.
{
"job_id": "671e3b8a1c9d2f0012ab34cd",
"status": "COMPLETED",
"query_count": 2,
"row_count": 142,
"format": "csv",
"credits_used": 2,
"results_ready": true,
"download_url": "/api/v1/jobs/671e3b8a1c9d2f0012ab34cd/results/download",
"created_at": "2026-10-24T18:22:10Z",
"updated_at": "2026-10-24T18:24:35Z"
}
Returns the secure download descriptor for a completed job. Pass ?download=true to stream the data file directly. If called while the job is still running, returns 409 Conflict.
{
"job_id": "671e3b8a1c9d2f0012ab34cd",
"status": "COMPLETED",
"format": "csv",
"row_count": 142,
"filename": "unidatahub_job_671e3b8a1c9d2f0012ab34cd.csv",
"download_url": "/api/v1/jobs/671e3b8a1c9d2f0012ab34cd/results/download",
"expires_in_seconds": 900
}
Complete Client Implementation Examples
import time
import requests
API_BASE = "https://unidatahub.com/api/v1"
API_KEY = "YOUR_API_KEY" # Replace with key generated in Developer Dashboard
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
# 1. Submit extraction job
submit_payload = {
"queries": [
"accountants in Dallas, TX",
"tax consultants in Dallas, TX",
],
"depth": 20,
"email": True,
"json": False, # True for JSON Lines, False for CSV
}
resp = requests.post(f"{API_BASE}/jobs", json=submit_payload, headers=headers)
resp.raise_for_status()
job = resp.json()
job_id = job["job_id"]
print(f"Submitted Job ID: {job_id}. Polling status...")
# 2. Poll until terminal status with exponential backoff
backoff = 3.0
max_timeout_seconds = 600
start_time = time.time()
while time.time() - start_time < max_timeout_seconds:
status_resp = requests.get(f"{API_BASE}/jobs/{job_id}", headers=headers)
status_data = status_resp.json()
status = status_data.get("status")
if status == "COMPLETED":
print(f"Extraction succeeded! Extracted {status_data.get('row_count')} records.")
break
elif status == "FAILED":
raise RuntimeError(f"Job failed: {status_data.get('error')}")
time.sleep(backoff)
backoff = min(backoff * 1.25, 10.0)
# 3. Stream download results file
download_url = f"{API_BASE}/jobs/{job_id}/results/download"
with requests.get(download_url, headers=headers, stream=True) as dl_resp:
dl_resp.raise_for_status()
with open("results.csv", "wb") as f:
for chunk in dl_resp.iter_content(chunk_size=65536):
if chunk:
f.write(chunk)
print("Downloaded results successfully to results.csv.")
HTTP Status & Error Responses
| Status | Code Name | Description & Remediation |
|---|---|---|
| 202 | Accepted | Job accepted into queue. Save job_id and poll the status endpoint. |
| 200 | OK | Request succeeded. Status or download descriptor returned. |
| 400 | Bad Request | Invalid payload, empty query list, or option exceeding maximum boundaries (e.g. depth > 100). |
| 401 | Unauthorized | Missing, malformed, or revoked API key. Verify key in Developer Dashboard. |
| 402 | Payment Required | Insufficient account credits to cover the query count. Recharge credits in your dashboard. |
| 404 | Not Found | The specified job_id does not exist or belongs to another user account. |
| 409 | Conflict | Results requested before job has completed. Continue polling status until COMPLETED. |
| 429 | Too Many Requests | Rate limit exceeded (standard tier: 20 jobs/hour). Back off and retry. |
| 502 | Bad Gateway | Temporary upstream error. Any deducted credits are automatically refunded to your balance. |
Ready to Integrate Fresh Business Data?
Get started today with 5 free credits on signup. Generate individual keys, automate extraction pipelines, and scale effortlessly.