> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cyberdesk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> Complete reference for all Cyberdesk API endpoints

## 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.

<Card title="OpenAPI Specification" icon="file-code" href="https://api.cyberdesk.io/openapi.json">
  View the complete OpenAPI specification
</Card>

## 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:

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

You can find your API key in the [Cyberdesk Dashboard](https://cyberdesk.io/dashboard) under Settings.

The public health endpoints, `/v1/health` and `/v1/health/db`, do not require authentication.

<Warning>
  Keep your API key secure and never expose it in client-side code or public repositories.
</Warning>

## Core Resources

The Cyberdesk API is organized around these main resources:

<CardGroup cols={2}>
  <Card title="Machines" icon="desktop">
    Virtual or physical desktops connected via Cyberdriver
  </Card>

  <Card title="Workflows" icon="diagram-project">
    Automation blueprints that define tasks to be executed
  </Card>

  <Card title="Runs" icon="play">
    Instances of workflow executions on specific machines
  </Card>

  <Card title="Connections" icon="plug">
    Active connections between machines and Cyberdesk
  </Card>

  <Card title="Trajectories" icon="route">
    Recorded sequences of actions for workflow replay
  </Card>
</CardGroup>

## Quick Start with SDKs

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

<CardGroup cols={2}>
  <Card title="TypeScript SDK" icon="js" href="/sdk-guides/typescript">
    Type-safe client with full IntelliSense support
  </Card>

  <Card title="Python SDK" icon="python" href="/sdk-guides/python">
    Async/sync client with comprehensive type hints
  </Card>
</CardGroup>

## Rate Limits

Authenticated API requests are subject to rate limits. Dashboard-authenticated JWT traffic uses a 60-second fixed window with default limits of `480` requests per user and `4000` requests per organization. These dashboard JWT limits are enforced internally and do not expose public `X-RateLimit-*` headers.

Public API key traffic uses separate rate-limit buckets. When those limits are 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](mailto:founders@cyberdesk.io) and we'll work with you to find a solution.

<Note>
  Public endpoints such as health checks are exempt from authentication and HTTP rate limiting.
</Note>

## Error Handling

The API uses standard HTTP status codes to indicate success or failure:

| Status Code | Description                                    |
| ----------- | ---------------------------------------------- |
| 200         | Success                                        |
| 201         | Created                                        |
| 400         | Bad Request - Invalid parameters               |
| 401         | Unauthorized - Invalid or rejected credentials |
| 403         | Forbidden - Missing credentials                |
| 404         | Not Found - Resource doesn't exist             |
| 429         | Too Many Requests - Rate limit exceeded        |
| 500         | Internal Server Error                          |

Most application errors are returned in a structured JSON body:

```json theme={null}
{
  "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:

```bash theme={null}
GET /v1/runs?skip=20&limit=10
```

Paginated responses follow this structure:

```json theme={null}
{
  "items": [...],
  "total": 100,
  "skip": 20,
  "limit": 10
}
```

## Including Related Resources

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.

```bash theme={null}
GET /v1/runs/abc-123?include=workflow,machine
```

Response:

```json theme={null}
{
  "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

| Resource   | Includable Fields                      | Example                     |
| ---------- | -------------------------------------- | --------------------------- |
| Run        | `workflow`, `machine`, `machine.pools` | `?include=workflow,machine` |
| Trajectory | `workflow`                             | `?include=workflow`         |
| Machine    | `pools`                                | `?include=pools`            |
| Pool       | `machines`                             | `?include=machines`         |

### SDK Usage

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    # 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}")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={null}
    // Get a run with related workflow and machine
    const { data: run } = await client.runs.get("run-id", {
      include: ["workflow", "machine"]
    });

    // Access included resources
    for (const resource of run.included || []) {
      if (resource.type === "workflow") {
        console.log(`Workflow: ${resource.name}`);
      } else if (resource.type === "machine") {
        console.log(`Machine: ${resource.name}`);
      }
    }
    ```
  </Tab>
</Tabs>

### List Endpoints

When using `include` on list endpoints, related resources from all items are deduplicated:

```bash theme={null}
GET /v1/runs?include=workflow
```

If multiple runs reference the same workflow, it only appears once in the `included` array.

<Note>
  Including many relationships on large lists can impact performance. Use sparingly for list operations.
</Note>

## Next Steps

<CardGroup>
  <Card title="Explore Endpoints" icon="terminal">
    Browse all available API endpoints in the sidebar
  </Card>

  <Card title="Get Your API Key" icon="key" href="https://cyberdesk.io/dashboard">
    Sign in to get your API key from the dashboard
  </Card>

  <Card title="Join Discord" icon="discord" href="https://discord.gg/ws5ddx5yZ8">
    Get help from our community and team
  </Card>
</CardGroup>
