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.
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.
http://127.0.0.1:47891Authentication
Send your API key in the Authorization header. Generate or reset the key in desktop local API settings and keep it private.
Authorization: Bearer YOUR_API_KEY
Content-Type: application/jsonService status
Check service readiness before business calls. This endpoint is useful for startup health checks and retry logic.
/health{ "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.
{
"mcpServers": {
"gekkologin-local": {
"url": "http://127.0.0.1:47891/mcp",
"headers": {
"Authorization": "Bearer YOUR_LOCAL_TOKEN"
}
}
}
}{
"mcpServers": {
"gekkologin-local": {
"command": "<path-to-gekkologin-executable>",
"args": ["--mcp-stdio"]
}
}
}/v2/profilesList profiles
List local browser profile summaries and runtime status.
Path parameters
{
"ok": true,
"operationId": "profiles.list",
"requestId": "<request-id>",
"data": {
"profiles": []
}
}/v2/profilesCreate 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
name*stringRequired.accountPlatformstringOptional.notesstringOptional.tagsarrayOptional.osstringOptional.templateIdstringOptional.proxyobjectOptional.{
"name": "<name>"
}{
"ok": true,
"operationId": "profiles.create",
"requestId": "<request-id>",
"data": {
"profileId": "<profileId>",
"name": "<name>"
}
}/v2/profiles/{profileId}/launchLaunch profile
Launch a browser profile and optionally navigate its active tab.
Request fields
profileId*stringRequired.startUrlstringOptional.{
"startUrl": "<startUrl>"
}{
"ok": true,
"operationId": "profiles.launch",
"requestId": "<request-id>",
"data": {
"ok": false,
"pid": 1,
"error": "<error>"
}
}/v2/profiles/{profileId}/stopStop profile
Stop a running browser profile and release its local control session.
Request fields
profileId*stringRequired.{
"ok": true,
"operationId": "profiles.stop",
"requestId": "<request-id>",
"data": {
"ok": false,
"error": "<error>"
}
}/v2/profiles/{profileId}/environment-state/deviceGet environment-state device status
Registers this device public key if needed and returns its non-secret pairing status for an environment.
Path parameters
profileId*stringRequired.{
"ok": true,
"operationId": "environmentState.device.status",
"requestId": "<request-id>",
"data": {
"deviceId": "<deviceId>",
"keyRegistered": true,
"approved": false,
"revision": 1,
"checkpointAvailable": false
}
}/v2/profiles/{profileId}/environment-state/checkpoint/retryRetry environment state upload
Retry a durable encrypted environment checkpoint after a previous upload failure without rebuilding browser state.
Request fields
profileId*stringRequired.{
"ok": true,
"operationId": "environmentState.checkpoint.retry",
"requestId": "<request-id>",
"data": {
"ok": true,
"profileId": "<profileId>",
"revision": 1
}
}/v2/automation/agentsList automation agents
List saved RPA automation agent definitions.
Path parameters
{
"ok": true,
"operationId": "automation.agents.list",
"requestId": "<request-id>",
"data": {
"agents": []
}
}/v2/automation/runRun automation agent
Run a saved RPA agent against a local browser profile.
Request fields
agentId*stringRequired.profileId*stringRequired.{
"agentId": "<agentId>",
"profileId": "<profileId>"
}{
"ok": true,
"operationId": "automation.run",
"requestId": "<request-id>",
"data": {
"ok": false,
"runId": "<runId>",
"steps": [],
"error": "<error>"
}
}/v2/profiles/{profileId}/tabsList browser tabs
Return browser windows and tabs from the native control plane.
Path parameters
profileId*stringRequired.{
"ok": true,
"operationId": "browser.tabs.list",
"requestId": "<request-id>",
"data": {
"browsers": []
}
}/v2/profiles/{profileId}/page/snapshotGet semantic page snapshot
Return structured semantic page state with opaque node references and sensitive values redacted.
Request fields
profileId*stringRequired.tabIdstringOptional.maxNodesintegerOptional.{
"maxNodes": 1
}{
"ok": true,
"operationId": "page.snapshot",
"requestId": "<request-id>",
"data": {
"snapshotId": "<snapshotId>",
"url": "<url>",
"title": "<title>",
"nodes": [],
"nodeCount": 1,
"truncated": false
}
}/v2/profiles/{profileId}/page/screenshotCapture page screenshot
Capture the selected or active tab as a PNG without enabling remote debugging.
Request fields
profileId*stringRequired.tabIdstringOptional.maxDimensionintegerOptional.{
"maxDimension": 1
}{
"ok": true,
"operationId": "page.screenshot",
"requestId": "<request-id>",
"data": {
"mimeType": "image/png",
"width": 1,
"height": 1,
"data": "<data>"
}
}/v2/profiles/{profileId}/page/queryQuery page element
Resolve a CSS selector and return element interaction state without executing page script.
Request fields
profileId*stringRequired.tabIdstringOptional.selector*stringRequired.{
"selector": "<selector>"
}{
"ok": true,
"operationId": "page.query",
"requestId": "<request-id>",
"data": {
"found": false,
"visible": false,
"editable": false,
"tagName": "<tagName>"
}
}/v2/profiles/{profileId}/page/clickClick page element
Click an element by CSS selector or semantic snapshot node reference.
Request fields
profileId*stringRequired.tabIdstringOptional.selectorstringOptional.snapshotIdstringOptional.nodeRefstringOptional.{
"selector": "<selector>"
}{
"ok": true,
"operationId": "page.click",
"requestId": "<request-id>",
"data": {
"ok": false,
"message": "<message>"
}
}/v2/profiles/{profileId}/page/typeType into page element
Type text into an editable element using native actor actions.
Request fields
profileId*stringRequired.tabIdstringOptional.selectorstringOptional.snapshotIdstringOptional.nodeRefstringOptional.text*stringRequired.modereplace | prepend | appendOptional.pressEnterbooleanOptional.{
"selector": "<selector>",
"text": "<text>"
}{
"ok": true,
"operationId": "page.type",
"requestId": "<request-id>",
"data": {
"ok": false,
"message": "<message>"
}
}/v2/profiles/{profileId}/page/selectSelect page option
Select an option from a page control by selector or semantic node reference.
Request fields
profileId*stringRequired.tabIdstringOptional.selectorstringOptional.snapshotIdstringOptional.nodeRefstringOptional.value*stringRequired.{
"selector": "<selector>",
"value": "<value>"
}{
"ok": true,
"operationId": "page.select",
"requestId": "<request-id>",
"data": {
"ok": false,
"message": "<message>"
}
}/v2/profiles/{profileId}/page/scrollScroll page
Scroll the page or an element by a deterministic distance.
Request fields
profileId*stringRequired.tabIdstringOptional.selectorstringOptional.direction*up | down | left | rightRequired.distance*numberRequired.{
"selector": "<selector>",
"direction": "up",
"distance": 1
}{
"ok": true,
"operationId": "page.scroll",
"requestId": "<request-id>",
"data": {
"ok": false,
"message": "<message>"
}
}/v2/profiles/{profileId}/page/scroll-toScroll element into view
Scroll a selected semantic node or CSS selector into view.
Request fields
profileId*stringRequired.tabIdstringOptional.selectorstringOptional.snapshotIdstringOptional.nodeRefstringOptional.{
"selector": "<selector>"
}{
"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.
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.
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.