Skip to content
Home » DICloak Open API Guide

DICloak Open API Guide

1.Open API Development Guide

1.1 Usage

  1. Install and log in to the DICloak Antidetect Browser.
  2. Navigate to More> Settings > Open API to obtain the local interface URL and API key.
  3. Download the sample code and execute the script.

1.2 Interface Usage Overview

  • When the request method is POST, parameters must be passed in the request body as JSON, not as form-data or URL query parameters.
  • When the request method is GET, parameters must be passed as form-data.
  • For PUT/PATCH/DELETE requests, refer to the specific interface documentation for parameter requirements.
  • A successful response with HTTP status 200 will return a JSON object with code set to 0. If there is additional data, it will be included in the data object.
  • Responses with non-200 HTTP statuses indicate errors. The error code will correspond to the HTTP status code, and a code other than 0 indicates failure. The error message will be included in the msg field, with error codes as referenced in the table below.
  • For all interface requests, the URL must be appended with “/openapi“. See the sample code for details.
{
    'code': 0,
    'msg': 'success',
    'data': {
        'serial_number': 2,
        'pid': '27028',
        'debug_port': 17539
    }
}
{
    'code': 500,
    'msg': 'fetch fail'
}
  • All requests must include the header X-API-KEY, with the value set to the API key copied from the client.

1.3 Example Code

The following demo showcases actions like retrieving environment lists, opening environments, connecting to environments, interacting with windows, and closing pages and windows, using Python (Playwright), Python (Chromedriver), Node.js (Puppeteer), and Java (Chromedriver).

1.3.1 Python Example Code (Playwright)

import time
import requests
from playwright.sync_api import sync_playwright

# API configuration for DICloak's open API platform
BASE_URL = "http://127.0.0.1:52140/openapi"  # Base URL of the API running locally
API_KEY = "*****"  # ⚠️ Your API key for authentication


def get_env_list():
    """
    Fetch a list of available browser environments from the DICloak API.
    Returns a JSON response containing environment details.
    """
    headers = {"X-API-KEY": API_KEY}  # Set API key in the request headers for authentication
    params = {"page_no": 1, "page_size": 20}  # Pagination: get first page with up to 20 environments
    try:
        response = requests.get(f"{BASE_URL}/v1/env/list", params=params, headers=headers)
        response.raise_for_status()  # Raise an exception for bad HTTP status codes
        return response.json()  # Return the API response as a Python dictionary
    except requests.RequestException as e:
        print(f"Failed to fetch environment list: {e}")
        return {"code": -1, "msg": str(e)}  # Return a mock error response


def open_env(env_id):
    """
    Open a specific browser environment using its ID.
    Args:
        env_id (str): The unique ID of the environment to open.
    Returns:
        dict: JSON response with details like debug port.
    """
    headers = {"X-API-KEY": API_KEY}  # Authentication header
    try:
        response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/open", headers=headers)
        response.raise_for_status()  # Raise an exception for bad HTTP status codes
        return response.json()  # Return the response as a dictionary
    except requests.RequestException as e:
        print(f"Failed to open environment {env_id}: {e}")
        return {"code": -1, "msg": str(e)}  # Return a mock error response


def close_env(env_id):
    """
    Close a specific browser environment using its ID.
    Args:
        env_id (str): The unique ID of the environment to close.
    Returns:
        dict: JSON response confirming the closure.
    """
    headers = {"X-API-KEY": API_KEY}  # Authentication header
    try:
        response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/close", headers=headers)
        response.raise_for_status()  # Raise an exception for bad HTTP status codes
        return response.json()  # Return the response as a dictionary
    except requests.RequestException as e:
        print(f"Failed to close environment {env_id}: {e}")
        return {"code": -1, "msg": str(e)}  # Return a mock error response


def get_browser_targets(port):
    """
    Get browser connection details (like WebSocket URL) using the debug port.
    Args:
        port (int): The debug port returned when opening an environment.
    Returns:
        dict or None: Browser details if successful, None if failed.
    """
    url = f"http://127.0.0.1:{port}/json/version"  # URL to fetch browser version and WebSocket info
    try:
        response = requests.get(url)
        if response.status_code == 200:  # Check if the request was successful
            return response.json()  # Return browser details
        else:
            print(f"Failed to get targets: {response.text}")  # Print error if request fails
            return None
    except requests.RequestException as e:
        print(f"Failed to get browser targets on port {port}: {e}")
        return None


