Skip to content

Find a component

Loading the directory…

↑ ↓ to select · Enter to open · Esc to closeBrowse all →
Contributor login

Bright Data

Asynchronous dataset acquisition

Bijection source
git clone https://github.com/bijectionhq/bright-data.git
cd bright-data
git checkout 42ab9b09e613314c409d40a1a8c9d8647b186fe2

Bijection repository access is required. Request access.

Description

Asynchronous dataset acquisition

Explore the package README for API concepts, configuration, and examples. Check the Bijection source for adaptation-specific setup.

Available to evaluate

Review the source and its dependencies before adopting this package. Source availability does not establish npm publication or runtime qualification.

Getting started

  1. Get the source at the revision above and read its package documentation.
  2. Check the required Bijection SDK version, dependencies, and external service credentials.
  3. Follow the package setup instructions and the guide to using components.
  4. Exercise the component in your deployment according to your project’s verification rules.

Open source

Maintained source: bijectionhq/bright-data. Based on sholajegede/convex-bright-data-datasets. License: Apache-2.0. Consult the repository for license terms, notices, and contributor attribution.

From the upstream publisher

A convex bright data datasets component for Convex.

Explore the demo ↗

Upstream overview

From the upstream package documentation.

This component integrates Bright Data's web scraping datasets with Convex's reactive database. It handles the complete pipeline from triggering async collections (LinkedIn profiles, Amazon products, job listings, etc.) to receiving webhook results and storing structured records. Developers get real-time data subscriptions via useQuery without building custom webhook infrastructure or polling mechanisms.

Use cases

From the upstream package documentation.

  • Building job boards or recruitment tools that need fresh LinkedIn company data, job postings from multiple sources, or professional profile information updated automatically
  • E-commerce price monitoring and product research where you need to track Amazon products, competitor pricing, or inventory changes across multiple marketplaces
  • Real estate applications that require up-to-date Zillow listings, property details, or market data synchronized with your app's database
  • Social media analytics dashboards that collect Instagram posts, Twitter trends, or other social platform data for brand monitoring or content analysis
  • Lead generation systems that scrape Google Maps business listings, directory sites, or industry-specific databases to build prospect lists

How it works

From the upstream package documentation.

The component wraps Bright Data's API with a reactive storage layer in Convex. When you call brightDatasets.trigger() from an action, it immediately stores a snapshot with "pending" status, then Bright Data begins the collection job. A webhook handler mounted at /webhooks/brightdata receives the NDJSON results, parses each record, and stores them in component-managed tables.

All queries are reactive through Convex's useQuery system. As webhook batches arrive, the component updates record counts and snapshot status, triggering automatic UI updates. The BrightDatasets class provides methods for synchronous scraping (small jobs), status polling, job cancellation, and record retrieval.

Setup requires mounting the webhook handler in convex/http.ts, instantiating the client with your Bright Data API token, and registering your Convex site URL as the webhook endpoint. The component handles discovery mode for keyword-based searches, custom output field filtering, and delivery logging for debugging failed webhook attempts.

Upstream package FAQ

What datasets can I collect with this component?

The Bright Data Datasets component supports 120+ datasets including LinkedIn profiles, Amazon products, Instagram posts, job listings, Airbnb, Zillow, Google Maps, and more. You need a Bright Data dataset ID (format gd_...) from their Web Scraper API.

How do I get results from dataset collections in real-time?

The component stores snapshot metadata immediately when you trigger a collection, then updates records reactively as the webhook receives results. Subscribe via useQuery to get automatic re-renders when data arrives, with no polling required.

Can I scrape data synchronously without webhooks?

Yes, use brightDatasets.scrape() for small single-URL jobs that complete within 1 minute. For longer jobs, it automatically falls back to the async webhook flow with snapshot polling.

How do I handle webhook delivery in my Convex app?

Mount the webhook handler in convex/http.ts using createWebhookHandler(components.convexBrightDataDatasets). The handler automatically parses NDJSON deliveries, stores records in component tables, and updates snapshot status.

Use with agents and CLI

Give your coding agent the component’s source identity and setup guidance.

agent-prompt.md
Help me integrate Bright Data with Bijection.

Read: https://bijection.com/components/bright-data/SKILL.md

Check SDK compatibility and dependency availability.
Follow this project's execution and verification rules.

Upstream README.md

View repository ↗

Documentation from sholajegede/convex-bright-data-datasets, recorded October 23, 2026. APIs and setup may differ in the Bijection adaptation.

@sholajegede/convex-bright-data-datasets

A Convex component that wraps Bright Data's Datasets API with reactive storage. Trigger async collections for LinkedIn profiles, Amazon products, Instagram posts, job listings, Airbnb, Zillow, Google Maps, and 120+ other datasets — receive results via webhook, and subscribe to structured records in real time via useQuery. No polling, no custom webhook infrastructure, no storage layer to build.

