> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brightdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Synchronous requests

> Send synchronous requests to the Bright Data Scraper API. POST /datasets/v3/scrape returns the scraped data in a single response, with no snapshot polling.

<RequestExample>
  ```bash cURL theme={null}
  curl -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"input":[{"user_name":"zoobarcelona"}],"limit_per_input":null}' \
    "https://api.brightdata.com/datasets/v3/scrape?dataset_id=gd_l1vikfch901nx3by4&notify=false&include_errors=true&type=discover_new&discover_by=user_name"
  ```

  ```python Python (requests) theme={null}
  import requests

  response = requests.post(
      "https://api.brightdata.com/datasets/v3/scrape",
      params={
          "dataset_id": "gd_l1vikfch901nx3by4",
          "notify": "false",
          "include_errors": "true",
          "type": "discover_new",
          "discover_by": "user_name",
      },
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={"input": [{"user_name": "zoobarcelona"}], "limit_per_input": None},
  )

  print(response.status_code, response.json())
  ```

  ```javascript Node.js (Axios) theme={null}
  import axios from "axios";

  const response = await axios.post(
    "https://api.brightdata.com/datasets/v3/scrape",
    { input: [{ user_name: "zoobarcelona" }], limit_per_input: null },
    {
      params: {
        dataset_id: "gd_l1vikfch901nx3by4",
        notify: false,
        include_errors: true,
        type: "discover_new",
        discover_by: "user_name",
      },
      headers: { Authorization: "Bearer YOUR_API_KEY" },
    }
  );

  console.log(response.status, response.data);
  ```
</RequestExample>

## How It Works

This synchronous API endpoint allows users to send a scraping request and receive the results in real-time directly in the response, at the point of request - such as a terminal or application - without the need for external storage or manual downloads. This approach streamlines the data collection process by eliminating additional steps for retrieving results.

Set the output format with the `format` query parameter. If no format is provided, the response is NDJSON, one record per line. Set `format=json` to get a JSON array.

## Request body

Send the inputs as an object with an `input` array:

```json theme={null}
{
  "input": [{"user_name": "zoobarcelona"}],
  "limit_per_input": null
}
```

| Field | Type | Description |
| :- | :- | :- |
| `input` | array of objects, required | The inputs to scrape. The fields depend on the scraper, for example `url` or `user_name` |
| `limit_per_input` | integer or `null` | Maximum records returned per input, or `null` |
| `custom_output_fields` | string | Output fields to keep, separated by `\|`, for example `title\|final_price\|url` |

`limit_per_input` matters for discovery requests, whose result count is open-ended. This request discovers posts in a subreddit and stops at three:

```json theme={null}
{
  "input": [{"url": "https://www.reddit.com/r/learnpython/"}],
  "limit_per_input": 3
}
```

Send it with `type=discover_new&discover_by=subreddit_url` on the query string. Put `limit_per_input` in the body, next to `input`. A `limit_per_input` query parameter also caps the results (verified September 30, 2026), but the body is the recommended place.

A bare JSON array of input objects is also accepted and returns the same records. It cannot carry `limit_per_input` or `custom_output_fields`:

```json theme={null}
[{"url": "https://www.amazon.com/dp/B0FQFB8FMG"}]
```

`POST /datasets/v3/trigger` takes the same object body. On that endpoint the object is also where a `deliver` block goes. See [Asynchronous requests](/api-reference/rest-api/scraper/asynchronous-requests).

## Timeout Limit

Please note that this synchronous request is subject to a 1 minute timeout limit. If the data retrieval process exceeds this limit, the API will return an HTTP 202 response, indicating that the request is still being processed. In such cases, you will receive a snapshot ID to monitor and retrieve the results asynchronously via the Monitor Snapshot and Download Snapshot endpoints. The 202 response carries a `retry-after` header (10 seconds at the time of writing) telling you how long to wait before polling.

Example response on timeout:

```JSON 202 theme={null}
{
  "snapshot_id": "sd_m1a2b3c4d5e6f7g8h",
  "message": "Your request is still in progress and cannot be retrieved in this call. Use the provided Snapshot ID to track progress via the Monitor Snapshot endpoint and download it once ready via the Download Snapshot endpoint."
}
```

## How to handle a 202 response

A `/scrape` request that runs past 1 minute answers HTTP 202 with a `snapshot_id` instead of records, and the job continues. Branch on the status code, then poll [Monitor progress](/api-reference/scrapers/management-apis/monitor-progress) and fetch the records with [Download snapshot](/api-reference/scrapers/delivery-apis/download-snapshot). The polling loop is in [How to scrape in bulk with async requests](/products/scrapers/scrapers-library/async-requests#step-2-monitor-progress).

```python Python theme={null}
import requests

response = requests.post(
    "https://api.brightdata.com/datasets/v3/scrape",
    params={"dataset_id": "gd_l7q7dkf244hwjntr0", "format": "json"},
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"input": [{"url": "https://www.amazon.com/dp/B0FQFB8FMG"}]},
)

if response.status_code == 200:
    print(f"Got {len(response.json())} results")
elif response.status_code == 202:
    print(f"Job running. Snapshot ID: {response.json()['snapshot_id']}")
else:
    response.raise_for_status()
```

A 200 carries the records; a 202 carries the snapshot ID. Any other status is an error, listed under Response below. The fix for each error is on [Scraper API error codes](/products/scrapers/error-codes).

## Custom inputs

You can add custom fields to the input schema. Whatever you send in those fields is returned in the results for each record. Use this to:

* Keep a unified output structure across different scrapers and datasets.
* Pass an `id`, `row_index` or any internal key so you can match results back to your original input rows.


## OpenAPI

````yaml api-reference/dca-api POST /datasets/v3/scrape
openapi: 3.1.0
info:
  title: Brightdata API
  description: API for interaction with datasets marketplace
  version: 1.0.0
servers:
  - url: https://api.brightdata.com
security:
  - bearerAuth: []
paths:
  /datasets/v3/scrape:
    post:
      summary: Scrape data and return it directly in the response.
      description: >-
        This endpoint allows users to fetch data efficiently and ensures
        seamless integration with their applications or workflows.
      parameters:
        - name: dataset_id
          in: query
          description: Dataset ID for which data collection is triggered.
          required: true
          schema:
            type: string
        - name: custom_output_fields
          description: >-
            List of output columns, separated by `|` (e.g.,
            `url|about.updated_on`). Filters the response to include only the
            specified fields.
          in: query
          required: false
          schema:
            type: string
            example: url|about.updated_on
        - name: include_errors
          in: query
          schema:
            type: boolean
          description: Include errors report with the results.
        - name: format
          in: query
          description: >-
            Format of the response: `ndjson` (default, one record per line),
            `json` (a JSON array) or `csv`. See [output
            formats](/products/scrapers/scrapers-library/data-delivery#which-output-formats-can-i-use).
          schema:
            type: string
            enum:
              - ndjson
              - json
              - csv
            default: ndjson
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: '#/components/schemas/ScrapeRequestWithFields'
                  title: Inputs with output filter
                - $ref: '#/components/schemas/ScrapeInput'
                  title: Only inputs
      responses:
        '200':
          description: >-
            OK


            A JSON array of records. An empty array means the inputs produced no
            records; check the input URLs.
          content:
            text/plain:
              schema:
                type: string
                example: OK
        '202':
          description: >-
            Request is still in progress, snapshot will be available later.


            The job ran past the 1-minute limit and continues asynchronously.
            Poll `GET /datasets/v3/progress/{snapshot_id}`, then download the
            snapshot. A `retry-after` header says how long to wait.
          headers:
            retry-after:
              description: Time in seconds before retrying the request.
              schema:
                type: integer
                example: 10
          content:
            application/json:
              schema:
                type: object
                properties:
                  snapshot_id:
                    type: string
                    description: >-
                      ID of the job that continues asynchronously. Pass it to
                      GET /datasets/v3/progress/{snapshot_id} and GET
                      /datasets/v3/snapshot/{snapshot_id}.
                  message:
                    type: string
              example:
                snapshot_id: sd_m1a2b3c4d5e6f7g8h
                message: >-
                  Your request is still in progress and cannot be retrieved in
                  this call. Use the provided Snapshot ID to track progress via
                  the Monitor Snapshot endpoint and download it once ready via
                  the Download Snapshot endpoint.
        '400':
          description: >-
            Messages:

            - `{"error": "Invalid input provided", "code": "validation_error",
            "errors": [[FIELD, REASON]]}`: An input field failed validation;
            `errors` names the field and the reason, for example `["url", "This
            field must be a valid url"]`. Fix the input value and resend

            - `{"error": "Parser cannot parse input: ...", "code":
            "parse_error"}`: The request body is not valid JSON. Fix the JSON
            and resend

            - No data to trigger: The request holds no inputs
          content:
            application/json:
              schema:
                type: object
                description: Error body
              example:
                error: Invalid input provided
                code: validation_error
                type: validation
                line: '{"url":"not-a-url","asin":"","zipcode":"","language":""}'
                index: 1
                errors:
                  - - url
                    - This field must be a valid url
        '401':
          description: >-
            Messages (plain text):

            - `Credentials are missing`: No `Authorization` header was sent

            - `Auth method is not supported`: The `Authorization` header is not
            in a supported format

            - `Invalid credentials`: The API key is wrong


            Send `Authorization: Bearer YOUR_API_KEY` with a valid API key
          content:
            text/plain:
              schema:
                type: string
              example: Invalid credentials
        '404':
          description: >-
            Messages (plain text):

            - `Collector not found`: The request has no `dataset_id` query
            parameter

            - `dataset does not exist`: No scraper matches the `dataset_id`
          content:
            text/plain:
              schema:
                type: string
              example: dataset does not exist
        '429':
          description: >-
            Messages:

            - Too Many Requests: Same limits as the trigger endpoint; see [How
            to handle 429
            errors](/products/scrapers/scrapers-library/async-requests#getting-a-429-too-many-requests-error)
        '500':
          description: |-
            Messages:
            - Internal server error
components:
  schemas:
    ScrapeRequestWithFields:
      type: object
      properties:
        input:
          type: array
          items:
            type: object
            additionalProperties: {}
          description: >-
            Array of input objects. The fields depend on the scraper, for
            example `url` or `user_name`.
        custom_output_fields:
          type: string
          description: >-
            List of output columns, separated by `|` (e.g.,
            `url|about.updated_on`). Filters the response to include only the
            specified fields.
          example: url|about.updated_on
        limit_per_input:
          type:
            - integer
            - 'null'
          minimum: 1
          description: >-
            Maximum number of records to return per input, or `null`. Applies to
            discovery requests, whose result count is otherwise open-ended.
          example: null
      required:
        - input
      example:
        input:
          - url: www.linkedin.com/in/bulentakar
        custom_output_fields: url|about.updated_on
    ScrapeInput:
      type: array
      description: >-
        A bare JSON array of input objects. Also accepted; it cannot carry
        `limit_per_input`.
      example:
        - url: https://www.amazon.com/dp/B0FQFB8FMG
      items:
        type: object
        additionalProperties: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Use your Bright Data API Key as a Bearer token in the Authorization
        header.


        **How to authenticate:**

        1. Obtain your API Key from the Bright Data account settings at
        https://brightdata.com/cp/setting/users

        2. Include the API Key in the Authorization header of your requests

        3. Format: `Authorization: Bearer YOUR_API_KEY`


        **Example:**

        ```

        Authorization: Bearer YOUR_API_KEY

        ```


        Learn how to get your Bright Data API key:
        https://docs.brightdata.com/api-reference/authentication
      bearerFormat: API Key

````