def open_browser_with_playwright(debug_port):
    """
    Connect to the browser environment using Playwright and open two web pages.
    Args:
        debug_port (int): The debug port to connect to the browser.
    Returns:
        tuple: Playwright instance, browser object, and list of pages (or None if failed).
    """
    # Fetch browser connection details using the debug port
    targets = get_browser_targets(debug_port)
    if targets and 'webSocketDebuggerUrl' in targets:  # Check if connection details are valid
        ws_url = targets['webSocketDebuggerUrl']  # WebSocket URL to control the browser
        print(f"Connecting to WebSocket URL: {ws_url}")  # Show the connection URL

        try:
            # Start Playwright manually (so we can control when to stop it)
            p = sync_playwright().start()
            browser = p.chromium.connect_over_cdp(ws_url)  # Connect to the browser via WebSocket

            # Use an existing context if available, or create a new one
            context = browser.contexts[0] if browser.contexts else browser.new_context()

            # Open Page 1: Visit Zhihu
            page1 = context.new_page()  # Create a new tab in the browser
            page1.goto("https://www.zhihu.com")  # Navigate to Zhihu

            # Open Page 2: Visit Facebook
            page2 = context.new_page()  # Create another new tab
            page2.goto("https://www.facebook.com")  # Navigate to Facebook

            # Return Playwright instance, browser, and pages for later use
            return p, browser, [page1, page2]
        except Exception as e:
            print(f"Playwright connection or navigation failed: {e}")
            if 'p' in locals():  # Clean up if Playwright was started
                p.stop()
            return None, None, None
    else:
        print("No valid WebSocket URL found")  # Error message if connection fails
        return None, None, None  # Return None if something goes wrong


def main():
    """Main function to demonstrate how to use the DICloak API with Playwright."""
    try:
        # Step 1: Get the list of available environments
        resp = get_env_list()
        if resp['code'] != 0:  # Check if the API call was successful (code 0 means success)
            print(f"Error: {resp['msg']}")  # Print error message if failed
            return

        env_list = resp['data']['list']  # Extract the list of environments
        if not env_list:  # Check if there are any environments available
            print("No available environments found")
            return

        # Step 2: Choose an environment to open (using the second one in the list)
        env_id = env_list[1]['id']  # Get the ID of the second environment
        print(f"Opening environment: {env_id}")  # Show which environment we're opening

        # Step 3: Open the environment
        open_resp = open_env(env_id)
        if open_resp['code'] != 0:  # Check if opening was successful
            print(f"Error: {open_resp['msg']}")
            return

        print(f"Environment opened successfully: {open_resp['code'] == 0}")
        debug_port = open_resp['data']['debug_port']  # Get the debug port for browser control
        print(f"Debug port: {debug_port}")

        # Wait for kernel to start
        time.sleep(2)

        # Step 4: Connect to the browser and open pages
        playwright_instance, browser, pages = open_browser_with_playwright(debug_port)
        if not browser:  # Check if connection failed
            print("Failed to connect to the browser")
            return

        # Step 5: Wait and close Page 1
        print("Waiting 5 seconds before closing Page 1")
        time.sleep(5)
        try:
            pages[0].close()  # Close the first page (Zhihu)
            print("Page 1 closed")
        except Exception as e:
            print(f"Failed to close Page 1: {e}")

        # Step 6: Wait and close the environment
        print("Waiting 5 seconds before closing the environment")
        time.sleep(5)

        try:
            close_env(env_id)  # Close the environment via API
            browser.close()  # Close the browser connection
            playwright_instance.stop()  # Stop Playwright and free resources
            print("Environment closed and resources freed")
        except Exception as e:
            print(f"Failed to clean up resources: {e}")
    except Exception as e:
        print(f"Unexpected error in main: {e}")


if __name__ == "__main__":
    main()  # Run the main function when the script is executed

1.3.2 Python Sample Code

The DICloak browser is built on the Chromium 120 kernel, so you need to download the appropriate version of chromedriver before using it.

import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# API configuration
BASE_URL = "http://127.0.0.1:52140/openapi"  # API base URL
API_KEY = "*****"  # ⚠️ Your API key for authentication 