Found a bug? Feature request? File it here.

How it works

Without this component, getting fresh LinkedIn company data, Amazon product data, or job postings into a Convex app means building the whole pipeline yourself: trigger the snapshot, handle the webhook, parse NDJSON, store the records, expose queries. This component does all of that in one install.

You call brightDatasets.trigger() from a Convex action. The component stores the snapshot metadata immediately, mounts a webhook handler that receives the results when Bright Data is done, parses and stores every record in component-owned tables, and updates the snapshot status to ready. Your frontend subscribes via useQuery and updates the moment data lands.

App calls trigger()
        ↓
Bright Data collection job starts
        ↓
Component stores snapshot as "pending"
        ↓
Bright Data POSTs results to webhook handler
        ↓
Component parses NDJSON, stores records, marks snapshot "ready"
        ↓
All useQuery subscribers notified automatically
        ↓
UI updates in real time

Features

  • Async dataset collections — trigger any Bright Data dataset (LinkedIn, Amazon, Instagram, job postings, and 120+ more) from a Convex action
  • Webhook receiver — mount a single HTTP route and the component handles the rest: parsing, storage, status updates
  • Reactive records — subscribe to records via useQuery, live updates as webhook delivers batches
  • Snapshot tracking — every job is stored with status (pending → collecting → digesting → ready), record count, and timing
  • Synchronous scrape — for small single-URL jobs, get results immediately without a webhook
  • Progress polling — poll Bright Data for status updates and sync to Convex reactively
  • Cancel support — cancel a running collection and update snapshot status instantly
  • Delivery logs — every webhook event is logged per snapshot for debugging
  • Discovery mode — trigger keyword, category, or URL-based discovery collections
  • Custom output fields — filter which fields Bright Data returns

Prerequisites

Installation

npm install @sholajegede/convex-bright-data-datasets

Add the component to your convex/convex.config.ts:

import { defineApp } from "convex/server";
import convexBrightDataDatasets from "@sholajegede/convex-bright-data-datasets/convex.config.js";

const app = defineApp();
app.use(convexBrightDataDatasets);

export default app;

Setup

1. Instantiate the client in your Convex functions:

// convex/brightDatasets.ts
import { components } from "./_generated/api.js";
import { BrightDatasets } from "@sholajegede/convex-bright-data-datasets";

export const brightDatasets = new BrightDatasets(components.convexBrightDataDatasets, {
  BRIGHTDATA_API_TOKEN: process.env.BRIGHTDATA_API_TOKEN!,
});

2. Mount the webhook handler in convex/http.ts:

import { httpRouter } from "convex/server";
import { components } from "./_generated/api.js";
import { createWebhookHandler } from "@sholajegede/convex-bright-data-datasets";

const http = httpRouter();

http.route({
  path: "/webhooks/brightdata",
  method: "POST",
  handler: createWebhookHandler(components.convexBrightDataDatasets),
});

export default http;

3. Set your Convex environment variable:

npx convex env set BRIGHTDATA_API_TOKEN your_token_here

Your Convex HTTP actions URL (the webhook endpoint to register in Bright Data) is:

https://<your-deployment>.convex.site/webhooks/brightdata

You can find this by running npx convex dev and looking for VITE_CONVEX_SITE_URL in your .env.local.

Usage

Trigger an async collection

// convex/myFunctions.ts
import { action, query } from "./_generated/server.js";
import { components } from "./_generated/api.js";
import { brightDatasets } from "./brightDatasets.js";
import { v } from "convex/values";

// Trigger a LinkedIn profile collection
export const collectProfiles = action({
  args: { urls: v.array(v.string()) },
  handler: async (ctx, args) => {
    return await brightDatasets.trigger(ctx, {
      datasetId: "gd_l1viktl72bvl7bjuj0", // LinkedIn profiles dataset
      inputs: args.urls.map((url) => ({ url })),
      webhookUrl: process.env.CONVEX_SITE_URL + "/webhooks/brightdata",
    });
    // Returns: { snapshotId: "s_...", status: "pending" }
  },
});

// Reactive query — subscribe to snapshot status from the frontend
export const getSnapshot = query({
  args: { snapshotId: v.string() },
  handler: async (ctx, args) => {
    return await ctx.runQuery(components.convexBrightDataDatasets.lib.getSnapshot, {
      snapshotId: args.snapshotId,
    });
  },
});

// Reactive query — subscribe to records as they arrive
export const getRecords = query({
  args: { snapshotId: v.string() },
  handler: async (ctx, args) => {
    return await ctx.runQuery(components.convexBrightDataDatasets.lib.getRecords, {
      snapshotId: args.snapshotId,
    });
  },
});
// React — subscribes reactively, re-renders when status or records update
const snapshot = useQuery(api.myFunctions.getSnapshot, { snapshotId });
// snapshot.status   — "pending" | "collecting" | "digesting" | "ready" | "failed" | "canceled"
// snapshot.recordCount — number of records received so far

