> This page is for version v1 (default).
> For other versions, use one of these documentation indexes:
> - v1 (default): https://platform.bctrl.ai/v1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://platform.bctrl.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://platform.bctrl.ai/_mcp/server.

# Execute desktop double-click

POST https://api.bctrl.ai/v1/browsers/{browserId}/computer/double-click
Content-Type: application/json

Double-click the left mouse button in the current Browser Run. Coordinates use screenshot pixels; omission uses the current cursor. An interrupted action returns unknown with its accepted Event ID.

Reference: https://platform.bctrl.ai/api/api-reference/browsers/computer-double-click

## Authentication

- `Authorization` header (bearer token, required) — Use Bearer \<api-key>.

## Servers

- `https://api.bctrl.ai` (Production, default)
- `http://localhost:8787` (Local development gateway)

## Request

### Path parameters

- `browserId` (string, required)

### Query parameters

- `spaceId` (V1BrowsersBrowserIdComputerDoubleClickPostParametersSpaceId, optional)

### Headers

- `BCTRL-Version` (enum, optional) — Dated API version. Defaults to the release pinned when the API key was created.
  - Allowed values: `2026-10-01`, `2026-10-03`
- `BCTRL-Space` (string, optional) — Select one authorized Space by its opaque ID or unique name. Omission uses the operation default.
- `BCTRL-Subaccount-Id` (string, optional) — Optional effective subaccount context for organization API keys. Subaccount API keys are already scoped and cannot use this header to act as another subaccount.
- `Idempotency-Key` (string, optional) — Optional retry key for this billable operation. Reusing the same key with the same request replays its stable outcome; credential-bearing results may be freshly issued for the same principal. Reusing it with a different request returns 409.

### Body (application/json)

This endpoint expects a BrowsersComputerDoubleClickRequest.

- `coordinate` (list of any, optional)
- `modifiers` (string, optional)

## Response

### 200

OK

- `data` (ComputerUseOutput, required, nullable)
- `eventId` (string, required) — Unique runEvent identifier generated by BCTRL.
- `object` ("computer.result", required)
- `status` (enum, required)
  - Allowed values: `succeeded`, `unknown`

## Errors

### 400 Bad Request Error

The request was invalid. See `code` and `details`. Example code: `request.invalid`.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

### 401 Unauthorized Error

Authentication required: the API key is missing or invalid.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

### 403 Forbidden Error

Forbidden: the API key cannot access this resource.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

### 404 Not Found Error

The requested resource was not found. Example code: `browser.not_found`.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

### 409 Conflict Error

The request conflicts with the current resource state. Example code: `tool.name_conflict`.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

### 429 Too Many Requests Error

Rate limit exceeded. Retry after the delay indicated by Retry-After.

- `error` (V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError, required)

## Types

### V1BrowsersBrowserIdComputerDoubleClickPostParametersSpaceId

### ComputerUseOutput

- `action` (enum, required)
  - Allowed values: `screenshot`, `left_click`, `right_click`, `middle_click`, `double_click`, `triple_click`, `type`, `key`, `mouse_move`, `scroll`, `left_click_drag`, `wait`, `cursor_position`
- `height` (integer, required)
- `width` (integer, required)
- `coordinate` (list of any, optional)
- `image` (ComputerUseOutputImage, optional)

### V1BrowsersBrowserIdComputerDoubleClickPostResponsesContentApplicationJsonSchemaError

