SSpiderIQ
SSpiderIQ

Docs / api-reference/spidermaps-campaigns

SpiderMaps Campaigns

19 endpoints from the published OpenAPI import.

POST/api/v1/jobs/spiderMaps/campaigns/submit

Create a new SpiderMaps campaign

Create a new SpiderMaps scraping campaign for a specific country and query.

What happens:

  1. Campaign is created with specified filters
  2. Matching locations are pre-computed and stored
  3. Campaign is ready for /next calls

Filter Modes:

  • all - All locations in the country (default)
  • population - Filter by min/max population
  • cities_only - Only cities, no postcodes
  • custom - Specific location_ids
  • regions - Specific admin regions

Example - Scrape restaurants in France:

    {
      "query": "restaurants",
      "country_code": "FR",
      "name": "France Restaurants 2024",
      "filter": {
        "mode": "population",
        "min_population": 50000
      }
    }

Returns:

  • campaign_id - Use this for subsequent calls
  • total_locations - Number of locations to scrape
  • next_location_id - First location to be processed
Try it

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/submit' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "search_query": "string",
  "query": "string",
  "country_code": "string",
  "name": "string",
  "filter": {
    "mode": "all",
    "min_population": 0,
    "max_population": 0,
    "location_ids": [
      0
    ],
    "admin_regions": [
      "string"
    ],
    "parent_city": "string",
    "include_postcodes": false,
    "exhaustive": false
  },
  "max_results": 100,
  "extract_reviews": false,
  "extract_photos": false,
  "lang": "en",
  "store_images": true,
  "validate_phones": true,
  "fuzziq_enabled": true,
  "fuzziq_unique_only": true,
  "skip_proxy": false,
  "test": false,
  "workflow": {
    "spidersite": {
      "enabled": false,
      "mode": {},
      "max_pages": 25,
      "crawl_strategy": "bestfirst",
      "target_pages": [
        "contact",
        "about",
        "team",
        "news",
        "blog"
      ],
      "enable_spa": true,
      "spa_timeout": 30,
      "extract_team": false,
      "extract_company_info": false,
      "extract_pain_points": false,
      "product_description": {},
      "icp_description": {},
      "compendium": {},
      "timeout": 30
    },
    "spiderverify": {
      "enabled": false,
      "check_gravatar": false,
      "check_dnsbl": false,
      "smtp_timeout_secs": 45,
      "max_emails_per_business": 10
    },
    "vayapin": {
      "enabled": false
    },
    "social_media_enrichment": {
      "enabled": true
    },
    "smartlead": {
      "enabled": false,
      "connection_id": {},
      "remote_campaign_id": {},
      "remote_campaign_name": {},
      "limit": {},
      "only_with_vayapin_seo": false,
      "only_with_vayapin_pin": false,
      "field_map": {}
    },
    "filter_social_media": true,
    "filter_review_sites": true,
    "filter_directories": true,
    "filter_maps": true
  }
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/submit",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"search_query": "string", "query": "string", "country_code": "string", "name": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "extract_reviews": false, "extract_photos": false, "lang": "en", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": false, "test": false, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/submit", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"search_query": "string", "query": "string", "country_code": "string", "name": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "extract_reviews": false, "extract_photos": false, "lang": "en", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": false, "test": false, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"search_query": "string", "query": "string", "country_code": "string", "name": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "extract_reviews": false, "extract_photos": false, "lang": "en", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": false, "test": false, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/submit", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
201Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/estimate

Pre-flight campaign estimate (locations + per-stage billable jobs)

Outscraper-style pre-flight estimate for a campaign — writes no rows.

Returns the number of locations the campaign would fan out to plus the estimated billable-job COUNTS per stage (spiderMaps / spiderSite / spiderVerify / spiderVayapin) so the UI can show a Proceed/Upgrade decision before the campaign is created.

Cost is expressed as job counts, not USD — there is no locally-queryable per-job USD price. Downstream stage counts use documented hit-rate assumptions (see the assumptions field); spiderMaps is exactly one job per location.