def open_browser(port):
    """
    Connect to a browser using Selenium and open a webpage.
    :param port: Debug port to connect to the browser.
    """
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_experimental_option('debuggerAddress', f"127.0.0.1:{port}")  # Use debug port
    s = Service(r"G:\chromedriver.exe")  # Path to ChromeDriver
    browser = webdriver.Chrome(options=chrome_options, service=s)
    browser.get("https://www.facebook.com")  # Open Facebook as an example

def get_evn_list():
    # Get list of available environments from the API
    headers = {"X-API-KEY": API_KEY}  # Authentication header
    params = {"page_no": 1, "page_size": 20}  # Pagination settings
    response = requests.get(f"{BASE_URL}/v1/env/list", params=params, headers=headers)
    return response.json()

def open_env(env_id):
    """
    Open an environment by ID.
    :param env_id: The ID of the environment to open.
    """
    headers = {"X-API-KEY": API_KEY}  # Authentication header
    response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/open", headers=headers)
    return response.json()

def close_env(env_id):
    """
    Close an environment by ID.
    :param env_id: The ID of the environment to close.
    """
    headers = {"X-API-KEY": API_KEY}  # Authentication header
    response = requests.patch(f"{BASE_URL}/v1/env/{env_id}/close", headers=headers)
    return response.json()

if __name__ == '__main__':
    # Get environment list
    resp = get_evn_list()
    if resp['code'] != 0:  # Check for errors
        print(resp.msg)
        exit(0)
    
    list = resp['data']['list']  # Extract environment list
    if len(list) == 0:  # Check if list is empty
        print('no profile')
        exit(0)
    
    print(f"open profile:{list[0]['id']}")  # Show the ID of the first environment
    
    # Open the environment
    open_resp = open_env(list[0]['id'])
    if open_resp['code'] != 0:  # Check for errors
        print(open_resp['msg'])
        exit(0)
    
    print(f"open_resp : {open_resp}")  # Show response details
    
    # Connect to browser and open a page
    open_browser(open_resp['data']['debug_port'])
    
    time.sleep(3)  # Wait 3 seconds
    
    # Close the environment
    close_env(list[0]['id'])

1.3.3 Node.js Sample Code(puppeteer)

const puppeteer = require('puppeteer');
const axios = require('axios');

// API configuration for DICloak's open API platform
const BASE_URL = "http://127.0.0.1:52140/openapi"; // Base URL of the API running locally
const API_KEY = "*****"; // Your API key for authentication

async function getEnvList() {
  /**
   * Fetch a list of available browser environments from the DICloak API.
   * Returns a JSON response with environment details.
   */
  const headers = { "X-API-KEY": API_KEY }; // Set API key for authentication
  const params = { page_no: 1, page_size: 20 }; // Pagination: get first page with up to 20 environments
  try {
    const response = await axios.get(`${BASE_URL}/v1/env/list`, { params, headers });
    return response.data; // Return the API response as an object
  } catch (error) {
    console.log(`Failed to fetch environment list: ${error.message}`);
    return { code: -1, msg: error.message }; // Return a mock error response
  }
}

async function openEnv(envId) {
  /**
   * Open a specific browser environment using its ID.
   * @param {string} envId - The unique ID of the environment to open.
   * @returns {object} - JSON response with details like debug port.
   */
  const headers = { "X-API-KEY": API_KEY }; // Authentication header
  try {
    const response = await axios.patch(`${BASE_URL}/v1/env/${envId}/open`, {}, { headers });
    return response.data; // Return the response as an object
  } catch (error) {
    console.log(`Failed to open environment ${envId}: ${error.message}`);
    return { code: -1, msg: error.message }; // Return a mock error response
  }
}

async function closeEnv(envId) {
  /**
   * Close a specific browser environment using its ID.
   * @param {string} envId - The unique ID of the environment to close.
   * @returns {object} - JSON response confirming the closure.
   */
  const headers = { "X-API-KEY": API_KEY }; // Authentication header
  try {
    const response = await axios.patch(`${BASE_URL}/v1/env/${envId}/close`, {}, { headers });
    return response.data; // Return the response as an object
  } catch (error) {
    console.log(`Failed to close environment ${envId}: ${error.message}`);
    return { code: -1, msg: error.message }; // Return a mock error response
  }
}

