Skip to main content
Most Bulkgrid write-style workflows are run-based. Instead of returning the full output immediately, the API creates a run that you inspect and retrieve results from.

When you will work with runs

You should expect run lifecycle handling for:
  • extraction requests
  • crawl requests
  • deep crawl requests
  • repository synchronization (source_sync)
  • generic run creation through POST /api/v1/runs
Search is different. POST /api/v1/search returns results directly in the response.

Run object basics

A run response includes fields that help you monitor progress and operational state. Important fields:
  • id: the run identifier used for later requests
  • status: current lifecycle state
  • type: crawl, deep_crawl, extract, or source_sync
  • urls: URLs associated with the run
  • queued, in_progress, done, failed: counters for work distribution
  • created_at, started_at, completed_at, updated_at: timing fields
  • last_error, error_code, error_count: failure context

Status values

The current API exposes these run statuses:
  • pending: the run has been accepted but work has not started yet
  • processing: the run is actively being worked on
  • completed: the run finished successfully enough for results to be retrieved
  • failed: the run ended in failure
  • cancelled: the run was cancelled before completion

Run lifecycle

  1. Create a run with POST /api/v1/extract, POST /api/v1/crawl, or POST /api/v1/deep-crawl.
  2. Store the returned id.
  3. Poll GET /api/v1/runs/{runId} until the run reaches a terminal state.
  4. If the status is completed, call GET /api/v1/runs/{runId}/results.
  5. If needed, retrieve content or screenshots from individual results.
  6. If the run fails, inspect error fields and decide whether to retry.

Check run status

Node.js and Python examples use the Bulkgrid SDKs. Set BULKGRID_API_KEY in your backend environment; cURL examples also use BULKGRID_BASE_URL=https://bulkgrid.com. Set RUN_ID and RESULT_ID to IDs returned by your requests.
Example shape:

Polling

A reasonable default:
  • first minute: every 2 to 5 seconds
  • larger crawl jobs: back off to 5 to 15 seconds
  • always apply a client-side maximum wait time
Stop on completed, failed, or cancelled. Inspect last_error, error_code, and per-URL failures before retrying. A completed run can still contain failed pages. Use source indexing status to confirm that content is searchable. A completed one-off crawl does not establish a searchable source.

List results

Requires results:read. List results after a run completes and inspect per-item errors before consuming content.
The response contains results, page, limit, and total. Each result can include URL/title metadata, output references, extraction_data, and error_message. Not every item produces every format.

Retrieve text content

The body is text, not a JSON envelope. Add download=true to request an attachment. For HTML, inline responses are formatted for display; downloads preserve the stored content.

Screenshots

The default response is JSON with signedUrl. Add download=true to retrieve the image bytes. Signed URLs are temporary; request a new URL instead of treating one as a permanent public asset URL. Request screenshot capture when creating the crawl. The screenshot endpoint cannot produce an image for a result that has none.

Store references

Persist run IDs, result IDs, and the structured data your application needs. Use the authenticated content endpoints when retrieving stored outputs. Handle unavailable formats and deleted results explicitly.

Retry a run

The API also supports a payload with a urls array for targeted retry behavior when appropriate. Use retry when:
  • the run failed for transient reasons
  • individual URLs should be retried
  • your application can safely tolerate repeated processing

Cancel a run

Expected success response:

When to retry vs cancel

Retry when the work is still useful and failure appears recoverable. Cancel when:
  • the request is obsolete
  • the customer changed scope
  • downstream systems no longer need the output
  • the run is consuming resources you no longer want to spend

Operational guidance

  • do not blindly retry permanent failures
  • log last_error, error_code, and run status history
  • make retry decisions in your backend, not from browser clients