Research Jobs API endpoint
Returns the state of a research job by `job_id`: queued, running, cancelling, succeeded, failed or cancelled. The response carries `progress` counts, `research` progress (round, searches completed, sources read, questions answered), usage, warnings, `partial`, `deadline_at` and any error. A job not started within 30 minutes fails with `timeout`.
/research/jobs/{job_id}Returns status and cumulative usage for the authenticated owner’s research job.
While the job is queued, deadline_at is the latest possible finish time. When work starts it moves earlier to the start time plus limits.timeout_seconds. A job that waits more than 30 minutes without starting fails with a timeout error ("job was not started within the 30-minute queue limit"), completion_reason deadline, and no charge.
Path parameters:
job_id (required): the ID returned by research-start.Example request path: GET /api/v1/research/jobs/job-123.
Completion reason values: frontier_exhausted, completed, page_limit, round_limit, deadline, budget, cancelled, upstream_failure, internal_failure.
The response includes research progress (round, max_rounds, searches_completed, sources_read, questions_answered, questions_total), usage, warnings, and an optional client-safe error. Results remain readable while settlement is pending.
A terminal evidence-only fallback has partial:true, matching the results response. Input/output or authorization caps report budget; source/provider failures report upstream_failure; a bounded search with no evidence reports round_limit. A completed validated report or structured result retains completed and partial:false. Job success can retain partial evidence even when the requested synthesis is unavailable. When some searches or page reads fail but evidence remains, the report is still written from that evidence and returned with partial:true.
questions_answered counts rounds with at least one validated, retained non-failure source outcome. A genuine empty successful search counts; failed, uncertain, or budget-denied source work does not. round still records the attempted round, so an attempted round can leave questions_answered unchanged.
Warning code values: source_failed, source_not_indexed, discovery_truncated, ranking_window_limit, imprecise_date_excluded, content_unavailable, cached_source_stale.
Failure reason values: invalid_url, unsupported_content_type, blocked, not_found, rate_limited, timeout, upstream_error, internal_error, out_of_scope, robots_disallowed, duplicate, limit_reached, unsupported_filter, unknown_source, idempotency_conflict, invalid_cursor, result_expired, full_text_unavailable, budget_exhausted.
Shared response schema enum values (the owning endpoint emits its own job kind): crawl, ingestion.
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| x-api-key (header) | string | Yes | API key | ||
| job_id (path) | string | Yes | Research job ID | job-123 |
curl -X GET "https://api.crawlora.net/api/v1/research/jobs/job-123" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"job_id": "job-123",
"kind": "research",
"state": "running",
"cancel_requested": false,
"partial": false,
"created_at": "2026-10-09T11:00:00Z",
"updated_at": "2026-10-09T11:01:00Z",
"deadline_at": "2026-10-09T11:03:00Z",
"research": {
"round": 1,
"max_rounds": 3,
"searches_completed": 2,
"sources_read": 1,
"questions_answered": 1,
"questions_total": 3
},
"usage": {
"search_requests": 2,
"fetch_attempts": 1,
"fetched_urls": 1,
"browser_renders": 0,
"input_tokens": 0,
"output_tokens": 0,
"credits_reserved": 100,
"credits_charged": 11,
"credits_released": 0,
"settlement_pending": true
},
"warnings": []
}
}Request schema
No body schema
Response schema
#/definitions/researchjobs.researchStatusResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | ||||
| data | retrievaltypes.JobStatus | No | ||||
| data.cancel_requested | boolean | No | ||||
| data.completion_reason | retrievaltypes.CompletionReason | No | frontier_exhausted, completed, page_limit, round_limit, deadline, budget, cancelled, upstream_failure, internal_failure | |||
| data.created_at | string | No | ||||
| data.deadline_at | string | No | ||||
| data.error | retrievaltypes.Failure | No | Failure record, 4 fields: message, reason, retry_after_seconds, retryable. Described under Cancel a research job API. | |||
| data.expires_at | string | No | ||||
| data.job_id | string | No | ||||
| data.kind | retrievaltypes.JobKind | No | crawl, research, ingestion | |||
| data.partial | boolean | No | ||||
| data.progress | retrievaltypes.JobProgress | No | JobProgress record, 8 fields: admitted, discovered, discovery_excluded, failed, in_flight, queued, skipped, succeeded. Described under Cancel a research job API. | |||
| data.research | retrievaltypes.ResearchProgress | No | ResearchProgress record, 6 fields: max_rounds, questions_answered, questions_total, round, searches_completed, sources_read. Described under Cancel a research job API. | |||
| data.state | retrievaltypes.JobState | No | queued, running, cancelling, succeeded, failed, cancelled | |||
| data.updated_at | string | No | ||||
| data.usage | retrievaltypes.Usage | No | Usage record, 10 fields: browser_renders, credits_charged, credits_released, credits_reserved, fetch_attempts, fetched_urls, input_tokens, output_tokens, search_requests, settlement_pending. Described under Cancel a research job API. | |||
| data.warnings | array | No | ||||
| data.warnings[].code | retrievaltypes.WarningCode | No | source_failed, source_not_indexed, discovery_truncated, ranking_window_limit, imprecise_date_excluded, content_unavailable, cached_source_stale | |||
| data.warnings[].message | string | No | ||||
| data.warnings[].source_id | string | No | ||||
| msg | string | No |
| Status | Description | Schema |
|---|---|---|
| 401 | Authentication required | #/definitions/app.Response |
| 404 | Research job not found | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/research/jobs/job-123" \
-H "x-api-key: $CRAWLORA_API_KEY"