API Reference
The CMDOP REST API (the control plane) provides programmatic access to manage sessions, machines, commands, files, schedules, and webhooks. Authenticate with a Bearer token and receive JSON responses. Self-hosted is the shipping deployment — send requests to your own instance. The hosted api.cmdop.com base URL and tiered rate limits below describe the planned managed cloud, which is not yet available. The official SDKs are recommended over raw API calls.
What is the base URL?
For a self-hosted instance (the shipping path), use your own host:
https://your-domain.com/api/v1The hosted base URL https://api.cmdop.com/v1 belongs to the planned managed cloud, which is not yet available. The examples on this page use it for illustration — point them at your self-hosted control plane today. See Pricing & editions.
How do I authenticate?
All requests require an API key as a Bearer token. CMDOP API keys are issued in the form cmdop_apikey_<random>:
# Include the API key as a Bearer token in the Authorization header
curl https://your-domain.com/api/v1/sessions \
-H "Authorization: Bearer cmdop_apikey_..."Create an API key with the CLI (cmdop auth create-key) or from your control plane’s API-keys settings.
What is the response format?
All responses are JSON:
{
"data": { ... },
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-02-14T10:30:00Z"
}
}What does a success response look like?
{
"data": {
"session_id": "sess_abc123",
"status": "CONNECTED"
}
}What does an error response look like?
{
"error": {
"code": "session_not_found",
"message": "Session not found",
"details": {
"session_id": "sess_invalid"
}
}
}What HTTP status codes does the API return?
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content |
| 400 | Bad Request — Invalid parameters |
| 401 | Unauthorized — Invalid or missing API key |
| 403 | Forbidden — No permission |
| 404 | Not Found — Resource doesn’t exist |
| 409 | Conflict — Resource already exists |
| 422 | Unprocessable — Validation failed |
| 429 | Rate Limited — Too many requests |
| 500 | Server Error — Internal error |
| 503 | Service Unavailable — Temporary outage |
What are the rate limits?
Per-tier rate limits apply to the planned managed cloud and are not yet enforced. A self-hosted instance imposes no enforced API rate caps. The numbers below describe the intended managed offering, not a live product. See Pricing & editions.
Intended managed-cloud limits (planned, not live):
| Tier (planned) | Requests/minute |
|---|---|
| Free | 100 |
| Pro | 1,000 |
| Enterprise | 10,000 |
When rate limiting is in effect, responses carry headers:
X-RateLimit-Limit: 1000 # Max requests per window
X-RateLimit-Remaining: 999 # Requests remaining
X-RateLimit-Reset: 1707903600 # Unix timestamp when limit resetsWhen rate limited (429):
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"details": {
"retry_after": 60
}
}
}How does pagination work?
List endpoints support pagination:
# Paginate with limit (page size) and offset (skip count)
curl "https://api.cmdop.com/v1/sessions?limit=10&offset=0"Parameters:
| Parameter | Default | Max |
|---|---|---|
limit | 20 | 100 |
offset | 0 | — |
Response:
{
"data": [...],
"meta": {
"total": 45,
"limit": 10,
"offset": 0,
"has_more": true
}
}How do I filter results?
Many endpoints support filtering:
# Filter by status
curl "https://api.cmdop.com/v1/sessions?status=CONNECTED"
# Filter by machine
curl "https://api.cmdop.com/v1/sessions?machine_hostname=prod-server"
# Multiple filters
curl "https://api.cmdop.com/v1/sessions?status=CONNECTED&machine_hostname=prod-server"How do I sort results?
# Sort by created date (descending)
curl "https://api.cmdop.com/v1/sessions?sort=-created_at"
# Sort by hostname (ascending)
curl "https://api.cmdop.com/v1/machines?sort=hostname"What endpoints are available?
Sessions
| Method | Endpoint | Description |
|---|---|---|
| GET | /sessions | List sessions |
| GET | /sessions/:id | Get session |
| POST | /sessions/:id/attach | Attach to session |
| POST | /sessions/:id/detach | Detach from session |
Machines
| Method | Endpoint | Description |
|---|---|---|
| GET | /machines | List machines |
| GET | /machines/:id | Get machine |
| DELETE | /machines/:id | Remove machine |
Commands
| Method | Endpoint | Description |
|---|---|---|
| POST | /commands | Execute command |
| GET | /commands/:id | Get command result |
Files
| Method | Endpoint | Description |
|---|---|---|
| GET | /files | List files |
| GET | /files/content | Read file |
| PUT | /files/content | Write file |
| DELETE | /files | Delete file |
Webhooks
| Method | Endpoint | Description |
|---|---|---|
| GET | /webhooks | List webhooks |
| POST | /webhooks | Create webhook |
| DELETE | /webhooks/:id | Delete webhook |
Are there official SDKs available?
We recommend using official SDKs instead of raw API:
- Python SDK — Full-featured async SDK
- CLI — Command-line access
How do I use real-time streaming?
For real-time streaming, use the gRPC API via SDK.