requires_upgrade is True when the location volume exceeds the global per-campaign backstop. This is a pure READ — it is not a metered dispatcher submission.

Try it

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/estimate' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "search_query": "string",
  "country_code": "string",
  "filter": {
    "mode": "all",
    "min_population": 0,
    "max_population": 0,
    "location_ids": [
      0
    ],
    "admin_regions": [
      "string"
    ],
    "parent_city": "string",
    "include_postcodes": false,
    "exhaustive": false
  },
  "max_results": 100,
  "workflow": {
    "spidersite": {
      "enabled": false,
      "mode": {},
      "max_pages": 25,
      "crawl_strategy": "bestfirst",
      "target_pages": [
        "contact",
        "about",
        "team",
        "news",
        "blog"
      ],
      "enable_spa": true,
      "spa_timeout": 30,
      "extract_team": false,
      "extract_company_info": false,
      "extract_pain_points": false,
      "product_description": {},
      "icp_description": {},
      "compendium": {},
      "timeout": 30
    },
    "spiderverify": {
      "enabled": false,
      "check_gravatar": false,
      "check_dnsbl": false,
      "smtp_timeout_secs": 45,
      "max_emails_per_business": 10
    },
    "vayapin": {
      "enabled": false
    },
    "social_media_enrichment": {
      "enabled": true
    },
    "smartlead": {
      "enabled": false,
      "connection_id": {},
      "remote_campaign_id": {},
      "remote_campaign_name": {},
      "limit": {},
      "only_with_vayapin_seo": false,
      "only_with_vayapin_pin": false,
      "field_map": {}
    },
    "filter_social_media": true,
    "filter_review_sites": true,
    "filter_directories": true,
    "filter_maps": true
  }
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/estimate",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"search_query": "string", "country_code": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/estimate", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"search_query": "string", "country_code": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"search_query": "string", "country_code": "string", "filter": {"mode": "all", "min_population": 0, "max_population": 0, "location_ids": [0], "admin_regions": ["string"], "parent_city": "string", "include_postcodes": false, "exhaustive": false}, "max_results": 100, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/estimate", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
PATCH/api/v1/jobs/spiderMaps/campaigns/{campaign_id}

Update campaign configuration

Update an existing campaign's configuration.

What can be updated:

  • search_query - Changes search term for future jobs
  • name - Campaign display name
  • SpiderMaps options (max_results, extract_reviews, extract_photos, lang, etc.)
  • workflow - Workflow configuration (merged with existing)

What cannot be updated:

  • country_code - Would change location set
  • filter - Locations already computed at creation

Restrictions:

  • Only active or stopped/paused campaigns can be updated
  • Completed campaigns cannot be modified
  • Changes only affect PENDING locations (already submitted jobs unaffected)

Example - Update search query and max_results:

    {
      "search_query": "coffee shops",
      "max_results": 200
    }

Example - Enable workflow after campaign creation:

    {
      "workflow": {
        "spidersite": {
          "enabled": true,
          "extract_team": true
        }
      }
    }

