# Universal Source

Scrape other websites (Home Depot, Idealo, Zillow, [**Yandex**](https://developers.oxylabs.io/guides-for-scraper-apis/forming-urls#yandex), [**Baidu**](https://developers.oxylabs.io/guides-for-scraper-apis/forming-urls#baidu), etc.) with our `universal` source. It accepts URLs along with [**additional parameters**](#additional).

## Request samples

In this example, the API will retrieve an e-commerce product page.

{% tabs %}
{% tab title="cURL" %}

```shell
curl 'https://realtime.oxylabs.io/v1/queries' \
--user 'USERNAME:PASSWORD' \
-H 'Content-Type: application/json' \
-d '{
        "source": "universal",
        "url": "https://sandbox.oxylabs.io/products/1"
    }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
from pprint import pprint


# Structure payload.
payload = {
    'source': 'universal',
    'url': 'https://sandbox.oxylabs.io/products/1',
}

# Get response.
response = requests.request(
    'POST',
    'https://realtime.oxylabs.io/v1/queries',
    auth=('USERNAME', 'PASSWORD'),
    json=payload,
)

# Instead of response with job status and results url, this will return the
# JSON response with the result.
pprint(response.json())
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const https = require("https");

const username = "USERNAME";
const password = "PASSWORD";
const body = {
    source: "universal",
    url: "https://sandbox.oxylabs.io/products/1",
};

const options = {
    hostname: "realtime.oxylabs.io",
    path: "/v1/queries",
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        Authorization:
            "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
    },
};

const request = https.request(options, (response) => {
    let data = "";

    response.on("data", (chunk) => {
        data += chunk;
    });

    response.on("end", () => {
        const responseData = JSON.parse(data);
        console.log(JSON.stringify(responseData, null, 2));
    });
});

request.on("error", (error) => {
    console.error("Error:", error);
});

request.write(JSON.stringify(body));
request.end();
```

{% endtab %}

{% tab title="HTTP" %}

```http
# The whole string you submit has to be URL-encoded.

https://realtime.oxylabs.io/v1/queries?source=universal&url=https%3A%2F%2Fsandbox.oxylabs.io%2Fproducts%2F1&access_token=12345abcde
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$params = array(
    'source' => 'universal',
    'url' => 'https://sandbox.oxylabs.io/products/1',
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://realtime.oxylabs.io/v1/queries");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "USERNAME" . ":" . "PASSWORD");

$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
echo $result;

if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
```

{% endtab %}

{% tab title="Golang" %}

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	const Username = "USERNAME"
	const Password = "PASSWORD"

	payload := map[string]interface{}{
		"source": "universal",
		"url":    "https://sandbox.oxylabs.io/products/1",
	}

	jsonValue, _ := json.Marshal(payload)

	client := &http.Client{}
	request, _ := http.NewRequest("POST",
		"https://realtime.oxylabs.io/v1/queries",
		bytes.NewBuffer(jsonValue),
	)

	request.SetBasicAuth(Username, Password)
	response, _ := client.Do(request)

	responseText, _ := ioutil.ReadAll(response.Body)
	fmt.Println(string(responseText))
}

```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace OxyApi
{
    class Program
    {
        static async Task Main()
        {
            const string Username = "USERNAME";
            const string Password = "PASSWORD";

            var parameters = new {
                source = "universal",
                url = "https://sandbox.oxylabs.io/products/1"
            };

            var client = new HttpClient();

            Uri baseUri = new Uri("https://realtime.oxylabs.io");
            client.BaseAddress = baseUri;

            var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/v1/queries");
            requestMessage.Content = JsonContent.Create(parameters);

            var authenticationString = $"{Username}:{Password}";
            var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(authenticationString));
            requestMessage.Headers.Add("Authorization", "Basic " + base64EncodedAuthenticationString);

            var response = await client.SendAsync(requestMessage);
            var contents = await response.Content.ReadAsStringAsync();

            Console.WriteLine(contents);
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
package org.example;

import okhttp3.*;
import org.json.JSONObject;
import java.util.concurrent.TimeUnit;

public class Main implements Runnable {
    private static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String USERNAME = "USERNAME";
    public static final String PASSWORD = "PASSWORD";

    public void run() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("source", "universal");
        jsonObject.put("url", "https://sandbox.oxylabs.io/products/1");

        Authenticator authenticator = (route, response) -> {
            String credential = Credentials.basic(USERNAME, PASSWORD);
            return response
                    .request()
                    .newBuilder()
                    .header(AUTHORIZATION_HEADER, credential)
                    .build();
        };

        var client = new OkHttpClient.Builder()
                .authenticator(authenticator)
                .readTimeout(180, TimeUnit.SECONDS)
                .build();

        var mediaType = MediaType.parse("application/json; charset=utf-8");
        var body = RequestBody.create(jsonObject.toString(), mediaType);
        var request = new Request.Builder()
                .url("https://realtime.oxylabs.io/v1/queries")
                .post(body)
                .build();

        try (var response = client.newCall(request).execute()) {
            if (response.body() != null) {
                try (var responseBody = response.body()) {
                    System.out.println(responseBody.string());
                }
            }
        } catch (Exception exception) {
            System.out.println("Error: " + exception.getMessage());
        }

        System.exit(0);
    }

    public static void main(String[] args) {
        new Thread(new Main()).start();
    }
}
```

{% endtab %}

{% tab title="JSON" %}

```json
{
    "source": "universal", 
    "url": "https://sandbox.oxylabs.io/products/1"
}
```

{% endtab %}
{% endtabs %}

<details>

<summary>Output example</summary>

```json
{
    "results": [
        {
            "content": "<!DOCTYPE html><html lang=\"en\">
            CONTENT
            </html>",
            "created_at": "2024-07-01 11:35:14",
            "updated_at": "2024-07-01 11:35:15",
            "page": 1,
            "url": "https://sandbox.oxylabs.io/products/1",
            "job_id": "7213505428280329217",
            "status_code": 200
        }
    ]
}
```

</details>

We use synchronous [**Realtime**](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/integration-methods/realtime) integration method in our examples. If you would like to use [**Proxy Endpoint**](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/integration-methods/proxy-endpoint) or asynchronous [**Push-Pull**](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/integration-methods/push-pull) integration, refer to the [**integration methods**](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/integration-methods) section.

## Request parameter values

### Generic

<table><thead><tr><th width="205">Parameter</th><th width="289.3333333333333">Description</th><th>Default Value</th></tr></thead><tbody><tr><td><mark style="background-color:green;"><strong>source</strong></mark></td><td>Sets the scraper.</td><td><code>universal</code></td></tr><tr><td><mark style="background-color:green;"><strong>url</strong></mark></td><td>Direct URL (link) to any page.</td><td>-</td></tr><tr><td><code>callback_url</code></td><td>URL to your callback endpoint. <a href="../../integration-methods/push-pull#callback"><strong>More info</strong></a>.</td><td>-</td></tr></tbody></table>

&#x20;    \- mandatory parameter

### Additional

These are the parameters of our [**features**](https://developers.oxylabs.io/scraping-solutions/web-scraper-api/features).

<table><thead><tr><th width="253">Parameter</th><th width="338.92746113989637">Description</th><th>Default Value</th></tr></thead><tbody><tr><td><code>geo_location</code></td><td>Sets the proxy's geo location to retrieve data. Find supported locations <a href="https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FiwDdoZGfMbUe5cRL2417%2Fuploads%2FxoQb19qSyodB2D4no0DZ%2FList%20of%20supported%20geo_location%20values_sapi.json?alt=media&#x26;token=d2e2df7b-10ba-4399-a547-0c4a99e62293"><strong>here</strong></a>.</td><td>-</td></tr><tr><td><code>render</code></td><td>Enables JavaScript rendering when set to <code>html</code>. <a href="../features/js-rendering-and-browser-control/javascript-rendering"><strong>More info</strong></a><strong>.</strong> NOTE: If you are observing low success rates or retrieve empty content, please try adding this parameter.</td><td>-</td></tr><tr><td><code>browser_instructions</code></td><td>Define your own browser instructions that are executed when rendering JavaScript. <a href="../features/js-rendering-and-browser-control/browser-instructions"><strong>More info</strong></a>.</td><td>-</td></tr><tr><td><code>parse</code></td><td>Returns parsed data when set to <code>true</code>, as long as a dedicated parser exists for the submitted URL's page type.</td><td><code>false</code></td></tr><tr><td><code>parsing_instructions</code></td><td>Define your own parsing and data transformation logic that will be executed on an HTML scraping result. Read more: <a href="../features/custom-parser/writing-instructions-manually/parsing-instruction-examples"><strong>Parsing instructions examples</strong></a><strong>.</strong></td><td>-</td></tr><tr><td><code>context</code>:<br><code>headers</code></td><td>Pass your own headers. Learn more<a href="../features/http-context-and-job-management/headers-cookies-method"> <strong>here</strong></a>.</td><td>-</td></tr><tr><td><code>context</code>:<br><code>cookies</code></td><td>Pass your own cookies. Learn more <a href="../../features/http-context-and-job-management/headers-cookies-method#custom-cookies"><strong>here</strong></a>.</td><td>-</td></tr><tr><td><code>context</code>:<br><code>session_id</code></td><td>If you want to use the same proxy with multiple requests, you can do so by using this parameter. Just set your session to any string you like, and we will assign a proxy to this ID, and keep it for up to 10 minutes. After that, if you make another request with the same session ID, a new proxy will be assigned to that particular session ID.</td><td>-</td></tr><tr><td><code>context</code>:<br><code>http_method</code></td><td>Set it to <code>post</code> if you would like to make a <code>POST</code> request to your target URL via E-commerce Scraper API. Learn more <a href="../../features/http-context-and-job-management/headers-cookies-method#http-method"><strong>here</strong></a>.</td><td><code>get</code></td></tr><tr><td><code>user_agent_type</code></td><td>Device type and browser. The full list can be found <a href="../features/http-context-and-job-management/user-agent-type"><strong>here</strong>.</a></td><td><code>desktop</code></td></tr><tr><td><code>context</code>:<br><code>content</code></td><td>Base64-encoded <code>POST</code> request body. It is only useful if <code>http_method</code> is set to <code>post</code>.</td><td>-</td></tr><tr><td><code>content_encoding</code></td><td>Add this parameter if you are downloading images. Learn more <a href="../features/result-processing-and-storage/output-types/download-images"><strong>here</strong></a>.</td><td><code>base64</code></td></tr><tr><td><code>context</code>:<br><code>follow_redirects</code></td><td>Set to <code>true</code> to enable scraper to follow redirects. By default, redirects are followed up to a limit of 10 links, treating the entire chain as one scraping job.</td><td><code>true</code></td></tr><tr><td><code>context</code>:<br><code>successful_status_codes</code></td><td>Define a custom HTTP response code (or a few of them), upon which we should consider the scrape successful and return the content to you. May be useful if you want us to return the 503 error page or in some other non-standard cases.</td><td>-</td></tr></tbody></table>

**All parameters**

In this example, all available parameters are included (though not always necessary or compatible within the same request), to give you an idea on how to format your requests.

{% code fullWidth="false" %}

```json
{
    "source": "universal", 
    "url": "https://example.com", 
    "user_agent_type": "desktop",
    "geo_location": "United States",
    "parse": true,
    "context": [
        {
            "key": "headers", 
            "value": {
                "Content-Type": "application/octet-stream", 
                "Custom-Header-Name": "custom header content"
            }
        }, 
        {
            "key": "cookies", 
            "value": [
                {
                    "key": "NID", 
                    "value": "1234567890"
                },
                {
                    "key": "1P JAR",
                    "value": "0987654321"
                }]
        },
        {
            "key": "follow_redirects",
            "value": true
        },
        {
            "key": "http_method", "value": "get"
        },
        {
            "key": "content",
            "value": "YmFzZTY0RW5jb2RlZFBPU1RCb2R5"
        },
        {
            "key": "successful_status_codes",
            "value": [808, 909]
        }]
}
```

{% endcode %}