- `code` (enum, required)
  - Allowed values: `run.activation_conflict`, `viewer.connection_unavailable`, `browser.state_saving`, `browser.start_not_found`, `run.artifacts_not_ready`, `run.scope_invalid`, `run.admission_changed`, `browser.start_admission_changed`, `run.reservation_conflict`, `run.end_time_invalid`, `run.stale_generation`, `run.connections_changed`, `run.host_mismatch`, `agent.admission_failed`, `agent.gateway_unconfigured`, `agent.model_not_allowed`, `agent.model_not_supported`, `agent.not_found`, `agent.name_conflict`, `agent.version_not_found`, `agent.scope_widening_forbidden`, `agent.scope_unverified`, `agent.promotion_approval_required`, `agent.runtime_type_not_supported`, `agent.unavailable`, `ai.gateway_execution_denied`, `ai.gateway_misconfigured`, `ai.gateway_unavailable`, `ai.rate_limited`, `ai.saved_connections_denied`, `ai_connection.disabled`, `ai_connection.not_found`, `ai_connection.scope_mismatch`, `ai_connection.unsupported_provider`, `ai_credential.api_key_missing`, `ai_credential.base_url_required`, `ai_credential.disabled`, `ai_credential.not_found`, `ai_credential.provider_unsupported`, `ai_credential.test_unsupported`, `ai_credential.verification_failed`, `api_key.child_revoke_failed`, `api_key.error`, `api_key.not_found`, `api_key.scopes_unsupported`, `api_keys.org_access_denied`, `api_keys.subaccount_access_denied`, `artifact_export.failed`, `artifact_export.file_not_found`, `artifact_export.no_artifacts`, `artifact_export.path_exists`, `artifact_export.source_changed`, `artifact_export.too_large`, `artifact_export.too_many_files`, `auth.admin_assertion_required`, `auth.admin_capability_required`, `auth.conflict`, `auth.customer_actor_required`, `auth.execution_delegation_rejected`, `auth.expired`, `auth.forbidden`, `auth.invalid`, `auth.invalid_signature`, `auth.legacy_identity_rejected`, `auth.principal_missing`, `auth.private_network_required`, `auth.rate_limited`, `auth.required`, `auth.runtime_invalid`, `auth.runtime_required`, `auth.service_unavailable`, `auth.subaccount_context_unsupported`, `auth.subaccount_invalid`, `auth.unauthorized`, `auth.view_invalid`, `auth.workload_invalid`, `auth.workload_issuer_invalid`, `auth.workload_required`, `billing.insufficient_credits`, `billing.insufficient_purchased_credits`, `branding.accent_contrast`, `branding.logo_invalid`, `branding.logo_too_large`, `branding.logo_unsafe`, `browser.concurrent_quota_exceeded`, `browser_extension.archive_limit_exceeded`, `browser_extension.duplicate_ids`, `browser_extension.file_empty`, `browser_extension.file_required`, `browser_extension.identity_mismatch`, `browser_extension.import_failed`, `browser_extension.import_url_invalid`, `browser_extension.in_use`, `browser_extension.invalid_ids`, `browser_extension.invalid_package`, `browser_extension.invalid_signature`, `browser_extension.not_found`, `browser_extension.protected_identity`, `browser_extension.scope_mismatch`, `browser_extension.storage_cleanup_failed`, `browser_extension.too_many`, `browser_extension.unsupported_format`, `browser_extension.verification_required`, `browser_extension.verification_unavailable`, `browser_profile.not_found`, `browser.not_found`, `browser.name_conflict`, `browser.changed`, `browser.not_running`, `browser.control_held`, `browser.file_transfer_failed`, `browser.fetch_failed`, `browser.fetch_timeout`, `browser.connections_unavailable`, `browser.already_started`, `browser.identity_in_use`, `browser.persona_required`, `browser.no_saved_state`, `browser.identity_missing`, `browser.configuration_missing`, `browser.start_timeout`, `browser.stop_pending`, `capabilities.invalid_override_value`, `capabilities.organization_not_found`, `capability.limit_exceeded`, `capability.not_available`, `capacity_test.run_missing`, `connection.protocol_unsupported`, `control_plane.unavailable`, `conversation.cursor_invalid`, `conversation.message_cursor_invalid`, `conversation.not_found`, `event.not_found`, `trace.not_found`, `drain.not_found`, `drain.destination_invalid`, `drain.destination_type_changed`, `conversation.busy`, `device_session.denied`, `device_session.expired`, `device_session.not_found`, `environment.bound`, `environment.busy`, `environment.changed`, `environment.connection_unavailable`, `environment.cursor_invalid`, `environment.environment_missing`, `environment.file_integrity`, `environment.file_too_large`, `environment.image_not_allowed`, `environment.not_a_file`, `environment.name_conflict`, `sandbox.not_found`, `sandbox.not_ready`, `sandbox.no_shell`, `sandbox.port_refused`, `sandbox.port_unreachable`, `sandbox.snapshot_space_mismatch`, `sandbox.secret_env_fork`, `sandboxSnapshot.not_found`, `sandboxSnapshot.name_conflict`, `environment.snapshots_unavailable`, `environment.not_ready`, `environment.path_exists`, `environment.path_invalid`, `environment.path_not_found`, `environment.provision_timeout`, `environment.provisioning`, `environment.runtime_bound`, `environment.stopping`, `environment.task_active`, `environment.unavailable`, `sandboxProcess.not_found`, `sandboxConnection.not_found`, `environment_exec.finished`, `execution_delegation.invalid`, `file.not_found`, `file.required`, `files.invalid_cursor`, `gateway.misconfigured`, `gateway.timeout`, `help.not_found`, `human_request.view_requires_run`, `idempotency.finalization_uncertain`, `idempotency.reconciliation_required`, `idempotency_key.invalid`, `idempotency_key.required`, `idempotency.mismatch`, `idempotency.not_replayable`, `idempotency_key_in_progress`, `idempotency_key_uncertain`, `internal.error`, `internal.response_serialization_failed`, `knowledge.evaluation_empty`, `knowledge.evaluation_failed`, `knowledge.evaluation_not_found`, `knowledge.evaluation_stale`, `knowledge.item_not_found`, `knowledge.key_invalid`, `knowledge.not_candidate`, `knowledge.not_published`, `knowledge.review_required`, `knowledge.source_not_found`, `knowledge.source_required`, `knowledge.space_not_found`, `knowledge.version_not_found`, `knowledge.visibility_mismatch`, `notification_recipient.duplicate`, `notification_recipient.invalid_email`, `notification_recipient.invalid_phone`, `notification_recipient.not_found`, `notification_recipient.value_required`, `organization.default_region_invalid`, `organization.default_region_missing`, `organization.member_required`, `organization.not_found`, `output.schema_invalid`, `output.schema_mismatch`, `pagination.cursor_invalid`, `plan_transition.error`, `playground_api_key.error`, `playground_execution.cancelled`, `playground_execution.not_startable`, `playground_principal.create_failed`, `profile.proxy_intent_invalid`, `proxies.access_denied`, `proxies.managed_rotating_denied`, `proxies.managed_static_denied`, `proxies.provider_misconfigured`, `proxies.provider_not_configured`, `proxies.provider_rate_limited`, `proxies.provider_rejected`, `proxies.provider_temporarily_unavailable`, `proxy.connection_required`, `proxy.device_unsupported`, `proxy.geo_country_mismatch`, `proxy.geo_fields_conflict`, `proxy.geo_not_found`, `proxy.geo_state_unsupported`, `proxy.geo_unavailable`, `proxy.kind_mismatch`, `proxy.lease_expired`, `proxy.managed_rotating.account_unavailable`, `proxy.managed_rotating.provider_unavailable`, `proxy.managed_static.invalid`, `proxy.managed_static.not_provisioned`, `proxy.name_conflict`, `proxy.not_found`, `proxy.overrides_unsupported`, `proxy.pool_not_found`, `proxy.pool_out_of_stock`, `proxy.pool_retired`, `proxy.protocol_invalid`, `proxy.protocol_unsupported`, `proxy.provider_response_invalid`, `proxy.renewal_in_progress`, `proxy.udp_protocol_unsupported`, `proxy.update_fields_invalid`, `proxy.url_invalid`, `proxy_pool.not_found`, `rate_limit.exceeded`, `rate_limited`, `recording.not_found`, `recording.run_not_ready`, `request.failed`, `request.invalid`, `request.version_unsupported`, `request.invalid_content_type`, `request.invalid_json`, `request.method_not_allowed`, `request.rate_limited`, `resource.conflict`, `resource.name_ambiguous`, `resource.name_conflict`, `resource.not_found`, `route.bad_gateway`, `route.error`, `route.not_found`, `route.timeout`, `route.unavailable`, `run.browser_host_unavailable`, `run.browser_host_unbound`, `run.browser_instance_inactive`, `run.evidence_invalid`, `run.failed`, `run.file_not_ready`, `run.file_path_conflict`, `run.file_removing`, `run.files.cursor_invalid`, `run.files_limit`, `run.live_host_unreachable`, `run.live_not_active`, `run.not_active`, `run.not_found`, `run.routing_unavailable`, `run.routing_unsupported`, `runtime.active_run_ambiguous`, `runtime.archived`, `runtime.attach_host_unreachable`, `runtime.attach_placement_changed`, `runtime.capacity_unavailable`, `runtime.connection_target_mismatch`, `runtime.connection_unavailable`, `runtime.control_conflict`, `runtime.control_invalid`, `runtime.control_unavailable`, `runtime.direct_network_disabled`, `runtime.engine_unavailable`, `runtime.event_not_stored`, `runtime.critical_event_conflict`, `runtime.graphics_unavailable`, `runtime.host_operation_failed`, `runtime.host_timeout`, `runtime.host_unavailable`, `runtime.invalid`, `runtime.not_active`, `runtime.not_executable`, `runtime.name_conflict`, `runtime.not_found`, `runtime.not_stopped`, `runtime.profile_identity_immutable`, `runtime.profile_in_use`, `runtime.profile_missing`, `runtime.profile_provisioning`, `runtime.proxy_geo_invalid`, `runtime.proxy_intent_invalid`, `runtime.proxy_invalid`, `runtime.proxy_protocol_invalid`, `runtime.proxy_required`, `runtime.proxy_unavailable`, `runtime.proxy_url_invalid`, `runtime.recording_conflict`, `runtime.required`, `runtime.resource_not_found`, `runtime.run_missing`, `runtime.stale_generation`, `runtime.start_failed`, `runtime.start_in_progress`, `runtime.start_interrupted`, `runtime.start_superseded`, `runtime.stopping`, `runtime.type_unavailable`, `runtime.webdriver_unavailable`, `runtime_file.execution_changed`, `runtime_file.no_active_run`, `runtime_file.path_invalid`, `runtime_file.runtime_unsupported`, `runtime_file.storage_path_exists`, `runtime_file.storage_workspace_forbidden`, `secrets.conflict`, `secrets.cursor_invalid`, `secrets.field_empty`, `secrets.invalid`, `secrets.no_origins`, `secrets.not_found`, `secrets.origin_invalid`, `secrets.path_denied`, `secrets.path_invalid`, `secrets.prefix_invalid`, `secrets.reference_invalid`, `secrets.reveal_forbidden`, `secrets.version_mismatch`, `secrets.version_not_found`, `segment.not_found`, `server.error`, `space.ai_default_not_allowed`, `space.default_not_deletable`, `space.deleting`, `space.error`, `space.has_active_placements`, `space.has_active_runtimes`, `space.name_conflict`, `space.not_found`, `spending_cap.reached`, `spending_cap.update_forbidden`, `space.region_invalid`, `status.invalid`, `storage.not_configured`, `storage.unavailable`, `storage_file.cursor_invalid`, `storage_file.path_exists`, `storage_file.path_invalid`, `storage_file.referenced`, `storage_file.space_unresolved`, `storage_file.too_large`, `subaccount.archived`, `subaccount.conflict`, `subaccount.not_found`, `subaccount.space_limit_reached`, `subaccount_api_key.error`, `subaccounts.access_denied`, `subaccounts.active_run_limit_exceeded`, `subaccounts.monthly_budget_exceeded`, `subaccounts.workspace_scoping_denied`, `task.not_found`, `task.not_running`, `task.runtime_limit_exceeded`, `task.run_conflict`, `task.start_intent_not_active`, `task.validation_busy`, `task.space_mismatch`, `task.scope_denied`, `task.input_request_mismatch`, `task.input_expired`, `task.input_not_requested`, `task.not_queued`, `task.credential_already_issued`, `task.credential_not_published`, `task.environment_changed`, `task.dispatch_already_committed`, `task.native_protocol`, `tool call.not_found`, `tool.builtin_immutable`, `tool.cancellation_not_supported`, `tool.catalog_changed`, `tool.context_input_forbidden`, `tool.context_invalid`, `tool.execution_mode_not_supported`, `tool.execution_unsupported`, `tool.host_failed`, `tool.host_unavailable`, `tool.implementation_change_unsupported`, `tool.implementation_unsupported`, `tool.input_invalid`, `tool.input_not_requested`, `tool.input_required`, `tool.name_conflict`, `tool.not_allowed`, `tool.not_found`, `tool.outcome_unknown`, `tool.output_invalid`, `tool.result_expired`, `tool.result_not_persisted`, `tool.revision_conflict`, `tool.revision_invalid`, `tool.revision_unavailable`, `tool.run_not_active`, `tool.runtime_mismatch`, `tool.runtime_not_allowed`, `tool.runtime_type_unsupported`, `tool.runtime_unavailable`, `tool.timed_out`, `tool.version_unavailable`, `tool_call.context_invalid`, `tool_call.cursor_invalid`, `tool_call.input_already_responded`, `tool_call.input_expired`, `tool_call.input_request_failed`, `tool_call.response_invalid`, `tool_call.response_schema_invalid`, `tool_call.scope_invalid`, `tool_call.state_invalid`, `toolset.name_conflict`, `toolset.not_found`, `toolset.tool_not_allowed`, `toolset.tool_not_found`, `upstream.unavailable`, `view.component_denied`, `view.conversation_component_required`, `view.file_capability_required`, `view.not_found`, `view.surface_unsupported_runtime`, `viewer.control_forbidden`, `viewer.control_not_held`, `viewer.download_not_found`, `viewer.gateway_url_missing`, `viewer.handoff_not_pending`, `viewer.media_not_found`, `viewer.mint_failed`, `viewer.not_found`, `viewer.recording_not_found`, `viewer.tool_inputs_forbidden`, `viewer.uploads_forbidden`, `viewer.view_shell_url_missing`, `webhook delivery.not_found`, `webhook.not_found`, `webhook.url_invalid`, `webhook.url_private`, `webhook.url_unresolvable`, `workflow.not_found`, `workflow.replay_failed`, `workflow.schema_immutable`