Returns: Full campaign status with updated values (same as GET /status endpoint).

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X PATCH 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "search_query": "string",
  "query": "string",
  "name": "string",
  "max_results": 0,
  "extract_reviews": true,
  "extract_photos": true,
  "lang": "string",
  "store_images": true,
  "validate_phones": true,
  "fuzziq_enabled": true,
  "fuzziq_unique_only": true,
  "skip_proxy": true,
  "test": true,
  "workflow": {
    "spidersite": {
      "enabled": false,
      "mode": {},
      "max_pages": 25,
      "crawl_strategy": "bestfirst",
      "target_pages": [
        "contact",
        "about",
        "team",
        "news",
        "blog"
      ],
      "enable_spa": true,
      "spa_timeout": 30,
      "extract_team": false,
      "extract_company_info": false,
      "extract_pain_points": false,
      "product_description": {},
      "icp_description": {},
      "compendium": {},
      "timeout": 30
    },
    "spiderverify": {
      "enabled": false,
      "check_gravatar": false,
      "check_dnsbl": false,
      "smtp_timeout_secs": 45,
      "max_emails_per_business": 10
    },
    "vayapin": {
      "enabled": false
    },
    "social_media_enrichment": {
      "enabled": true
    },
    "smartlead": {
      "enabled": false,
      "connection_id": {},
      "remote_campaign_id": {},
      "remote_campaign_name": {},
      "limit": {},
      "only_with_vayapin_seo": false,
      "only_with_vayapin_pin": false,
      "field_map": {}
    },
    "filter_social_media": true,
    "filter_review_sites": true,
    "filter_directories": true,
    "filter_maps": true
  }
}'
Python
import httpx

