Vision

Start/stop profiles

Introduction

Vision provides the ability to start and stop profiles via API using HTTP-requests. To send some requests you may need X-Token, you can read more about it in the corresponding article.

Work with profiles

Getting the list of running profiles

In Vision it is possible to get information on profiles that are already running.

Request

To get the list of running profiles you need to send the corresponding GET request:

GET
http://127.0.0.1:3030/list

Request example

const url =  "http://127.0.0.1:3030/list"; const options = {  method: "GET",  headers: {    "X-Token": "Your Token",   }, };fetch(url, options)  .then((response) => {    response.json().then((data) => {      console.log(data);    });  })  .catch((error) => {    console.error(error);  });
import requestsurl = 'http://127.0.0.1:3030/list' headers = {    'X-Token': 'Your Token',    'Content-Type': 'application/json'}response = requests.get(url, headers=headers)print(response.json())
<?php$url = "http://127.0.0.1:3030/list";$token = "Your Token"; $headers = array(  'X-Token: '.$token,  'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$data = curl_exec($ch);if (curl_errno($ch)) {    print "Error: " . curl_error($ch);} else {    var_dump($data);    curl_close($ch);}?>
// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() {    let url = "http://127.0.0.1:3030/list";    let token = "Token";     let client = reqwest::Client::new();    let response = client        .get(url)        .header("X-Token", token)        .send()        .await        .expect("Failed to send request")        .json::<serde_json::Value>()        .await        .expect("Failed to parse response");    dbg!(response);}
package mainimport (	"io"	"net/http")func main() {	url := "http://127.0.0.1:3030/list"	token := "Your Token"    	client := http.Client{}	req, err := http.NewRequest("GET", url, nil)	if err != nil {		panic(err)	}	req.Header.Add("X-Token", token)        	resp, err := client.Do(req)	if err != nil {		panic(err)	}	defer resp.Body.Close()	body, _ := io.ReadAll(resp.Body)	println(string(body))}
var url = "http://127.0.0.1:3030/list";var token = "Your Token"; var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);var response = await client.GetAsync(url);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);

Response example

{
"profiles": [
    {
        "folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
        "profile_id": "05296821-1ee5-445c-805f-1523578e898c",
        "port": null
    },
    {
        "folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
        "profile_id": "98bc0cb8-3cae-483f-bb8c-2607cc5c9883",
        "port": null
    },
    {
        "folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
        "profile_id": "9c6ed4a3-20b3-441d-adc6-58b99791f67b",
        "port": null
    }
]
}

Start profile by API

Request

To launch a profile, you need to send a corresponding GET or POST request:

Please note that in the request URL it is necessary to pass the ID of the folder - folderId, where the profile to be launched is located, as well as the ID of the profile itself - profileId.

GET
http://127.0.0.1:3030/start/{folderId}/{profileId}
POST
http://127.0.0.1:3030/start/{folderId}/{profileId}

If you want to pass extra arguments to the browser, you can do it by sending a POST request with the JSON body containing the args field with an array of arguments.

Request headers

Prop

Type

Request body (optional)

Prop

Type

Request example

const url =  "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const options = {  method: "GET",  headers: {    "X-Token": "Your Token",   }, };fetch(url, options)  .then((response) => {    response.json().then((data) => {      console.log(data);    });  })  .catch((error) => {    console.error(error);  });
import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' headers = {    'X-Token': 'Your Token',    'Content-Type': 'application/json'}response = requests.get(url, headers=headers)print(response.json())
<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $headers = array(  'X-Token: '.$token,  'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);$data = curl_exec($ch);if (curl_errno($ch)) {    print "Error: " . curl_error($ch);} else {    var_dump($data);    curl_close($ch);}?>
// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() {    let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";    let token = "Token";     let client = reqwest::Client::new();    let response = client        .get(url)        .header("X-Token", token)        .send()        .await        .expect("Failed to send request")        .json::<serde_json::Value>()        .await        .expect("Failed to parse response");    dbg!(response);}
package mainimport (	"io"	"net/http")func main() {	url := "http://127.0.0.1:3030/start/{folderId}/{profileId}"	token := "Your Token"    	client := http.Client{}	req, err := http.NewRequest("GET", url, nil)	if err != nil {		panic(err)	}	req.Header.Add("X-Token", token)        	resp, err := client.Do(req)	if err != nil {		panic(err)	}	defer resp.Body.Close()	body, _ := io.ReadAll(resp.Body)	println(string(body))}
var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);var response = await client.GetAsync(url);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);

Request example with headless mode