- `hint` (string, required) — Required actionable next step for 4xx errors; optional for server errors.
- `message` (string, required) — Human-readable description of the error.
- `reasonClass` (enum, required) — Stable public error category for programmatic branching.
  - Allowed values: `invalid_input`, `unauthorized`, `capability_denied`, `capability_limit_exceeded`, `rate_limited`, `not_found`, `conflict`, `upstream`, `server`
- `requestId` (string, required)
- `details` (map from string to any, optional) — Resource-specific structured context. Use `code` and `reasonClass` for branching.

### ComputerUseOutputImage

- `data` (string, required)
- `mimeType` ("image/jpeg", required)

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "data": {
    "action": "screenshot",
    "height": 1,
    "width": 1,
    "coordinate": [
      null
    ],
    "image": {
      "data": "string",
      "mimeType": "string"
    }
  },
  "eventId": "evt_uAAAAAAAAAAAAAAAAAAAAAA",
  "object": "string",
  "status": "succeeded"
}
```

**SDK Code**

```python
import requests

url = "https://api.bctrl.ai/v1/browsers/browserId/computer/double-click"

payload = {}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.bctrl.ai/v1/browsers/browserId/computer/double-click';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.bctrl.ai/v1/browsers/browserId/computer/double-click"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.bctrl.ai/v1/browsers/browserId/computer/double-click")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.bctrl.ai/v1/browsers/browserId/computer/double-click")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.bctrl.ai/v1/browsers/browserId/computer/double-click', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.bctrl.ai/v1/browsers/browserId/computer/double-click");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.bctrl.ai/v1/browsers/browserId/computer/double-click")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```