async function getBrowserTargets(port) {
  /**
   * Get browser connection details (like WebSocket URL) using the debug port.
   * @param {number} port - The debug port returned when opening an environment.
   * @returns {object|null} - Browser details if successful, null if failed.
   */
  const url = `http://127.0.0.1:${port}/json/version`; // URL to fetch browser version and WebSocket info
  try {
    const response = await axios.get(url);
    return response.data; // Return browser details
  } catch (error) {
    console.log(`Failed to get targets: ${error.message}`); // Print error if request fails
    return null;
  }
}

async function openBrowserWithPuppeteer(debugPort) {
  /**
   * Connect to the browser environment using Puppeteer and open two web pages.
   * @param {number} debugPort - The debug port to connect to the browser.
   * @returns {Promise<object>} - Puppeteer browser object and list of pages (or null if failed).
   */
  // Fetch browser connection details using the debug port
  const targets = await getBrowserTargets(debugPort);
  if (targets && targets.webSocketDebuggerUrl) { // Check if connection details are valid
    const wsUrl = targets.webSocketDebuggerUrl; // WebSocket URL to control the browser
    console.log(`Connecting to WebSocket URL: ${wsUrl}`); // Show the connection URL

    try {
      // Connect to the existing browser instance via WebSocket
      const browser = await puppeteer.connect({
        browserWSEndpoint: wsUrl, // Use the WebSocket URL from the API
        defaultViewport: null // Keep the default viewport of the environment
      });

      // Open Page 1: Visit Zhihu
      const page1 = await browser.newPage(); // Create a new tab in the browser
      await page1.goto("https://www.zhihu.com"); // Navigate to Zhihu

      // Open Page 2: Visit Baidu
      const page2 = await browser.newPage(); // Create another new tab
      await page2.goto("https://www.baidu.com"); // Navigate to Baidu

      // Return browser and pages for later use
      return { browser, pages: [page1, page2] };
    } catch (error) {
      console.log(`Puppeteer connection or navigation failed: ${error.message}`);
      return null; // Return null if something goes wrong
    }
  } else {
    console.log("No valid WebSocket URL found"); // Error message if connection fails
    return null; // Return null if something goes wrong
  }
}

async function main() {
  /** Main function to demonstrate how to use the DICloak API with Puppeteer. */
  try {
    // Step 1: Get the list of available environments
    const resp = await getEnvList();
    if (resp.code !== 0) { // Check if the API call was successful (code 0 means success)
      console.log(`Error: ${resp.msg}`); // Print error message if failed
      return;
    }

    const envList = resp.data.list; // Extract the list of environments
    if (!envList || envList.length === 0) { // Check if there are any environments available
      console.log("No available environments found");
      return;
    }

    // Step 2: Choose an environment to open (using the second one in the list)
    const envId = envList[1].id; // Get the ID of the second environment
    console.log(`Opening environment: ${envId}`); // Show which environment we're opening

    // Step 3: Open the environment
    const openResp = await openEnv(envId);
    if (openResp.code !== 0) { // Check if opening was successful
      console.log(`Error: ${openResp.msg}`);
      return;
    }

    console.log(`Environment opened successfully: ${openResp.code === 0}`);
    const debugPort = openResp.data.debug_port; // Get the debug port for browser control
    console.log(`Debug port: ${debugPort}`);

    // Wait for kernel to start
    await new Promise((resolve) => setTimeout(() => {
      resolve()
    }, 2000))

    // Step 4: Connect to the browser and open pages
    const result = await openBrowserWithPuppeteer(debugPort);
    if (!result) { // Check if connection failed
      console.log("Failed to connect to the browser");
      return;
    }

    const { browser, pages } = result;

    // Step 5: Wait and close Page 1
    console.log("Waiting 5 seconds before closing Page 1");
    await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
    try {
      await pages[0].close(); // Close the first page (Zhihu)
      console.log("Page 1 closed");
    } catch (error) {
      console.log(`Failed to close Page 1: ${error.message}`);
    }

    // Step 6: Wait and close the environment
    console.log("Waiting 5 seconds before closing the environment");
    await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds
    try {
      await closeEnv(envId); // Close the environment via API
      await browser.close(); // Close the browser connection
      console.log("Environment closed and resources freed");
    } catch (error) {
      console.log(`Failed to clean up resources: ${error.message}`);
    }
  } catch (error) {
    console.error(`Unexpected error in main: ${error.message}`);
  }
}

