API reference v2

Local API documentation

GekkoLogin exposes an authenticated local HTTP interface over its native browser control plane. Use structured page snapshots and deterministic actions without enabling a remote debugging port.

Local communicationRESTful JSONNative page control

Base URL and port

After the GekkoLogin desktop client starts, the local API service listens on the following address by default. The port can be reviewed in desktop settings.

BASE URL
http://127.0.0.1:47891
The local API is available only when the desktop client is running and local API access is enabled.

Authentication

Send your API key in the Authorization header. Generate or reset the key in desktop local API settings and keep it private.

HTTP HEADER
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Service status

Check service readiness before business calls. This endpoint is useful for startup health checks and retry logic.

GET/health
Response, 200
{ "ok": true, "status": { "running": true, "host": "127.0.0.1", "port": 47891 } }

MCP

Standard MCP integration

The Desktop Agent serves stateful Streamable HTTP at /mcp. Sessions, permissions, audit, and all 18 tools are driven by the same automation contract. REST operations use /v2 exclusively.

Streamable HTTP
{
  "mcpServers": {
    "gekkologin-local": {
      "url": "http://127.0.0.1:47891/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_LOCAL_TOKEN"
      }
    }
  }
}
stdio bridge
{
  "mcpServers": {
    "gekkologin-local": {
      "command": "<path-to-gekkologin-executable>",
      "args": ["--mcp-stdio"]
    }
  }
}
GET/v2/profiles

List profiles

List local browser profile summaries and runtime status.

Path parameters

FieldTypeDescription
Response, 200
{
  "ok": true,
  "operationId": "profiles.list",
  "requestId": "<request-id>",
  "data": {
    "profiles": []
  }
}
POST/v2/profiles

Create profile

Create a new local browser environment; the server allocates its hardware template and fingerprint seed. Each environment gets its own seed, so its canvas/text-render fingerprint differs from every other environment on the same hardware. Returns the new profile id, which profiles_launch then opens.

Request fields

FieldTypeDescription
name*stringRequired.
accountPlatformstringOptional.
notesstringOptional.
tagsarrayOptional.
osstringOptional.
templateIdstringOptional.
proxyobjectOptional.
Request body
{
  "name": "<name>"
}
Response, 200
{
  "ok": true,
  "operationId": "profiles.create",
  "requestId": "<request-id>",
  "data": {
    "profileId": "<profileId>",
    "name": "<name>"
  }
}
POST/v2/profiles/{profileId}/launch

Launch profile

Launch a browser profile and optionally navigate its active tab.

Request fields

FieldTypeDescription
profileId*stringRequired.
startUrlstringOptional.
Request body
{
  "startUrl": "<startUrl>"
}
Response, 200
{
  "ok": true,
  "operationId": "profiles.launch",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "pid": 1,
    "error": "<error>"
  }
}
POST/v2/profiles/{profileId}/stop

Stop profile

Stop a running browser profile and release its local control session.

Request fields

FieldTypeDescription
profileId*stringRequired.
Response, 200
{
  "ok": true,
  "operationId": "profiles.stop",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "error": "<error>"
  }
}
GET/v2/profiles/{profileId}/environment-state/device

Get environment-state device status

Registers this device public key if needed and returns its non-secret pairing status for an environment.

Path parameters

FieldTypeDescription
profileId*stringRequired.
Response, 200
{
  "ok": true,
  "operationId": "environmentState.device.status",
  "requestId": "<request-id>",
  "data": {
    "deviceId": "<deviceId>",
    "keyRegistered": true,
    "approved": false,
    "revision": 1,
    "checkpointAvailable": false
  }
}
POST/v2/profiles/{profileId}/environment-state/checkpoint/retry

Retry environment state upload

Retry a durable encrypted environment checkpoint after a previous upload failure without rebuilding browser state.

Request fields

FieldTypeDescription
profileId*stringRequired.
Response, 200
{
  "ok": true,
  "operationId": "environmentState.checkpoint.retry",
  "requestId": "<request-id>",
  "data": {
    "ok": true,
    "profileId": "<profileId>",
    "revision": 1
  }
}
GET/v2/automation/agents

List automation agents

List saved RPA automation agent definitions.

Path parameters

FieldTypeDescription
Response, 200
{
  "ok": true,
  "operationId": "automation.agents.list",
  "requestId": "<request-id>",
  "data": {
    "agents": []
  }
}
POST/v2/automation/run

Run automation agent

Run a saved RPA agent against a local browser profile.

Request fields

FieldTypeDescription
agentId*stringRequired.
profileId*stringRequired.
Request body
{
  "agentId": "<agentId>",
  "profileId": "<profileId>"
}
Response, 200
{
  "ok": true,
  "operationId": "automation.run",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "runId": "<runId>",
    "steps": [],
    "error": "<error>"
  }
}
GET/v2/profiles/{profileId}/tabs

List browser tabs

Return browser windows and tabs from the native control plane.

Path parameters

