Ceki.me API Documentation

Rent real browser sessions via MCP, Python SDK, JavaScript SDK, or REST API

Quick Start

Two ways to get started with Ceki — choose the path that fits your workflow.

Path A — Agent self-register via MCP

Let your AI agent register itself as a Ceki agent without any manual setup.

1. Add MCP config (no auth needed)

JSON
{
  "mcpServers": {
    "ceki": {
      "url": "https://api.ceki.me/mcp/agent"
    }
  }
}

2. Ask your agent to register

Prompt
"Register me as a Ceki agent. Name: my-agent. Email: you@example.com"

3. Agent calls register-agent

The backend sends an api_key in the response and emails a 6-digit verification code to the provided address.

4. Verify email

Prompt
"Verify my email with code 123456"

5. Reconnect MCP with auth

JSON
{
  "mcpServers": {
    "ceki": {
      "url": "https://api.ceki.me/mcp/agent",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

6. Fund your wallet

Ask your agent: "Show my wallet" (calls get-wallet). Deposit crypto to the wallet.deposit_address shown in the response.

7. Done

Status becomes active — all tools are now available. Start renting browsers.

Path B — Human via Dashboard

Register manually through the web interface and create an agent key.

  1. Register at ceki.me (email + password + OTP)
  2. Open Dashboard → Agents
  3. Click Create Agent, fill the form, copy the api_key from the dialog (shown once)
  4. Put the key in MCP config (Authorization: Bearer ag_...)
  5. Deposit crypto to the wallet address shown in Dashboard — status becomes active
JSON
{
  "mcpServers": {
    "ceki": {
      "url": "https://api.ceki.me/mcp/agent",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Python SDK

Install the SDK and start renting browsers in a few lines of code.

bash
pip install ceki-sdk
Python
import asyncio
import os
from ceki_browser import connect

async def main():
    client = await connect(os.environ["CEKI_API_KEY"])
    options = await client.search({"geo": "DE", "language": "en"})
    browser = await client.rent(options[0].schedule_id)

    await browser.navigate("https://example.com")
    snap = await browser.snapshot()
    print(snap.title)

    await browser.close()
    await client.close()

asyncio.run(main())

JavaScript SDK

Works with Node.js 18+ and modern browsers.

bash
npm install @ceki/sdk
JavaScript
import { connect } from '@ceki/sdk';

const client = await connect(process.env.CEKI_API_KEY);
const options = await client.search({ geo: 'DE', language: 'en' });
const browser = await client.rent(options[0].schedule_id);

await browser.navigate('https://example.com');
const snap = await browser.snapshot();
console.log(snap.title);

await browser.close();
await client.close();

Command-line interface

Both SDKs install a single ceki CLI on your PATH. Same command set whether you came from Python or Node.js — pick the install path that matches your stack.

Install

Python:

bash
pip install ceki-sdk

Node.js:

bash
npm install -g @ceki/sdk

After install, run ceki --help to confirm the binary is on PATH.

Environment variables

Configuration is passed via environment, not flags. Set these in your shell or .env:

VariableRequiredPurpose
CEKI_API_KEYyesAgent token (ag_...). Get via MCP register-agent tool (recommended for agents) or in Dashboard → Agents → Create Agent.
CEKI_API_URLnoOverride API base URL. Default: https://api.ceki.me.
CEKI_RELAY_URLnoOverride browser relay WebSocket URL. Default: wss://browser.ceki.me/ws/agent.
CEKI_CHAT_URLnoOverride chat-service URL.
CEKI_BASIC_AUTH_USERnoHTTP Basic Auth username (only for protected dev/stage endpoints).
CEKI_BASIC_AUTH_PASSnoHTTP Basic Auth password (only for protected dev/stage endpoints).

Quick start

Five commands to rent, drive, and shut down:

bash
export CEKI_API_KEY=ag_...

SCHEDULE=$(ceki search --limit 1 | jq -r '.[0].schedule_id')
SID=$(ceki rent --schedule $SCHEDULE | jq -r .session_id)
ceki navigate $SID https://example.com
ceki snapshot $SID -o snap.png
ceki stop $SID

The CLI persists session state locally — after rent it saves the session ID so subsequent commands resume it by SID without re-renting.

Command reference

Discovery and lifecycle

CommandWhat it does
search [--limit N] [--filter K=V]…List available browsers. Filters: country, time, price, etc.
my-browsersList browsers with pre-arranged rent contracts.
rent --schedule ID [--mode incognito|main] [--fingerprint-from FILE]Rent a browser by schedule ID. --mode main requests the host's real profile (must be pre-authorized).
sessions [--all] [--limit N] [--json]List your sessions. By default only active; --all shows ended too.
stop SIDEnd a session (releases the browser and stops billing).
wait SIDBlock until the session ends. Useful in scripts that should clean up on session expiry.

Browser control

CommandWhat it does
navigate SID URLOpen a URL in the rented browser.
click SID X YClick at viewport coordinates (X, Y in pixels).
type SID TEXT [--natural]Type text into the focused element. --natural adds human-like delays.
scroll SID X Y DYScroll from origin (X, Y) by DY pixels (negative = down).
screenshot SID -o FILE [--format png|jpeg] [--full]Save a viewport (or --full page) screenshot to a file.
snapshot SID -o FILESame as screenshot plus the latest unread chat messages from the host.
switch-tab SIDSwitch active browser tab.
upload SID --selector CSS --file PATH [--filename NAME]Attach a file to an input[type=file] by CSS selector.

Chat with host

CommandWhat it does
chat SID send TEXTSend a text message to the host.
chat SID next [--timeout SEC]Block until the next host message arrives, or timeout.
chat SID history [--since TS] [--limit N]Fetch past chat messages (Unix-ts or ISO-8601 --since).
chat SID send-image --image PATH [--text MSG]Send an image (with optional preceding text) to the host.

Advanced

CommandWhat it does
profile SID export -o FILE [--domains CSV] [--no-session-storage]Export cookies / localStorage / sessionStorage to JSON. Filter by --domains a.com,b.com.
profile SID import -i FILEImport a previously exported profile into the session.
request-captcha SID [--acceptance SEC] [--completion SEC] [--manual]Ask the host to solve a CAPTCHA. --manual disables auto-accept so the agent votes explicitly.
configure SID [--masking-mode VAL] [--fingerprint VAL]Toggle masking / fingerprint at runtime.
cdp SID --method METHOD [--params JSON]Send a raw Chrome DevTools Protocol command. Escape hatch for anything the high-level API doesn't cover.

Output and errors

Successful commands write a single JSON line to stdout. Errors go to stderr as JSON with "error" and "code" fields. Pipe stdout into jq to chain commands in scripts.

Exit codes

CodeMeaning
0success
1generic error
2CEKI_API_KEY not set
3session not found or you are not the owner
4timeout (CAPTCHA acceptance, chat next, etc.)
5network / connection error
130interrupted (Ctrl-C)

REST API

Direct HTTP access for any language or platform.

Rent a session

HTTP
POST /api/sessions/rent
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "geo": "DE",
  "duration": 300,
  "budget": 0.50
}

Response

JSON
{
  "session_id": "sess_abc123",
  "ws_url": "wss://browser.ceki.me/ws/sess_abc123",
  "host_geo": "DE",
  "rate_per_min": 0.05,
  "expires_at": "2026-04-30T15:05:00Z"
}

Endpoints

MethodEndpointDescription
POST/api/sessions/rentRent a browser session
POST/api/sessions/{id}/navigateNavigate to URL
POST/api/sessions/{id}/clickClick element by selector
POST/api/sessions/{id}/fillFill form fields
POST/api/sessions/{id}/extractExtract data by selector
POST/api/sessions/{id}/screenshotTake screenshot
DELETE/api/sessions/{id}End session
GET/api/geolocationsList available geolocations
WS/ws/{session_id}Real-time WebSocket control

MCP Protocol

Ceki natively supports the Model Context Protocol — the open standard for connecting AI agents to external tools. Works with Claude, GPT, LangChain, and any MCP-compatible agent.

Configuration

Add Ceki to your agent's MCP config (same as Quick Start):

JSON
{
  "mcpServers": {
    "ceki": {
      "url": "https://api.ceki.me/mcp/agent",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Available Tools

ToolDescription
rent_browserRent a real browser session in a specific geolocation
navigateNavigate the browser to a URL
clickClick an element by CSS selector
fillFill form fields with values
extractExtract text/data from the page using selectors
screenshotTake a screenshot of the current page
closeClose the browser session and release resources

Example Agent Conversation

Dialog
User: "Rent a browser in Germany and check the price on example.com"

Agent: [calls rent_browser(geo="DE", duration=60)]
  -> Session sess_abc123 ready

Agent: [calls navigate(url="https://example.com")]
  -> Page loaded, title: "Example Domain"

Agent: [calls extract(selector=".price")]
  -> Extracted: "$29.99"

Agent: [calls close()]
  -> Session ended

Agent: "The price on example.com is $29.99 (checked from a German IP)."

Authentication

All API requests require a Bearer token in the Authorization header.

HTTP Header
Authorization: Bearer YOUR_API_KEY

Getting Your API Key

Option 1 (MCP): Call the public register-agent MCP tool — see Quick Start above for the full flow.

Option 2 (Dashboard): Sign up at ceki.me, then go to Dashboard → Agents → Create Agent. The api_key is shown once — copy it immediately.

Security: Never expose your API key in client-side code. Use environment variables or a secrets manager.

Webhooks

Receive real-time notifications about session events via HTTP webhooks.

Events

EventDescription
session.startedA new browser session has been created and is ready
session.endedSession completed or timed out
session.errorAn error occurred during session execution

Payload Example

JSON
{
  "event": "session.ended",
  "session_id": "sess_abc123",
  "timestamp": "2026-04-30T15:05:00Z",
  "data": {
    "duration_seconds": 47,
    "total_cost": 0.24,
    "host_geo": "DE",
    "pages_visited": 3
  }
}
Configure webhooks in Dashboard → Settings → Webhooks. Each webhook URL receives a POST request with JSON payload.