Profiles
配置文件列表
http://127.0.0.1:40325/profiles返回永久配置文件(临时文件隐藏),按从新到旧排序, 已置顶的排在最前。每条记录附带当前运行状态。
来自 Settings → Automation API 的永久 JWT。
200配置文件列表。application/json
启动器中配置文件的元数据(创建时返回)。
ISO-8601 或 null。
图标强调色,格式为 #rrggbb;null 表示根据名称自动生成颜色,这是浏览器在未选择颜色时的默认行为。
启动时加载的扩展库 ID。
cdpobject · CdpInfo· nullableoptional正在运行的配置文件的 CDP 端点。
Show propertiesHide properties
正在运行的配置文件的 CDP 端点。
Chrome 选择的 remote-debugging 端口。
REST 基础地址(/json、/json/version)。
Puppeteer/Playwright connect 使用的浏览器级 WS 端点。
401缺失或无效的 Bearer 令牌。
/profilesGET /profiles HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/profiles' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/profiles")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/profiles");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"proxy_id": "text",
"last_launched_at": "text",
"created_at": "text",
"pinned": true,
"folder": "text",
"color": "text",
"extensions": [
"text"
],
"running": true,
"pid": 1,
"cdp": {
"port": 1,
"http_url": "http://127.0.0.1:53217",
"web_socket_debugger_url": "ws://127.0.0.1:53217/devtools/browser/ab12-..."
}
}
]创建配置文件
http://127.0.0.1:40325/profiles将客户端传入的 fingerprint 对象原样保存为配置文件
(不进行重新随机化; 唯一化已在 /fingerprint/new 完成)。
使用 folder 将配置文件放入文件夹;通过存储中的 proxy_id
或内联的 proxy(字符串,不保存到代理存储)绑定代理。
来自 Settings → Automation API 的永久 JWT。
绑定存储中的代理(按 id)。
以字符串方式绑定代理(host:port:user:pass 或
scheme://user:pass@host:port)。对于永久配置文件,代理
会被添加到存储(按端点去重)并完成全量测试(UDP + 地理位置),
然后按 id 绑定; 显示在代理列表中,QUIC/WebRTC 结果被缓存。
对于临时配置文件,代理以内联方式附加(不保存)。
若已指定 proxy_id 则忽略。
文件夹标签(对于 /folders/{folder}/profiles 被忽略; 路径优先)。
配置文件窗口图标和地址栏名称标签的强调色。省略时,图标颜色根据名称生成,标签保留浏览器工具栏的颜色。
扩展库 ID (GET /extensions),在启动时加载。库不保存的 id 是 400,而不是在没有它的情况下静默启动的配置文件。
声称的显示刷新率,写入screen.refresh_rate。没有 Web API 报告它;页面通过计时 requestAnimationFrame 来衡量它,这就是为什么将其排除在外并不是中立的;缺席意味着 60,这是大多数机器报告的值,而不是主机自己的屏幕所做的任何内容。帧只能减慢,因此有效速率是主机面板在此或低于此的最接近的整个划分。
fingerprintobject · Fingerprintrequired原样保存。从 /fingerprint/new 获取后按需编辑。
Show propertiesHide properties
原样保存。从 /fingerprint/new 获取后按需编辑。
0 = 仅覆盖模式(典型情况)。
navigatorobjectoptionalShow propertiesHide properties
81632screenobjectoptionalShow propertiesHide properties
srgbp3rec2020所声明的显示刷新频率。缺席意味着 60。请参阅创建/编辑请求上的刷新率字段。
client_hintsobjectoptionalSec-CH-UA 系列(在 browser.vision 中称为 hints)。
Show propertiesHide properties
Sec-CH-UA 系列(在 browser.vision 中称为 hints)。
webglobjectoptionalShow propertiesHide properties
WebRTC 处理模式。
autotcp_onlyblocknoiseobject · NoisePrefsoptional各向量的反指纹噪音配置。每个块:{enabled, seed}
(+ 特定参数)。enabled:false = 直接透传。
Show propertiesHide properties
各向量的反指纹噪音配置。每个块:{enabled, seed}
(+ 特定参数)。enabled:false = 直接透传。
canvasobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
webglobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
audioobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
client_rectsobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
sensorsobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
fontsobject · NoiseBlockoptionalenabled:true 为每个配置文件隐藏少量确定性的
非关键字体子集(其余真实主机字体直接透传)。
Show propertiesHide properties
enabled:true 为每个配置文件隐藏少量确定性的
非关键字体子集(其余真实主机字体直接透传)。
每个配置文件的熵值;0 = 自动计算。
networkobjectoptionalShow propertiesHide properties
局域网端口扫描防护(ports_protection)。
IANA 名称或 "auto"; 将在启动时通过绑定代理解析。
200已创建配置文件的元数据。application/json
启动器中配置文件的元数据(创建时返回)。
ISO-8601 或 null。
图标强调色,格式为 #rrggbb;null 表示根据名称自动生成颜色,这是浏览器在未选择颜色时的默认行为。
启动时加载的扩展库 ID。
400缺少 `fingerprint` 或其不是对象,或代理字符串无法解析。application/json
401缺失或无效的 Bearer 令牌。
/profilesPOST /profiles HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}curl -X POST 'http://127.0.0.1:40325/profiles' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"text","notes":"text","proxy_id":"text","proxy":"socks5://user:[email protected]:1080","folder":"text","color":"#2FCB80","extensions":["text"],"refresh_rate":60,"fingerprint":{"name":"text","notes":"text","seed":1,"navigator":{"user_agent":"text","platform":"Win32","hardware_concurrency":12,"device_memory":16,"language":"text","do_not_track":true},"screen":{"width":1,"height":1,"avail_width":1,"avail_height":1,"color_depth":24,"device_pixel_ratio":2,"color_gamut":"","refresh_rate":60},"client_hints":{"platform":"text","platform_version":"text","architecture":"x86","bitness":"64","mobile":true},"webgl":{"unmasked_vendor":"text","unmasked_renderer":"text"},"webgpu":{},"webrtc":"auto","noise":{"canvas":{"enabled":true,"seed":1},"webgl":{"enabled":true,"seed":1,"intensity":1},"audio":{"enabled":true,"seed":1,"intensity":1},"client_rects":{"enabled":true,"seed":1,"max_offset":1},"sensors":{"enabled":true,"seed":1},"fonts":{"enabled":true,"seed":1}},"network":{"blocked_ports":[1]},"timezone":"text"}}'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text",
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": True,
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60,
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": True,
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text",
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": True,
"seed": 1,
},
"webgl": {
"enabled": True,
"seed": 1,
"intensity": 1,
},
"audio": {
"enabled": True,
"seed": 1,
"intensity": 1,
},
"client_rects": {
"enabled": True,
"seed": 1,
"max_offset": 1,
},
"sensors": {
"enabled": True,
"seed": 1,
},
"fonts": {
"enabled": True,
"seed": 1,
},
},
"network": {
"blocked_ports": [
1,
],
},
"timezone": "text",
},
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles";
const payload = {
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles"
body := bytes.NewBufferString(`{
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/profiles")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/profiles");
request.Content = new StringContent("""
{
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"name": "text",
"notes": "text",
"proxy_id": "text",
"proxy": "socks5://user:[email protected]:1080",
"folder": "text",
"color": "#2FCB80",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"notes": "text",
"proxy_id": "text",
"last_launched_at": "text",
"created_at": "text",
"pinned": true,
"folder": "text",
"color": "text",
"extensions": [
"text"
]
}{
"error": "text"
}创建临时配置文件
http://127.0.0.1:40325/profiles/temporary从库中随机(或指定)指纹创建配置文件,唯一化方式与
/fingerprint/new 相同,原样保存,带 temporary 标志:
在列表和界面中隐藏,浏览器关闭后自动删除(含数据文件夹,
或在崩溃后下次启动时删除)。
配合 POST /profiles/{id}/start 使用。
来自 Settings → Automation API 的永久 JWT。
配置文件所基于的库条目;未提供时,在 platform 下随机选取。
若未指定 fingerprint_id 则用于随机选取指纹;两者均未提供时使用主机 OS。
WindowsmacOSLinux内联代理字符串(不保存到存储中)。
声称的显示刷新率,写入screen.refresh_rate。没有 Web API 报告它;页面通过计时 requestAnimationFrame 来衡量它,这就是为什么将其排除在外并不是中立的;缺席意味着 60,这是大多数机器报告的值,而不是主机自己的屏幕所做的任何内容。帧只能减慢,因此有效速率是主机面板在此或低于此的最接近的整个划分。
noiseobjectoptional按向量设置指纹噪声。请求中省略的向量保留默认值(关闭)。
同一个请求可以组合两种格式:
简写:`{"canvas": true, "webgl": true}`。这样启用 `webgl` 或 `client_rects` 时,也会使用界面中的默认强度;
完整对象:{"canvas": {"enabled": true, "seed": 42}},格式与 GET /profiles/{id} 返回的对象相同。
字段会与现有向量设置合并,而不是替换整个向量。例如 {"webgl": {"intensity": 0.001}} 不会修改 enabled。seed 为 0 或未提供时,系统会根据配置文件 ID 生成稳定值,避免两个临时配置文件使用相同的指纹。
Show propertiesHide properties
按向量设置指纹噪声。请求中省略的向量保留默认值(关闭)。
同一个请求可以组合两种格式:
简写:`{"canvas": true, "webgl": true}`。这样启用 `webgl` 或 `client_rects` 时,也会使用界面中的默认强度;
完整对象:{"canvas": {"enabled": true, "seed": 42}},格式与 GET /profiles/{id} 返回的对象相同。
字段会与现有向量设置合并,而不是替换整个向量。例如 {"webgl": {"intensity": 0.001}} 不会修改 enabled。seed 为 0 或未提供时,系统会根据配置文件 ID 生成稳定值,避免两个临时配置文件使用相同的指纹。
200已创建的临时配置文件。application/json
生成该配置文件所基于的库条目。
是否附加了内联代理。
400无法解析的代理字符串,或未知的噪声向量。application/json
401缺失或无效的 Bearer 令牌。
404未找到匹配指纹 / 库为空。application/json
/profiles/temporaryPOST /profiles/temporary HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
}curl -X POST 'http://127.0.0.1:40325/profiles/temporary' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"fingerprint_id":"text","platform":"Windows","proxy":"text","name":"text","folder":"text","refresh_rate":60,"noise":{"canvas":true,"webgl":{"enabled":true,"intensity":0.0005},"fonts":true}}'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/temporary"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": True,
"webgl": {
"enabled": True,
"intensity": 0.0005,
},
"fonts": True,
},
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/temporary";
const payload = {
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/temporary"
body := bytes.NewBufferString(`{
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/profiles/temporary")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/profiles/temporary");
request.Content = new StringContent("""
{
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"fingerprint_id": "text",
"platform": "Windows",
"proxy": "text",
"name": "text",
"folder": "text",
"refresh_rate": 60,
"noise": {
"canvas": true,
"webgl": {
"enabled": true,
"intensity": 0.0005
},
"fonts": true
}
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/temporary");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "text",
"fingerprint_id": "text",
"temporary": true,
"proxy_inline": true
}{
"error": "text"
}{
"error": "text"
}获取配置文件
http://127.0.0.1:40325/profiles/{id}返回完整的已保存配置文件:_meta 包装层加上
展开的 FingerprintConfig。若配置文件正在运行;
附带 running 和 cdp。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
200已保存的配置文件。application/json
磁盘上的完整配置文件:_meta 包装层加上展开的
FingerprintConfig(所有 Fingerprint 字段位于顶层)。
running/cdp 仅在配置文件运行时存在。
_metaobjectoptionalShow propertiesHide properties
inline_proxyobject · ProxyEntry· nullableoptional完整的代理条目(嵌入在 _meta.inline_proxy 中)。
Show propertiesHide properties
完整的代理条目(嵌入在 _meta.inline_proxy 中)。
socks5httphttps每次写入都会递增。桌面编辑器会回传打开配置文件时的版本号;如果配置文件已通过此 API 修改,桌面保存会被拒绝,以免覆盖修改。API 修改不会被拒绝,而是读取并一次性写回配置文件。
cdpobject · CdpInfo· nullableoptional正在运行的配置文件的 CDP 端点。
Show propertiesHide properties
正在运行的配置文件的 CDP 端点。
Chrome 选择的 remote-debugging 端口。
REST 基础地址(/json、/json/version)。
Puppeteer/Playwright connect 使用的浏览器级 WS 端点。
401缺失或无效的 Bearer 令牌。
404未找到配置文件。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000GET /profiles/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"_meta": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"proxy_id": "text",
"inline_proxy": {
"id": "text",
"name": "text",
"kind": "socks5",
"host": "text",
"port": 1,
"username": "text",
"password": "text",
"country": "text",
"notes": "text"
},
"last_launched_at": "text",
"created_at": "text",
"pinned": true,
"folder": "text",
"temporary": true,
"rev": 1
},
"running": true,
"cdp": {
"port": 1,
"http_url": "http://127.0.0.1:53217",
"web_socket_debugger_url": "ws://127.0.0.1:53217/devtools/browser/ab12-..."
}
}{
"error": "text"
}删除配置文件
http://127.0.0.1:40325/profiles/{id}将配置文件移入回收站,可在 7 天内恢复,过期后自动清理。归档内容包括账户数据、cookies、登录信息、网页数据、偏好设置、Local Storage 和 IndexedDB,不包括缓存,因此归档仅占用户数据目录的一部分。创建归档后,原始配置和用户数据目录会被删除。
临时配置文件在浏览器关闭时由进程跟踪器删除,不会进入回收站。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
200配置文件已移至回收站。application/json
可在 7 天内从回收站恢复。
401缺失或无效的 Bearer 令牌。
500删除时出错。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000DELETE /profiles/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X DELETE 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.delete(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000";
const response = await fetch(url, {
method: "DELETE",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.delete("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Delete, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"deleted": true,
"id": "123e4567-e89b-12d3-a456-426614174000",
"trashed": true
}{
"error": "text"
}编辑配置文件
http://127.0.0.1:40325/profiles/{id}仅更新传入的字段。若传入 fingerprint; 它将原样替换
已保存的指纹(不重新随机化)。
folder: "" 将配置文件移出文件夹;proxy_id: "" 解绑代理;
代理 proxy 字符串保存(去重)+ 完整测试,然后绑定。
返回更新后的配置文件。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
""将配置文件移出文件夹(移至"全部")。
""解绑代理。
代理字符串; 保存(去重)+ 全量测试,然后绑定。
#rrggbb; “”回到源自名称的颜色。
替换整个列表; [] 不加载任何内容。
声明的显示刷新率,在 fingerprint 之后应用并写入 screen.refresh_rate。没有 Web API 报告它;页面通过计时 requestAnimationFrame 来衡量它,这就是为什么将其排除在外并不是中立的;缺席意味着 60,这是大多数机器报告的值,而不是主机自己的屏幕所做的任何内容。帧只能减慢,因此有效速率是主机面板在此或低于此的最接近的整个划分。
fingerprintobject · Fingerprintoptional若提供,则原样替换已保存的指纹。
Show propertiesHide properties
若提供,则原样替换已保存的指纹。
0 = 仅覆盖模式(典型情况)。
navigatorobjectoptionalShow propertiesHide properties
81632screenobjectoptionalShow propertiesHide properties
srgbp3rec2020所声明的显示刷新频率。缺席意味着 60。请参阅创建/编辑请求上的刷新率字段。
client_hintsobjectoptionalSec-CH-UA 系列(在 browser.vision 中称为 hints)。
Show propertiesHide properties
Sec-CH-UA 系列(在 browser.vision 中称为 hints)。
webglobjectoptionalShow propertiesHide properties
WebRTC 处理模式。
autotcp_onlyblocknoiseobject · NoisePrefsoptional各向量的反指纹噪音配置。每个块:{enabled, seed}
(+ 特定参数)。enabled:false = 直接透传。
Show propertiesHide properties
各向量的反指纹噪音配置。每个块:{enabled, seed}
(+ 特定参数)。enabled:false = 直接透传。
canvasobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
webglobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
audioobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
client_rectsobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
sensorsobject · NoiseBlockoptionalShow propertiesHide properties
每个配置文件的熵值;0 = 自动计算。
fontsobject · NoiseBlockoptionalenabled:true 为每个配置文件隐藏少量确定性的
非关键字体子集(其余真实主机字体直接透传)。
Show propertiesHide properties
enabled:true 为每个配置文件隐藏少量确定性的
非关键字体子集(其余真实主机字体直接透传)。
每个配置文件的熵值;0 = 自动计算。
networkobjectoptionalShow propertiesHide properties
局域网端口扫描防护(ports_protection)。
IANA 名称或 "auto"; 将在启动时通过绑定代理解析。
200更新后的已保存配置文件。application/json
磁盘上的完整配置文件:_meta 包装层加上展开的
FingerprintConfig(所有 Fingerprint 字段位于顶层)。
running/cdp 仅在配置文件运行时存在。
_metaobjectoptionalShow propertiesHide properties
inline_proxyobject · ProxyEntry· nullableoptional完整的代理条目(嵌入在 _meta.inline_proxy 中)。
Show propertiesHide properties
完整的代理条目(嵌入在 _meta.inline_proxy 中)。
socks5httphttps每次写入都会递增。桌面编辑器会回传打开配置文件时的版本号;如果配置文件已通过此 API 修改,桌面保存会被拒绝,以免覆盖修改。API 修改不会被拒绝,而是读取并一次性写回配置文件。
cdpobject · CdpInfo· nullableoptional正在运行的配置文件的 CDP 端点。
Show propertiesHide properties
正在运行的配置文件的 CDP 端点。
Chrome 选择的 remote-debugging 端口。
REST 基础地址(/json、/json/version)。
Puppeteer/Playwright connect 使用的浏览器级 WS 端点。
400无效的 fingerprint(非对象)或无法解析的代理。application/json
401缺失或无效的 Bearer 令牌。
404未找到配置文件。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000PATCH /profiles/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}curl -X PATCH 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"text","notes":"text","folder":"text","proxy_id":"text","proxy":"text","color":"text","extensions":["text"],"refresh_rate":60,"fingerprint":{"name":"text","notes":"text","seed":1,"navigator":{"user_agent":"text","platform":"Win32","hardware_concurrency":12,"device_memory":16,"language":"text","do_not_track":true},"screen":{"width":1,"height":1,"avail_width":1,"avail_height":1,"color_depth":24,"device_pixel_ratio":2,"color_gamut":"","refresh_rate":60},"client_hints":{"platform":"text","platform_version":"text","architecture":"x86","bitness":"64","mobile":true},"webgl":{"unmasked_vendor":"text","unmasked_renderer":"text"},"webgpu":{},"webrtc":"auto","noise":{"canvas":{"enabled":true,"seed":1},"webgl":{"enabled":true,"seed":1,"intensity":1},"audio":{"enabled":true,"seed":1,"intensity":1},"client_rects":{"enabled":true,"seed":1,"max_offset":1},"sensors":{"enabled":true,"seed":1},"fonts":{"enabled":true,"seed":1}},"network":{"blocked_ports":[1]},"timezone":"text"}}'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text",
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": True,
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60,
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": True,
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text",
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": True,
"seed": 1,
},
"webgl": {
"enabled": True,
"seed": 1,
"intensity": 1,
},
"audio": {
"enabled": True,
"seed": 1,
"intensity": 1,
},
"client_rects": {
"enabled": True,
"seed": 1,
"max_offset": 1,
},
"sensors": {
"enabled": True,
"seed": 1,
},
"fonts": {
"enabled": True,
"seed": 1,
},
},
"network": {
"blocked_ports": [
1,
],
},
"timezone": "text",
},
}
response = requests.patch(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000";
const payload = {
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
};
const response = await fetch(url, {
method: "PATCH",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000"
body := bytes.NewBufferString(`{
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}`)
req, err := http.NewRequest("PATCH", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.patch("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Patch, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
request.Content = new StringContent("""
{
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"name": "text",
"notes": "text",
"folder": "text",
"proxy_id": "text",
"proxy": "text",
"color": "text",
"extensions": [
"text"
],
"refresh_rate": 60,
"fingerprint": {
"name": "text",
"notes": "text",
"seed": 1,
"navigator": {
"user_agent": "text",
"platform": "Win32",
"hardware_concurrency": 12,
"device_memory": 16,
"language": "text",
"do_not_track": true
},
"screen": {
"width": 1,
"height": 1,
"avail_width": 1,
"avail_height": 1,
"color_depth": 24,
"device_pixel_ratio": 2,
"color_gamut": "",
"refresh_rate": 60
},
"client_hints": {
"platform": "text",
"platform_version": "text",
"architecture": "x86",
"bitness": "64",
"mobile": true
},
"webgl": {
"unmasked_vendor": "text",
"unmasked_renderer": "text"
},
"webgpu": {},
"webrtc": "auto",
"noise": {
"canvas": {
"enabled": true,
"seed": 1
},
"webgl": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"audio": {
"enabled": true,
"seed": 1,
"intensity": 1
},
"client_rects": {
"enabled": true,
"seed": 1,
"max_offset": 1
},
"sensors": {
"enabled": true,
"seed": 1
},
"fonts": {
"enabled": true,
"seed": 1
}
},
"network": {
"blocked_ports": [
1
]
},
"timezone": "text"
}
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"_meta": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"proxy_id": "text",
"inline_proxy": {
"id": "text",
"name": "text",
"kind": "socks5",
"host": "text",
"port": 1,
"username": "text",
"password": "text",
"country": "text",
"notes": "text"
},
"last_launched_at": "text",
"created_at": "text",
"pinned": true,
"folder": "text",
"temporary": true,
"rev": 1
},
"running": true,
"cdp": {
"port": 1,
"http_url": "http://127.0.0.1:53217",
"web_socket_debugger_url": "ws://127.0.0.1:53217/devtools/browser/ab12-..."
}
}{
"error": "text"
}{
"error": "text"
}启动配置文件(含 CDP)
http://127.0.0.1:40325/profiles/{id}/start为配置文件启动启用了 remote-debugging 的 ShardX 浏览器,
通过绑定代理填充 auto 字段(时区/语言/地理位置),
并在 Chrome 写入 DevToolsActivePort 后返回 CDP 端点。
CDP 仅在通过 API 启动时启用(通过界面启动不开放调试端口;
反检测能力不受影响)。
若在超时内无法读取端点,cdp 返回 null。
适用于普通配置文件和临时配置文件。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
可选。空请求体以图形界面模式启动。
以 headless 模式启动(--headless=new)。
200已启动。application/json
操作系统进程 PID。
cdpobject · CdpInfo· nullableoptional正在运行的配置文件的 CDP 端点。
Show propertiesHide properties
正在运行的配置文件的 CDP 端点。
Chrome 选择的 remote-debugging 端口。
REST 基础地址(/json、/json/version)。
Puppeteer/Playwright connect 使用的浏览器级 WS 端点。
为什么 cdp 为空,当它是时。否则缺席。
401缺失或无效的 Bearer 令牌。
500未配置二进制文件 / 无法启动进程。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000/startPOST /profiles/123e4567-e89b-12d3-a456-426614174000/start HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"headless": false
}curl -X POST 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"headless":false}'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"headless": False,
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start";
const payload = {
"headless": false
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start"
body := bytes.NewBufferString(`{
"headless": false
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"headless": false
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start");
request.Content = new StringContent("""
{
"headless": false
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"headless": false
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/start");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"profile_id": "text",
"pid": 1,
"headless": true,
"cdp": {
"port": 1,
"http_url": "http://127.0.0.1:53217",
"web_socket_debugger_url": "ws://127.0.0.1:53217/devtools/browser/ab12-..."
},
"cdp_error": "text"
}{
"error": "text"
}停止配置文件
http://127.0.0.1:40325/profiles/{id}/stop向浏览器发送 graceful shutdown 信号(Unix 上为 SIGTERM;等待 5 秒,
然后发送 SIGKILL)。临时配置文件在关闭过程中被删除。
若配置文件未运行,stopped 返回 false。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
200已发送停止命令。application/json
401缺失或无效的 Bearer 令牌。
/profiles/123e4567-e89b-12d3-a456-426614174000/stopPOST /profiles/123e4567-e89b-12d3-a456-426614174000/stop HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X POST 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.post(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop";
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop"
req, err := http.NewRequest("POST", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/stop");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"profile_id": "text",
"stopped": true
}导出 cookies
http://127.0.0.1:40325/profiles/{id}/cookies读取配置文件的 Chromium cookie 存储,以解密形式返回所有 cookies。 对正在运行和已停止的配置文件均有效。 若配置文件从未启动过,返回空数组。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
200Cookies。application/json
cookiesobject · Cookie[]optionalShow propertiesHide properties
Cookie 主机(Chromium host_key),例如".example.com"。
Unix 秒数;null/缺失 = 会话 cookie。
导入时不区分大小写。
StrictLaxNoneunspecified401缺失或无效的 Bearer 令牌。
500读取或解密 cookie 数据库时出错。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000/cookiesGET /profiles/123e4567-e89b-12d3-a456-426614174000/cookies HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
}{
"error": "text"
}导入 cookies
http://127.0.0.1:40325/profiles/{id}/cookies将 cookies 写入配置文件存储(按 Chromium v10 方案重新加密)。 配置文件必须已停止; 运行中的浏览器在退出时会覆盖存储, 导致导入内容丢失。
来自 Settings → Automation API 的永久 JWT。
配置文件的 UUID。
cookiesobject · Cookie[]requiredShow propertiesHide properties
Cookie 主机(Chromium host_key),例如".example.com"。
Unix 秒数;null/缺失 = 会话 cookie。
导入时不区分大小写。
StrictLaxNoneunspecified200已导入。application/json
已写入的 cookie 数量。
401缺失或无效的 Bearer 令牌。
409配置文件正在运行; 请先停止它。application/json
500写入 cookie 数据库时出错。application/json
/profiles/123e4567-e89b-12d3-a456-426614174000/cookiesPOST /profiles/123e4567-e89b-12d3-a456-426614174000/cookies HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
{
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
}curl -X POST 'http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"cookies":[{"domain":"text","name":"text","value":"text","path":"/","expires":1,"secure":false,"http_only":false,"same_site":"Strict"}]}'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies"
headers = {
"Authorization": f"Bearer {token}",
}
payload = {
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": False,
"http_only": False,
"same_site": "Strict",
},
],
}
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies";
const payload = {
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
};
const response = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
console.log(response.status);
console.log(await response.text());package main
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies"
body := bytes.NewBufferString(`{
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
}`)
req, err := http.NewRequest("POST", url, body)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }, serde_json = "1"
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.post("http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies")
.header("Authorization", format!("Bearer {token}"))
.json(&serde_json::json!({
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
}))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Post, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies");
request.Content = new StringContent("""
{
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
headers = curl_slist_append(headers, "Content-Type: application/json");
const std::string body = R"json({
"cookies": [
{
"domain": "text",
"name": "text",
"value": "text",
"path": "/",
"expires": 1,
"secure": false,
"http_only": false,
"same_site": "Strict"
}
]
})json";
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/profiles/123e4567-e89b-12d3-a456-426614174000/cookies");
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, static_cast<long>(body.size()));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}{
"imported": 1
}{
"error": "text"
}{
"error": "text"
}正在运行的配置文件列表
http://127.0.0.1:40325/running拥有活跃浏览器进程的配置文件,通过 API 启动时包含 CDP 端点。
来自 Settings → Automation API 的永久 JWT。
200正在运行的配置文件。application/json
cdpobject · CdpInfo· nullableoptional正在运行的配置文件的 CDP 端点。
Show propertiesHide properties
正在运行的配置文件的 CDP 端点。
Chrome 选择的 remote-debugging 端口。
REST 基础地址(/json、/json/version)。
Puppeteer/Playwright connect 使用的浏览器级 WS 端点。
401缺失或无效的 Bearer 令牌。
/runningGET /running HTTP/1.1
Host: 127.0.0.1:40325
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*curl -X GET 'http://127.0.0.1:40325/running' \
-H 'Authorization: Bearer YOUR_SECRET_TOKEN'import requests
# 来自 Settings → Automation API 的永久 JWT。
token = "YOUR_SECRET_TOKEN"
url = "http://127.0.0.1:40325/running"
headers = {
"Authorization": f"Bearer {token}",
}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.status_code)
print(response.text)// 来自 Settings → Automation API 的永久 JWT。
const token = "YOUR_SECRET_TOKEN";
const url = "http://127.0.0.1:40325/running";
const response = await fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
},
});
console.log(response.status);
console.log(await response.text());package main
import (
"fmt"
"io"
"log"
"net/http"
)
func main() {
// 来自 Settings → Automation API 的永久 JWT。
token := "YOUR_SECRET_TOKEN"
url := "http://127.0.0.1:40325/running"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
out, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(resp.Status)
fmt.Println(string(out))
}// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 来自 Settings → Automation API 的永久 JWT。
let token = "YOUR_SECRET_TOKEN";
let client = reqwest::Client::new();
let response = client
.get("http://127.0.0.1:40325/running")
.header("Authorization", format!("Bearer {token}"))
.send()
.await?;
println!("{}", response.status());
println!("{}", response.text().await?);
Ok(())
}using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
// 来自 Settings → Automation API 的永久 JWT。
var token = "YOUR_SECRET_TOKEN";
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var request = new HttpRequestMessage(HttpMethod.Get, "http://127.0.0.1:40325/running");
var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}// build: c++ -std=c++17 main.cpp -lcurl
#include <curl/curl.h>
#include <iostream>
#include <string>
static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
static_cast<std::string *>(userdata)->append(ptr, size * nmemb);
return size * nmemb;
}
int main() {
// 来自 Settings → Automation API 的永久 JWT。
const std::string token = "YOUR_SECRET_TOKEN";
curl_global_init(CURL_GLOBAL_DEFAULT);
CURL *curl = curl_easy_init();
if (!curl) {
std::cerr << "curl_easy_init failed\n";
curl_global_cleanup();
return 1;
}
struct curl_slist *headers = nullptr;
headers = curl_slist_append(headers, ("Authorization: Bearer " + token).c_str());
std::string response;
curl_easy_setopt(curl, CURLOPT_URL, "http://127.0.0.1:40325/running");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
const CURLcode rc = curl_easy_perform(curl);
if (rc != CURLE_OK) {
std::cerr << curl_easy_strerror(rc) << "\n";
} else {
long status = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
std::cout << status << "\n" << response << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
curl_global_cleanup();
return rc == CURLE_OK ? 0 : 1;
}[
{
"profile_id": "text",
"pid": 1,
"cdp": {
"port": 1,
"http_url": "http://127.0.0.1:53217",
"web_socket_debugger_url": "ws://127.0.0.1:53217/devtools/browser/ab12-..."
}
}
]最后更新