// Run the main function and handle any errors
main().catch(error => {
  console.error(`An error occurred: ${error.message}`);
  process.exit(1); // Exit with an error code if something goes wrong
});

1.3.4 Java Sample Code

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import org.json.JSONArray;
import org.json.JSONObject;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class Main {

    // API configuration
    private static final String BASE_URL = "http://127.0.0.1:52140/openapi";  // Base URL for the DICloak API
    private static final String API_KEY = "****";  // ⚠️ Your API key for authentication 

    public static void main(String[] args) {
        // Get environment list
        JSONObject resp = getEvnList();
        if (resp.getInt("code") != 0) {  // Check for errors
            System.out.println(resp.getString("msg"));
            System.exit(0);
        }
        JSONArray list = resp.getJSONObject("data").getJSONArray("list");  // Extract environment list
        if (list.length() == 0) {  // Check if list is empty
            System.out.println("no profile");
            System.exit(0);
        }
        System.out.println("open profile:" + list.getJSONObject(0).getString("id"));  // Show first environment ID

        // Open the environment
        JSONObject openResp = openEnv(list.getJSONObject(0).getString("id"));
        if (openResp.getInt("code") != 0) {  // Check for errors
            System.out.println(openResp.getString("msg"));
            System.exit(0);
        }

        System.out.println("open_resp : " + openResp);  // Show response details

        // Open browser and visit a webpage
        WebDriver browser = openBrowser(openResp.getJSONObject("data").getString("debug_port"));

        try {
            TimeUnit.SECONDS.sleep(3);  // Wait 3 seconds
        } catch (InterruptedException e) {
            e.printStackTrace();  // Print error if sleep is interrupted
        }

        // Close the environment
        closeEnv(list.getJSONObject(0).getString("id"));

        // Close the browser
        browser.quit();
    }

    public static JSONObject getEvnList() {
        // Fetch list of environments from the API
        try {
            URL url = new URL(BASE_URL + "/v1/env/list?page_no=1&page_size=20");  // API endpoint with pagination
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("X-API-KEY", API_KEY);  // Set API key header
            connection.setRequestMethod("GET");  // Use GET method

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {  // Check if request succeeded
                Scanner scanner = new Scanner(connection.getInputStream());
                StringBuilder response = new StringBuilder();
                while (scanner.hasNextLine()) {
                    response.append(scanner.nextLine());
                }
                scanner.close();
                return new JSONObject(response.toString());  // Return JSON response
            }
            throw new RuntimeException("Request failed, status code: " + responseCode);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static JSONObject openEnv(String envId) {
        // Open an environment by ID
        try {
            URL url = new URL(BASE_URL + "/v1/env/" + envId + "/open");  // API endpoint to open environment
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("X-API-KEY", API_KEY);  // Set API key header
            connection.setRequestMethod("PATCH");  // Use PATCH method

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {  // Check if request succeeded
                Scanner scanner = new Scanner(connection.getInputStream());
                StringBuilder response = new StringBuilder();
                while (scanner.hasNextLine()) {
                    response.append(scanner.nextLine());
                }
                scanner.close();
                return new JSONObject(response.toString());  // Return JSON response
            }
            throw new RuntimeException("Request failed, status code: " + responseCode);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static JSONObject closeEnv(String envId) {
        // Close an environment by ID
        try {
            URL url = new URL(BASE_URL + "/v1/env/" + envId + "/close");  // API endpoint to close environment
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("X-API-KEY", API_KEY);  // Set API key header
            connection.setRequestMethod("PATCH");  // Use PATCH method

            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {  // Check if request succeeded
                Scanner scanner = new Scanner(connection.getInputStream());
                StringBuilder response = new StringBuilder();
                while (scanner.hasNextLine()) {
                    response.append(scanner.nextLine());
                }
                scanner.close();
                return new JSONObject(response.toString());  // Return JSON response
            }
            throw new RuntimeException("Request failed, status code: " + responseCode);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static WebDriver openBrowser(String port) {
        // Connect to browser using Selenium and debug port
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setExperimentalOption("debuggerAddress", "127.0.0.1:" + port);  // Use debug port
        return new ChromeDriver(chromeOptions);  // Launch Chrome browser
    }
}