const url =  "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = {  "args": [    "--headless"  ]}const options = {  method: "POST",  headers: {    "X-Token": "Your Token",     "Content-Type": "application/json"  },   body: JSON.stringify(body)};fetch(url, options)  .then((response) => {    response.json().then((data) => {      console.log(data);    });  })  .catch((error) => {    console.error(error);  });
import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = {  "args": [    "--headless"  ]}headers = {    'X-Token': 'Your Token',    'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())
<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{  "args": [    "--headless"  ]}';$headers = array(  'X-Token: '.$token,  'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) {    print "Error: " . curl_error($ch);} else {    var_dump($data);    curl_close($ch);}?>
// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() {    let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";    let token = "Token";     let body = serde_json::json!(        {          "args": [            "--headless"          ]        }	);    let client = reqwest::Client::new();    let response = client        .post(url)        .header("X-Token", token)        .json(&body)        .send()        .await        .expect("Failed to send request")        .json::<serde_json::Value>()        .await        .expect("Failed to parse response");    dbg!(response);}
package mainimport (	"bytes"	"io"	"net/http")func main() {	url := "http://127.0.0.1:3030/start/{folderId}/{profileId}"	token := "Your Token"    body := []byte(`        {          "args": [            "--headless"          ]        }	`)	client := http.Client{}	req, err := http.NewRequest("POST", url, nil)	if err != nil {		panic(err)	}	req.Header.Add("X-Token", token)    req.Header.Add("Content-Type", "application/json")    req.Body = io.NopCloser(bytes.NewReader(body))	resp, err := client.Do(req)	if err != nil {		panic(err)	}	defer resp.Body.Close()	body, _ := io.ReadAll(resp.Body)	println(string(body))}
var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{  "args": [    "--headless"  ]}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);

Example of a request to start a profile with a specific port

In the example below, instead of PORT_NUMBER_HERE you should specify an integer in the range from 1024 to 65535. Thus, the profile will be launched with the port specified in the code, and you can use this port to connect to the browser profile instance.

const url =  "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = {  "args": [    "--remote-debugging-port=PORT_NUMBER_HERE"  ]}const options = {  method: "POST",  headers: {    "X-Token": "Your Token",     "Content-Type": "application/json"  },   body: JSON.stringify(body)};fetch(url, options)  .then((response) => {    response.json().then((data) => {      console.log(data);    });  })  .catch((error) => {    console.error(error);  });
import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = {  "args": [    "--remote-debugging-port=PORT_NUMBER_HERE"  ]}headers = {    'X-Token': 'Your Token',    'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())
<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{  "args": [    "--remote-debugging-port=PORT_NUMBER_HERE"  ]}';$headers = array(  'X-Token: '.$token,  'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) {    print "Error: " . curl_error($ch);} else {    var_dump($data);    curl_close($ch);}?>
// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() {    let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";    let token = "Token";     let body = serde_json::json!(        {          "args": [            "--remote-debugging-port=PORT_NUMBER_HERE"          ]        }	);    let client = reqwest::Client::new();    let response = client        .post(url)        .header("X-Token", token)        .json(&body)        .send()        .await        .expect("Failed to send request")        .json::<serde_json::Value>()        .await        .expect("Failed to parse response");    dbg!(response);}
package mainimport (	"bytes"	"io"	"net/http")func main() {	url := "http://127.0.0.1:3030/start/{folderId}/{profileId}"	token := "Your Token"    body := []byte(`        {          "args": [            "--remote-debugging-port=PORT_NUMBER_HERE"          ]        }	`)	client := http.Client{}	req, err := http.NewRequest("POST", url, nil)	if err != nil {		panic(err)	}	req.Header.Add("X-Token", token)    req.Header.Add("Content-Type", "application/json")    req.Body = io.NopCloser(bytes.NewReader(body))	resp, err := client.Do(req)	if err != nil {		panic(err)	}	defer resp.Body.Close()	body, _ := io.ReadAll(resp.Body)	println(string(body))}
var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{  "args": [    "--remote-debugging-port=PORT_NUMBER_HERE"  ]}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);

Example request to launch a profile with a temporary proxy

If you need to launch a profile with a temporary proxy, you can specify the proxy details in the request body when starting it. Note that this proxy will not be saved. You'll need to provide the following data in the request body:

  • proxy type (http, https, socks5, ssh)
  • proxy host (IP address or domain)
  • port
  • username (if available)
  • password (if available)

IMPORTANT: To launch a profile with a temporary proxy, the args parameter must always be provided.

If there are arguments — include them in the array.

If there are no arguments — pass an empty array (args: []), otherwise the launch will fail.

