Get Job Results (Blocking)
/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/resultsOverview
v2.16.0 Feature (updated v2.27.6): This endpoint blocks until all workflow stages complete for a specific SpiderMaps job, then returns aggregated results from all three services (SpiderMaps + SpiderSite + SpiderVerify).
Unlike /workflow-results which returns results for the entire campaign grouped by location, this endpoint focuses on a single job and returns ALL businesses from that job with their complete workflow data.
Blocking Behavior: By default, this endpoint waits until all businesses in the job complete processing (or timeout). Use wait=false to poll for current status instead.
Use Case: Perfect for n8n/Xano webhooks or real-time integrations where you need to wait for results before proceeding to the next step.
Path Parameters
campaign_idstringrequiredThe campaign ID returned from the submit endpoint (e.g., "camp_lu_restaurants_20251223_abc123")
job_idstringrequiredThe SpiderMaps job UUID returned from the /next endpoint
Query Parameters
waitbooleandefault: trueControls blocking behavior:
true(default): Block until all workflow stages complete or timeoutfalse: Return current status immediately (for polling)
Timeouts
| Stage | Timeout | Description |
|---|---|---|
| SpiderSite | 5 minutes | Per-business website crawling timeout |
| SpiderVerify | 2 minutes | Per-business email verification timeout |
| Maximum | 10 minutes | Absolute maximum wait time |
If a timeout occurs, the endpoint returns a partial status with all available data collected up to that point.
Response
successbooleanWhether the job processed without errors. A job with 0 results is still considered successful.
has_resultsbooleanv2.27.6: Whether businesses_total > 0. Use this for automation filtering to quickly skip empty locations.
job_idstringThe SpiderMaps job UUID
campaign_idstringThe campaign identifier
statusstringCurrent job status: queued, processing, completed, completed_with_errors, failed, partial
progressobjectProgress information (included while processing)
businesses_totalintegerTotal number of businesses in this job
businesses_with_domainsintegerBusinesses with valid website domains (not filtered)
businesses_filteredintegerBusinesses filtered out (social media, review sites, etc.)
spidersite_completedintegerNumber of SpiderSite jobs completed
spidersite_failedintegerNumber of SpiderSite jobs failed
spiderverify_completedintegerNumber of SpiderVerify jobs completed
spiderverify_failedintegerNumber of SpiderVerify jobs failed
total_emails_foundintegerTotal emails extracted from websites
total_valid_emailsintegerTotal emails confirmed as valid/deliverable
businessesarrayArray of all businesses with complete workflow data
processing_time_secondsnumberTotal time spent processing (or waiting)
spidersite_timed_outbooleanWhether SpiderSite timed out for any business
spiderverify_timed_outbooleanWhether SpiderVerify timed out for any business
error_messagestringError message if the job failed
Status Values
| Status | Description |
|---|---|
queued | Job is waiting for workers to pick it up |
processing | Workflow stages are currently running |
completed | All workflow stages finished successfully |
completed_with_errors | Some workflow jobs failed but useful data was collected |
failed | Processing failed (check error_message) |
partial | Timeout occurred but partial data is available |
Response Field Logic (v2.27.6)
| Scenario | success | has_results | status |
|---|---|---|---|
| 100 businesses, all OK | true | true | completed |
| 100 businesses, 3 failed | true | true | completed_with_errors |
| 0 businesses found | true | false | completed |
| SpiderMaps job failed | false | false | failed |
| Still processing | false | false | processing |
Automation Tip: Use has_results to quickly filter out empty locations:
if (response.has_results) {
// Process businesses
} else {
// Skip - no data for this location
}
Examples
- cURL (Blocking)
- cURL (Polling)
- Python (Blocking)
- Python (Polling)
- JavaScript
# Wait for job completion (blocks up to 10 minutes)
curl -X GET "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/camp_lu_restaurants_20251223_abc123/jobs/79719220-6309-4742-9850-adb988b5dd4a/results" \
-H "Authorization: Bearer <your_token>"
# Get current status without blocking
curl -X GET "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/camp_lu_restaurants_20251223_abc123/jobs/79719220-6309-4742-9850-adb988b5dd4a/results?wait=false" \
-H "Authorization: Bearer <your_token>"
import requests
API_URL = "https://spideriq.ai/api/v1"
HEADERS = {"Authorization": "Bearer <your_token>"}
# Submit next location
next_resp = requests.post(
f"{API_URL}/jobs/spiderMaps/campaigns/{campaign_id}/next",
headers=HEADERS
)
job_id = next_resp.json()['current_task']['job_id']
print(f"Submitted job: {job_id}")
# Block until complete (up to 10 minutes)
results = requests.get(
f"{API_URL}/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results",
headers=HEADERS
).json()
print(f"Status: {results['status']}")
print(f"Businesses: {results['businesses_total']}")
print(f"Emails found: {results['total_emails_found']}")
print(f"Valid emails: {results['total_valid_emails']}")
# Process businesses with valid emails
for biz in results['businesses']:
if biz['valid_emails_count'] > 0:
print(f"\n{biz['business_name']}:")
for email in biz['emails_verified']:
if email['status'] == 'valid':
print(f" - {email['email']} (score: {email['score']})")
import requests
import time
API_URL = "https://spideriq.ai/api/v1"
HEADERS = {"Authorization": "Bearer <your_token>"}
# Poll until complete
while True:
results = requests.get(
f"{API_URL}/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results?wait=false",
headers=HEADERS
).json()
print(f"Status: {results['status']} | "
f"Site: {results['spidersite_completed']}/{results['businesses_total']} | "
f"Verify: {results['spiderverify_completed']}")
if results['status'] in ('completed', 'partial', 'failed'):
break
time.sleep(5)
print(f"\nFinal: {results['total_valid_emails']} valid emails found")
// Blocking - wait for completion
const response = await fetch(
`https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/${campaignId}/jobs/${jobId}/results`,
{
headers: {
'Authorization': 'Bearer <your_token>'
}
}
);
const results = await response.json();
console.log(`Status: ${results.status}`);
console.log(`Businesses: ${results.businesses_total}`);
console.log(`Valid emails: ${results.total_valid_emails}`);
// Process results
results.businesses
.filter(biz => biz.valid_emails_count > 0)
.forEach(biz => {
console.log(`${biz.business_name}:`);
biz.emails_verified
.filter(e => e.status === 'valid')
.forEach(e => console.log(` - ${e.email}`));
});
Completed Response (with results):
{
"success": true,
"has_results": true,
"job_id": "79719220-6309-4742-9850-adb988b5dd4a",
"campaign_id": "camp_lu_restaurants_20251223_abc123",
"status": "completed",
"businesses_total": 100,
"businesses_with_domains": 69,
"businesses_filtered": 4,
"spidersite_completed": 69,
"spidersite_failed": 0,
"spiderverify_completed": 43,
"spiderverify_failed": 0,
"total_emails_found": 201,
"total_valid_emails": 8,
"businesses": [
{
"business_name": "Café des Tramways",
"business_place_id": "0x47954f2add89aa79:0x74c726ae28575bec",
"business_address": "79 Av. Pasteur, 2311 Luxembourg",
"business_phone": "35226201136",
"business_rating": 4.4,
"business_website": "http://www.cafedestramways.lu/",
"domain_filtered": false,
"filter_reason": null,
"spidersite_status": "completed",
"pages_crawled": 2,
"emails_found": ["info@cafedestramways.lu"],
"phones_found": [],
"social_media": {},
"company_info": {
"industry": "Restaurant/Bar",
"key_services": ["Flammekueches", "Burgers", "Cocktails"],
"target_audience": "Locals and tourists in Luxembourg"
},
"team_members": [],
"compendium": {
"available": true,
"chars": 3200,
"cleanup_level": "fit",
"storage_location": "spidermedia",
"download_url": "https://media.spideriq.ai/client-xxx/compendiums/job-uuid-1.md",
"filename": "compendiums/job-uuid-1.md",
"size_bytes": 3200,
"content_hash": "abc123...",
"estimated_tokens": 800
},
"spiderverify_status": "completed",
"emails_verified": [
{
"email": "info@cafedestramways.lu",
"status": "risky",
"score": 90,
"is_deliverable": true,
"is_free_email": false,
"is_disposable": false,
"is_role_account": true
}
],
"valid_emails_count": 0,
"spidersite_error": null,
"spiderverify_error": null
},
{
"business_name": "Glacier Bargello",
"business_place_id": "0x479548d196113821:0x6be5b2fd9b7d473f",
"business_address": "13 Rue du Fort Elisabeth, 1463 Luxembourg",
"business_phone": "35226296097",
"business_rating": 4.7,
"business_website": "http://www.bargello.lu/",
"domain_filtered": false,
"filter_reason": null,
"spidersite_status": "completed",
"pages_crawled": 3,
"emails_found": ["gelato@bargello.lu"],
"phones_found": [],
"social_media": {},
"company_info": {},
"team_members": [],
"compendium": {
"available": true,
"chars": 2100,
"cleanup_level": "fit",
"storage_location": "spidermedia",
"download_url": "https://media.spideriq.ai/client-xxx/compendiums/job-uuid-2.md",
"filename": "compendiums/job-uuid-2.md",
"size_bytes": 2100,
"content_hash": "def456...",
"estimated_tokens": 525
},
"spiderverify_status": "completed",
"emails_verified": [
{
"email": "gelato@bargello.lu",
"status": "valid",
"score": 100,
"is_deliverable": true,
"is_free_email": false,
"is_disposable": false,
"is_role_account": false
}
],
"valid_emails_count": 1,
"spidersite_error": null,
"spiderverify_error": null
}
],
"processing_time_seconds": 245.3,
"spidersite_timed_out": false,
"spiderverify_timed_out": false
}
Completed Response (0 results):
{
"success": true,
"has_results": false,
"job_id": "ac6fed8e-8188-4dbd-bdfa-6c636d49486b",
"campaign_id": "camp_au_restaurant_20260116155853_74a4a6b2",
"status": "completed",
"businesses_total": 0,
"businesses_with_domains": 0,
"businesses_filtered": 0,
"spidersite_completed": 0,
"spidersite_failed": 0,
"spiderverify_completed": 0,
"spiderverify_failed": 0,
"total_emails_found": 0,
"total_valid_emails": 0,
"businesses": [],
"processing_time_seconds": 0.05,
"spidersite_timed_out": false,
"spiderverify_timed_out": false
}
Partial Response (Timeout):
{
"success": true,
"has_results": true,
"job_id": "79719220-6309-4742-9850-adb988b5dd4a",
"campaign_id": "camp_lu_restaurants_20251223_abc123",
"status": "partial",
"businesses_total": 100,
"businesses_with_domains": 69,
"businesses_filtered": 4,
"spidersite_completed": 69,
"spidersite_failed": 0,
"spiderverify_completed": 43,
"spiderverify_failed": 0,
"total_emails_found": 201,
"total_valid_emails": 8,
"businesses": [...],
"processing_time_seconds": 601.36,
"spidersite_timed_out": true,
"spiderverify_timed_out": true
}
Error Responses
Invalid Job ID Format
{
"detail": "Invalid job_id format - must be a valid UUID"
}
Campaign Not Found
{
"detail": "Campaign not found"
}
Job Not Found
{
"detail": "Job not found"
}
No Workflow Configured
{
"detail": "This campaign does not have workflow configuration enabled"
}
Comparison with /workflow-results
| Feature | /jobs/{job_id}/results | /workflow-results |
|---|---|---|
| Scope | Single job | Entire campaign |
| Grouping | Flat list of businesses | Grouped by location |
| Blocking | Yes (optional) | No |
| Use case | Real-time integrations | Batch processing |
| Response size | Smaller (one job) | Larger (all jobs) |