FieldTypeDescription
profileId*stringRequired.
Response, 200
{
  "ok": true,
  "operationId": "browser.tabs.list",
  "requestId": "<request-id>",
  "data": {
    "browsers": []
  }
}
POST/v2/profiles/{profileId}/page/snapshot

Get semantic page snapshot

Return structured semantic page state with opaque node references and sensitive values redacted.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
maxNodesintegerOptional.
Request body
{
  "maxNodes": 1
}
Response, 200
{
  "ok": true,
  "operationId": "page.snapshot",
  "requestId": "<request-id>",
  "data": {
    "snapshotId": "<snapshotId>",
    "url": "<url>",
    "title": "<title>",
    "nodes": [],
    "nodeCount": 1,
    "truncated": false
  }
}
POST/v2/profiles/{profileId}/page/screenshot

Capture page screenshot

Capture the selected or active tab as a PNG without enabling remote debugging.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
maxDimensionintegerOptional.
Request body
{
  "maxDimension": 1
}
Response, 200
{
  "ok": true,
  "operationId": "page.screenshot",
  "requestId": "<request-id>",
  "data": {
    "mimeType": "image/png",
    "width": 1,
    "height": 1,
    "data": "<data>"
  }
}
POST/v2/profiles/{profileId}/page/query

Query page element

Resolve a CSS selector and return element interaction state without executing page script.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selector*stringRequired.
Request body
{
  "selector": "<selector>"
}
Response, 200
{
  "ok": true,
  "operationId": "page.query",
  "requestId": "<request-id>",
  "data": {
    "found": false,
    "visible": false,
    "editable": false,
    "tagName": "<tagName>"
  }
}
POST/v2/profiles/{profileId}/page/click

Click page element

Click an element by CSS selector or semantic snapshot node reference.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selectorstringOptional.
snapshotIdstringOptional.
nodeRefstringOptional.
Request body
{
  "selector": "<selector>"
}
Response, 200
{
  "ok": true,
  "operationId": "page.click",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "message": "<message>"
  }
}
POST/v2/profiles/{profileId}/page/type

Type into page element

Type text into an editable element using native actor actions.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selectorstringOptional.
snapshotIdstringOptional.
nodeRefstringOptional.
text*stringRequired.
modereplace | prepend | appendOptional.
pressEnterbooleanOptional.
Request body
{
  "selector": "<selector>",
  "text": "<text>"
}
Response, 200
{
  "ok": true,
  "operationId": "page.type",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "message": "<message>"
  }
}
POST/v2/profiles/{profileId}/page/select

Select page option

Select an option from a page control by selector or semantic node reference.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selectorstringOptional.
snapshotIdstringOptional.
nodeRefstringOptional.
value*stringRequired.
Request body
{
  "selector": "<selector>",
  "value": "<value>"
}
Response, 200
{
  "ok": true,
  "operationId": "page.select",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "message": "<message>"
  }
}
POST/v2/profiles/{profileId}/page/scroll

Scroll page

Scroll the page or an element by a deterministic distance.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selectorstringOptional.
direction*up | down | left | rightRequired.
distance*numberRequired.
Request body
{
  "selector": "<selector>",
  "direction": "up",
  "distance": 1
}
Response, 200
{
  "ok": true,
  "operationId": "page.scroll",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "message": "<message>"
  }
}
POST/v2/profiles/{profileId}/page/scroll-to

Scroll element into view

Scroll a selected semantic node or CSS selector into view.

Request fields

FieldTypeDescription
profileId*stringRequired.
tabIdstringOptional.
selectorstringOptional.
snapshotIdstringOptional.
nodeRefstringOptional.
Request body
{
  "selector": "<selector>"
}
Response, 200
{
  "ok": true,
  "operationId": "page.scrollTo",
  "requestId": "<request-id>",
  "data": {
    "ok": false,
    "message": "<message>"
  }
}

Appendix

Script sample

List profiles and read semantic page state through the authenticated local API.

Python, requests
import requests

base = "http://127.0.0.1:47891"
headers = {"Authorization": "Bearer YOUR_LOCAL_TOKEN"}

profiles = requests.get(f"{base}/v2/profiles", headers=headers).json()
profile_id = profiles["data"]["profiles"][0]["id"]

snapshot = requests.post(
    f"{base}/v2/profiles/{profile_id}/page/snapshot",
    headers=headers,
    json={"maxNodes": 1000},
).json()

print(snapshot["data"]["url"], snapshot["data"]["nodeCount"])

Error codes

Errors use a stable machine-readable code and include requestId for audit correlation.

CodeDescriptionAction
400 / invalid_requestThe input does not match the operation contract.Fix the fields reported in error.message.
401 / unauthorizedThe bearer token is missing or invalid.Use the current local token from the desktop client.
403 / forbiddenThe token lacks the operation permission.Grant the permission or use an authorized token.
404 / operation_not_foundThe route or operation is not available.Check the generated OpenAPI contract and Desktop Agent version.
500 / operation_failedThe native operation failed.Use requestId to correlate the desktop audit log.