const url =  "http://127.0.0.1:3030/start/{folderId}/{profileId}"; const body = {  "args": [],  "proxy": {    "type": "socks5",    "address": "1.1.1.1",    "port": 4123,    "username": "vision",    "password": "password"  }}const options = {  method: "POST",  headers: {    "X-Token": "Your Token",     "Content-Type": "application/json"  },   body: JSON.stringify(body)};fetch(url, options)  .then((response) => {    response.json().then((data) => {      console.log(data);    });  })  .catch((error) => {    console.error(error);  });
import requestsurl = 'http://127.0.0.1:3030/start/{folderId}/{profileId}' body = {  "args": [],  "proxy": {    "type": "socks5",    "address": "1.1.1.1",    "port": 4123,    "username": "vision",    "password": "password"  }}headers = {    'X-Token': 'Your Token',    'Content-Type': 'application/json'}response = requests.post(url, headers=headers, json=body)print(response.json())
<?php$url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";$token = "Your Token"; $body = '{  "args": [],  "proxy": {    "type": "socks5",    "address": "1.1.1.1",    "port": 4123,    "username": "vision",    "password": "password"  }}';$headers = array(  'X-Token: '.$token,  'Content-Type: application/json');$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);curl_setopt($ch, CURLOPT_POSTFIELDS, $body);$data = curl_exec($ch);if (curl_errno($ch)) {    print "Error: " . curl_error($ch);} else {    var_dump($data);    curl_close($ch);}?>
// Requires tokio with features = ["macros", "rt-multi-thread"]// Requires reqwest with features = ["json"]// Requires serde_json#[tokio::main]async fn main() {    let url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";    let token = "Token";     let body = serde_json::json!(        {          "args": [],          "proxy": {            "type": "socks5",            "address": "1.1.1.1",            "port": 4123,            "username": "vision",            "password": "password"          }        }	);    let client = reqwest::Client::new();    let response = client        .post(url)        .header("X-Token", token)        .json(&body)        .send()        .await        .expect("Failed to send request")        .json::<serde_json::Value>()        .await        .expect("Failed to parse response");    dbg!(response);}
package mainimport (	"bytes"	"io"	"net/http")func main() {	url := "http://127.0.0.1:3030/start/{folderId}/{profileId}"	token := "Your Token"    body := []byte(`        {          "args": [],          "proxy": {            "type": "socks5",            "address": "1.1.1.1",            "port": 4123,            "username": "vision",            "password": "password"          }        }	`)	client := http.Client{}	req, err := http.NewRequest("POST", url, nil)	if err != nil {		panic(err)	}	req.Header.Add("X-Token", token)    req.Header.Add("Content-Type", "application/json")    req.Body = io.NopCloser(bytes.NewReader(body))	resp, err := client.Do(req)	if err != nil {		panic(err)	}	defer resp.Body.Close()	body, _ := io.ReadAll(resp.Body)	println(string(body))}
var url = "http://127.0.0.1:3030/start/{folderId}/{profileId}";var token = "Your Token"; var body = """{  "args": [],  "proxy": {    "type": "socks5",    "address": "1.1.1.1",    "port": 4123,    "username": "vision",    "password": "password"  }}"""var client = new HttpClient();client.DefaultRequestHeaders.Add("X-Token", token);client.DefaultRequestHeaders.Add("Content-Type", "application/json");var contentBody = new StringContent(body, Encoding.UTF8, "application/json");var response = await client.PostAsync(url, contentBody);var content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);

Please note that the temporary proxy takes priority when launching.

This means that even if the profile has a bound proxy, it will still launch with the temporary proxy.

Response

Response data

Prop

Type

Response example

{
"folder_id": "698d2698-11a5-4768-bfb8-92b904026bfd",
"profile_id": "98bc0cb8-3cae-483f-bb8c-2607cc5c9883",
"port": 19512
}

Stopping profile by API

Request

To stop a profile, you need to send a corresponding GET request:

GET
http://127.0.0.1:3030/stop/{folderId}/{profileId}

Please note that in the request URL it is necessary to pass the ID of the folder - folderId, where the profile to be launched is located, as well as the ID of the profile itself - profileId.

Request example

var requestOptions = {
    method: 'GET',
    redirect: 'follow'
};

fetch("http://127.0.0.1:3030/stop/FOLDER_ID_HERE/PROFILE_ID_HERE", requestOptions)
    .then(response => response.text())
    .then(result => console.log(result))
    .catch(error => console.log('error', error));
import requests

url = "http://127.0.0.1:3030/stop/FOLDER_ID_HERE/PROFILE_ID_HERE"

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

Response

Response example

Stopping profile 98bc0cb8-3cae-483f-bb8c-2607cc5c9883 in folder 698d2698-11a5-4768-bfb8-92b904026bfd

On this page