Get Search Job Status
curl --request GET \
--url https://api.spidra.io/api/search/{jobId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.spidra.io/api/search/{jobId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.spidra.io/api/search/{jobId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.spidra.io/api/search/{jobId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.spidra.io/api/search/{jobId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.spidra.io/api/search/{jobId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spidra.io/api/search/{jobId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "active",
"progress": {
"message": "Searching the web...",
"progress": 0.3
},
"result": null,
"error": null
}Search Endpoints
Get Search Job Status
Poll the status of a running search job. Returns progress and the full result set when the job completes.
GET
/
search
/
{jobId}
Get Search Job Status
curl --request GET \
--url https://api.spidra.io/api/search/{jobId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.spidra.io/api/search/{jobId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.spidra.io/api/search/{jobId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.spidra.io/api/search/{jobId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.spidra.io/api/search/{jobId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.spidra.io/api/search/{jobId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.spidra.io/api/search/{jobId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"status": "active",
"progress": {
"message": "Searching the web...",
"progress": 0.3
},
"result": null,
"error": null
}Polling Pattern
Every search job goes through the same async pattern as scrape and crawl: submit, then poll this endpoint untilstatus is completed or failed. Plain search jobs usually resolve in 1-8 seconds (occasional automatic retries take a bit longer), so in practice a couple of polls is normal. If you’d rather skip polling entirely for a fast search, see wait on the submit endpoint.
A search with scrapeOptions set takes noticeably longer. It doesn’t report completed until every result has actually been scraped, so expect however long the slowest page takes, not the usual few seconds.
async function waitForResult(jobId) {
while (true) {
const res = await fetch(`https://api.spidra.io/api/search/${jobId}`, {
headers: { Authorization: 'Bearer YOUR_API_KEY' }
});
const data = await res.json();
if (data.status === 'completed') return data.result;
if (data.status === 'failed') throw new Error(data.error);
await new Promise(r => setTimeout(r, 1500));
}
}
Response Structure
{
"status": "completed",
"progress": { "message": "Search completed successfully", "progress": 1 },
"result": {
"success": true,
"data": {
"web": [
{ "title": "...", "url": "...", "description": "...", "position": 1 }
]
},
"stats": {
"durationMs": 1714
}
},
"error": null
}
result.data
One key per requested source (web, news, images, videos, research, developer), each an array of result objects, plus nextPageTokens when a source has more pages available. Fields vary slightly by source:
| Field | Sources | Description |
|---|---|---|
title | all | Result title |
url | all | Link to the result |
description | web, news, research | Snippet text, or the paper’s abstract for research |
position | all | 1-indexed rank within that source |
imageUrl | images | Full-size image URL |
thumbnailUrl | images, news, videos | Thumbnail URL |
imageWidth | images | Width in pixels, when reported |
imageHeight | images | Height in pixels, when reported |
source | news, research | Publisher name (news), or journal/repository name such as "arXiv" (research) |
date | news, videos, research | Relative or absolute date string, or publication date for research |
duration | videos | Video length, e.g. "12:43" |
authors | research, developer | Comma-separated author names (research), or the reporter’s GitHub username (developer) |
doi | research | Digital Object Identifier, when the paper has one |
markdown | web | Only present if scrapeOptions was requested and content-fetch succeeded for this result |
result.stats
| Field | Description |
|---|---|
durationMs | How long the whole job took, in milliseconds |
result.success: false with an empty data object means Spidra could not retrieve results for every requested source after retrying. This is rare, but it’s a normal “no results” outcome, not treated as a hard error, and isn’t billed.Authorizations
BearerAuthApiKeyAuth
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
The job ID returned from POST /search
Was this page helpful?

