Skip to main content

Overview

The Cyberdesk API provides programmatic access to all platform features, enabling you to automate desktop tasks at scale. Whether you’re building custom integrations, managing fleets of machines, or orchestrating complex workflows, our API gives you full control.

OpenAPI Specification

View the complete OpenAPI specification

Base URL

All API requests should be made to:
https://api.cyberdesk.io

Authentication

Most API endpoints require authentication using Bearer tokens. Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
You can find your API key in the Cyberdesk Dashboard under Settings. The public health endpoints, /v1/health and /v1/health/db, do not require authentication.
Keep your API key secure and never expose it in client-side code or public repositories.

Core Resources

The Cyberdesk API is organized around these main resources:

Machines

Virtual or physical desktops connected via Cyberdriver

Workflows

Automation blueprints that define tasks to be executed

Runs

Instances of workflow executions on specific machines

Connections

Active connections between machines and Cyberdesk

Trajectories

Recorded sequences of actions for workflow replay

Quick Start with SDKs

While you can use the API directly, we recommend using our official SDKs for a better developer experience:

TypeScript SDK

Type-safe client with full IntelliSense support

Python SDK

Async/sync client with comprehensive type hints

Rate Limits

Authenticated API requests are subject to rate limits. When rate limiting is enabled for your environment, responses include standard headers such as X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset, and blocked requests return HTTP 429 Too Many Requests with a Retry-After header. If you have concerns about rate limits or need higher limits for your specific use case, please contact our team and we’ll work with you to find a solution.
Public endpoints such as health checks are exempt from authentication and HTTP rate limiting.

Error Handling

The API uses standard HTTP status codes to indicate success or failure:
Status CodeDescription
200Success
201Created
400Bad Request - Invalid parameters
401Unauthorized - Invalid or rejected credentials
403Forbidden - Missing credentials
404Not Found - Resource doesn’t exist
429Too Many Requests - Rate limit exceeded
500Internal Server Error
Most application errors are returned in a structured JSON body:
{
  "error": "HTTPException",
  "message": "Not authenticated",
  "error_code": null,
  "details": null,
  "timestamp": "2026-03-27T16:00:00Z"
}
Request validation errors from FastAPI use a different shape with a detail array. Check the OpenAPI schema for the exact response model used by each endpoint.

Pagination

List endpoints support pagination using skip and limit parameters:
GET /v1/runs?skip=20&limit=10
Paginated responses follow this structure:
{
  "items": [...],
  "total": 100,
  "skip": 20,
  "limit": 10
}
Many endpoints support the include query parameter to fetch related resources in a single request, following the JSON:API pattern. This reduces the number of API calls needed to get complete data.

How It Works

When you use the include parameter, related resources are returned in a separate included array in the response. The original ID fields remain unchanged for backward compatibility.
GET /v1/runs/abc-123?include=workflow,machine
Response:
{
  "id": "abc-123",
  "workflow_id": "wf-456",
  "machine_id": "mach-789",
  "status": "success",
  "included": [
    {
      "type": "workflow",
      "id": "wf-456",
      "name": "My Workflow",
      "main_prompt": "..."
    },
    {
      "type": "machine",
      "id": "mach-789",
      "name": "Desktop-1",
      "status": "connected"
    }
  ]
}

Available Includes

ResourceIncludable FieldsExample
Runworkflow, machine, machine.pools?include=workflow,machine
Trajectoryworkflow?include=workflow
Machinepools?include=pools
Poolmachines?include=machines

SDK Usage

# Get a run with related workflow and machine
run = await client.runs.get(
    "run-id",
    include=["workflow", "machine"]
)

# Access included resources
for resource in run.data.included or []:
    if resource.type == "workflow":
        print(f"Workflow: {resource.name}")
    elif resource.type == "machine":
        print(f"Machine: {resource.name}")

List Endpoints

When using include on list endpoints, related resources from all items are deduplicated:
GET /v1/runs?include=workflow
If multiple runs reference the same workflow, it only appears once in the included array.
Including many relationships on large lists can impact performance. Use sparingly for list operations.

Next Steps

Explore Endpoints

Browse all available API endpoints in the sidebar

Get Your API Key

Sign in to get your API key from the dashboard

Join Discord

Get help from our community and team