const records = useQuery(api.myFunctions.getRecords, { snapshotId });
// records — array of structured records from Bright Data, parsed from NDJSON

Synchronous scrape (small jobs)

export const scrapeProfile = action({
  args: { url: v.string() },
  handler: async (ctx, args) => {
    return await brightDatasets.scrape(ctx, {
      datasetId: "gd_l1viktl72bvl7bjuj0",
      inputs: [{ url: args.url }],
    });
    // Returns: { records: [...], status: "ready" }
    // If job exceeds 1 min: { records: [], snapshotId: "s_...", status: "running" }
  },
});

Poll for status

export const checkStatus = action({
  args: { snapshotId: v.string() },
  handler: async (ctx, args) => {
    return await brightDatasets.pollStatus(ctx, args.snapshotId);
    // Fetches from Bright Data, updates snapshot in Convex, returns current status
  },
});

Cancel a collection

export const cancelJob = action({
  args: { snapshotId: v.string() },
  handler: async (ctx, args) => {
    return await brightDatasets.cancel(ctx, args.snapshotId);
  },
});

List all snapshots

export const listJobs = query({
  args: {},
  handler: async (ctx) => {
    return await ctx.runQuery(components.convexBrightDataDatasets.lib.listSnapshots, {
      limit: 20,
    });
  },
});

Discovery mode

// Discover Amazon products by keyword
export const discoverProducts = action({
  args: { keywords: v.array(v.string()) },
  handler: async (ctx, args) => {
    return await brightDatasets.trigger(ctx, {
      datasetId: "gd_l7q7dkf244hwjntr0",
      inputs: args.keywords.map((keyword) => ({ keyword })),
      discoveryMode: "discover_new",
      discoverBy: "keyword",
      limitPerInput: 10,
      webhookUrl: process.env.CONVEX_SITE_URL + "/webhooks/brightdata",
    });
  },
});

API

BrightDatasets class

MethodDescription
trigger(ctx, opts)Trigger an async Bright Data dataset collection. Returns { snapshotId, status } immediately.
scrape(ctx, opts)Synchronous scrape for small single-URL jobs. Falls back to snapshot polling if job exceeds 1 minute.
pollStatus(ctx, snapshotId)Poll Bright Data for snapshot status and sync to Convex.
cancel(ctx, snapshotId)Cancel a running collection.
getSnapshot(ctx, snapshotId)Get snapshot metadata. Reactive via useQuery.
listSnapshots(ctx, opts?)List snapshots, optionally filtered by datasetId, status, or limit. Reactive.
getRecords(ctx, snapshotId, limit?)Get stored records for a snapshot. Reactive — updates as webhook delivers data.
getDeliveryLogs(ctx, snapshotId)Get webhook delivery events for debugging. Reactive.

createWebhookHandler(component)

Creates the HTTP action handler for receiving Bright Data webhook deliveries. Mount in convex/http.ts.

trigger options

OptionTypeDescription
datasetIdstringBright Data dataset ID (e.g. gd_l1viktl72bvl7bjuj0)
inputsobject[]Array of input objects (e.g. [{ url: "..." }])
formatstring?Output format: "json" | "ndjson" | "csv" (default: "json")
webhookUrlstring?Webhook URL where Bright Data delivers results
notifyUrlstring?Notification URL called on completion with snapshot_id and status
discoveryModestring?Set to "discover_new" to enable discovery
discoverBystring?Discovery method: "keyword" | "category_url" | "best_sellers_url" | "location"
limitPerInputnumber?Max results per input (discovery mode)
totalLimitnumber?Max total results
customOutputFieldsstring?Pipe-separated fields to return (e.g. "url|name|price")
includeErrorsboolean?Include error records in results (default: true)

Snapshot status lifecycle

pending → collecting → digesting → ready
                                 → failed
                                 → canceled

Reactive queries (call via ctx.runQuery)

FunctionArgsReturns
components.convexBrightDataDatasets.lib.getSnapshot{ snapshotId }Snapshot or null
components.convexBrightDataDatasets.lib.listSnapshots{ datasetId?, status?, limit? }Array of snapshots
components.convexBrightDataDatasets.lib.getRecords{ snapshotId, limit? }Array of records
components.convexBrightDataDatasets.lib.getDeliveryLogs{ snapshotId }Array of delivery events

Example app

See example/ for a working Vite + React demo showing async dataset triggering, live snapshot status tracking, and reactive record display.

Development

npm i
npm run dev

License

Apache-2.0

Keywords