resp = httpx.patch(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"search_query": "string", "query": "string", "name": "string", "max_results": 0, "extract_reviews": true, "extract_photos": true, "lang": "string", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": true, "test": true, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"search_query": "string", "query": "string", "name": "string", "max_results": 0, "extract_reviews": true, "extract_photos": true, "lang": "string", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": true, "test": true, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"search_query": "string", "query": "string", "name": "string", "max_results": 0, "extract_reviews": true, "extract_photos": true, "lang": "string", "store_images": true, "validate_phones": true, "fuzziq_enabled": true, "fuzziq_unique_only": true, "skip_proxy": true, "test": true, "workflow": {"spidersite": {"enabled": false, "mode": {}, "max_pages": 25, "crawl_strategy": "bestfirst", "target_pages": ["contact", "about", "team", "news", "blog"], "enable_spa": true, "spa_timeout": 30, "extract_team": false, "extract_company_info": false, "extract_pain_points": false, "product_description": {}, "icp_description": {}, "compendium": {}, "timeout": 30}, "spiderverify": {"enabled": false, "check_gravatar": false, "check_dnsbl": false, "smtp_timeout_secs": 45, "max_emails_per_business": 10}, "vayapin": {"enabled": false}, "social_media_enrichment": {"enabled": true}, "smartlead": {"enabled": false, "connection_id": {}, "remote_campaign_id": {}, "remote_campaign_name": {}, "limit": {}, "only_with_vayapin_seo": false, "only_with_vayapin_pin": false, "field_map": {}}, "filter_social_media": true, "filter_review_sites": true, "filter_directories": true, "filter_maps": true}}`)
	req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
DELETE/api/v1/jobs/spiderMaps/campaigns/{campaign_id}

Delete a campaign

Delete a campaign and all of its related data.

The campaign must be stopped first — this returns 409 if it still has active jobs (submitted/processing). Cascade removes campaign locations, workflow jobs, and run-tracking rows. Returns 404 if the campaign does not exist or is not owned by the caller.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X DELETE 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.delete(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/next

Get next location and submit job

Get the next location for a campaign and automatically submit a SpiderMaps job.

What happens:

  1. Finds the next pending location in the campaign
  2. Submits a SpiderMaps job for that location
  3. Updates campaign progress
  4. Returns job details and progress

N8N/Xano Workflow:

    Loop while has_more == true:
        POST /campaigns/{id}/next
        # Wait for job to complete (optional)
        # Process results

Response Fields:

  • has_more - true if more locations remain
  • current_task - Details of the submitted job
  • progress - Campaign progress statistics

When has_more is false:

  • Campaign is complete
  • No more locations to process

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/next' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/next",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/next", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/next", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/status

Get campaign status

Get detailed status and statistics for a campaign.

Returns:

  • Campaign configuration (query, country, filters)
  • Progress statistics (completed, failed, pending)
  • Job statistics by status (queued, processing, completed, failed)
  • Total businesses found

Query Parameters:

  • format: Response format — json (default), yaml, md or llm

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
formatqueryanyfalseResponse format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422.
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/status' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/status",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/status", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/status", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stage-progress

Get per-stage campaign progress

Per-stage breakdown of campaign progress with a velocity-based ETA.

Replaces the misleading "0/N 0%" rollup with location-level completed / active / queued / failed counters per pipeline stage (Maps / Site / Verify / Vayapin). The stage list is derived from the campaign's workflow_config — Site/Verify/Vayapin only appear when their config block has enabled=True.

Cached in Redis for 30s. Bearer-authenticated mirror of /api/v1/dashboard/client/campaigns/{id}/stage-progress.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stage-progress' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stage-progress",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stage-progress", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stage-progress", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs

Get campaign Inngest runs

Get all Inngest workflow runs for a campaign.

Returns:

  • List of runs with status, timing, and Inngest correlation info
  • Useful for visualizing campaign workflow execution (waterfall diagram)

Note: Run IDs are correlated asynchronously after event submission. New runs may take a few seconds to appear with full run_id.

v2.54.0: Added for Inngest run visualization feature.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
pagequeryintegerfalsePage number
page_sizequeryintegerfalseItems per page
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs/{run_id}

Get campaign run detail with steps

Get detailed information about a specific Inngest run including all steps.

Returns:

  • Full run details with timing and status
  • Steps array for waterfall visualization
  • Pre-computed waterfall_data for frontend rendering

Use this endpoint to display the Inngest run waterfall trace.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
run_idpathintegertrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs/{run_id}' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs/{run_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs/{run_id}", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/runs/{run_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-progress

Get workflow progress and health metrics

Get real-time workflow progress and health metrics for a campaign.

Returns:

  • Active/completed/failed run counts
  • Details of currently running workflows with current step
  • Location progress statistics
  • Timing statistics (avg, min, max workflow duration)
  • Health metrics for stuck workflow detection

Use Cases:

  • Dashboard progress monitoring
  • Detecting stuck workflows
  • Understanding workflow performance

v2.60.0: Added for campaign workflow monitoring feature.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-progress' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-progress",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-progress", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-progress", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/abort-workflow

Abort all running workflows for a campaign

Abort all running Inngest workflow runs for a campaign.

What happens:

  1. Campaign workflow_status is set to 'aborted'
  2. All running/queued orchestrated_campaign_runs are marked as aborted
  3. Submitted campaign_locations are marked as skipped
  4. Running workflow steps will check for abort and stop early

Use Cases:

  • Emergency stop when workflows are stuck
  • Cancel long-running campaigns
  • Clear stuck workflow runs before retry

Note: This does NOT stop already-running worker jobs (SpiderMaps, SpiderSite, etc). It only prevents new workflow steps from starting.

v2.60.0: Added for campaign workflow safeguards.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
reasonquerystringfalseReason for abort
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/abort-workflow' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/abort-workflow",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/abort-workflow", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/abort-workflow", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stop

Stop a campaign

Stop an active campaign.

Stopped campaigns can be resumed later with /continue. Jobs already submitted will continue processing.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stop' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stop",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stop", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/stop", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/continue

Continue a stopped campaign

Resume a stopped or paused campaign.

Campaign will continue from where it left off.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/continue' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/continue",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/continue", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/continue", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/locations/{location_id}/retry

Retry a campaign location

Re-run a failed or completed location (dispatches worker jobs again).

  • retry_mode="full": re-run the whole workflow from SpiderMaps
  • retry_mode="site": keep Maps results, re-run SpiderSite + SpiderVerify
  • retry_mode="verify": keep Site results, re-run SpiderVerify only

location_id is the id returned by GET /{campaign_id}/jobs (campaign_locations.id). Max 3 retries per location — returns 400 once that limit is hit.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
location_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/locations/{location_id}/retry' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "retry_mode": "full"
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/locations/{location_id}/retry",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"retry_mode": "full"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/locations/{location_id}/retry", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"retry_mode": "full"})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"retry_mode": "full"}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/locations/{location_id}/retry", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/retry-failed

Retry all failed locations

Re-run every failed location in the campaign (up to max_locations). Locations that already hit the 3-retry limit are skipped, not errored.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
max_locationsqueryintegerfalseMax locations to retry
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/retry-failed' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/retry-failed",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/retry-failed", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/retry-failed", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns

List campaigns

List all campaigns for the current client.

Filter Options:

  • status: Filter by campaign status (active, paused, completed, stopped)
  • country_code: Filter by country

Query Parameters:

  • format: Response format — json (default), yaml, md or llm

Parameters

NameInTypeRequiredDescription
statusqueryanyfalseCampaign status
country_codequeryanyfalseCountry code
pagequeryintegerfalsePage number
page_sizequeryintegerfalseItems per page
formatqueryanyfalseResponse format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422.
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs

List jobs for a campaign

Get a paginated list of all jobs submitted for a campaign.

Filter Options:

  • status: Filter by campaign_location status (pending, submitted, completed, failed, skipped)
  • job_status: Filter by actual job status (queued, processing, completed, failed)

Includes:

  • Job IDs linked to each location
  • Job status from both campaign_locations and jobs tables
  • Results count and error messages
  • Submission and completion timestamps

Use Cases:

  • Monitor job progress within a campaign
  • Identify failed jobs for retry
  • Get job IDs for fetching detailed results via /{campaign_id}/jobs/{job_id}/results

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
location_statusqueryanyfalseFilter by campaign_location status
job_statusqueryanyfalseFilter by actual job status
pagequeryintegerfalsePage number
page_sizequeryintegerfalseItems per page
include_summaryquerybooleanfalseInclude status summary counts
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-results

Get aggregated workflow results

Get complete aggregated results from the workflow chain: SpiderMaps → SpiderSite → SpiderVerify

Returns data from all three services combined:

  • SpiderMaps: Business listings (name, address, phone, rating)
  • SpiderSite: Website data (emails, social media, company info)
  • SpiderVerify: Email verification results (validity, score)

Note: Only available for campaigns created with workflow configuration.

Query Parameters:

  • format: json (default) / llm -> JSON; yaml -> text/yaml; md -> text/markdown. Any other value is a 422. Before SDS-26 this route declared no format at all, so FastAPI DROPPED it: ?format=md answered 200 application/json and so did ?format=bogus.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
include_filteredquerybooleanfalseInclude businesses that were filtered out
formatqueryanyfalseResponse format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422.
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-results' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-results",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-results", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/workflow-results", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results

Wait for workflow job completion (blocking)

Blocks until all workflow stages complete for a specific SpiderMaps job, then returns aggregated results from SpiderMaps + SpiderSite + SpiderVerify.

Timeouts:

  • SpiderSite: 5 minutes per business
  • SpiderVerify: 2 minutes per business
  • Maximum total wait: 10 minutes

Partial Results: If SpiderVerify times out but SpiderSite completed, returns partial results with SpiderSite data (compendium, emails_found, company_info, etc.)

Query Parameters:

  • wait=true (default): Block until all businesses complete or timeout
  • wait=false: Return current status immediately (for polling)

Status Values:

  • queued - Waiting for workers
  • processing - Currently being processed
  • completed - All stages finished successfully
  • failed - Processing failed
  • partial - SpiderVerify timed out but SpiderSite data available

Query Parameters:

  • format: json (default) / llm -> JSON; yaml -> text/yaml; md -> text/markdown. Any other value is a 422. Before SDS-26 this route declared no format at all, so FastAPI DROPPED it and ?format=md answered 200 application/json.

Parameters

NameInTypeRequiredDescription
campaign_idpathstringtrue
job_idpathstringtrue
waitquerybooleanfalseWait for completion (blocking). If false, returns current state immediately.
formatqueryanyfalseResponse format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422.
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/jobs/spiderMaps/campaigns/{campaign_id}/jobs/{job_id}/results", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error