Skip to content

Latest commit

 

History

History
299 lines (209 loc) · 5.14 KB

File metadata and controls

299 lines (209 loc) · 5.14 KB

REST API

Overview

The REST API runs on a separate port (default 8080) alongside the gRPC server (port 50051). Built with axum, it provides management endpoints for projects, sessions, health checks, and real-time events via SSE.

OpenAPI 3.x spec is available at runtime: GET /api/v1/openapi.json

Authentication

All /api/v1/* endpoints (except /api/v1/openapi.json) require authentication.

Authorization: Bearer <token>

Rate limiting is enforced per client IP. Exceeding the limit returns:

HTTP 429 Too Many Requests
Retry-After: <seconds>

Public endpoints (no auth): /healthz, /api/v1/openapi.json

Endpoints

Health & Monitoring

GET /healthz

Liveness probe. No auth required.

200 OK
"ok"

GET /api/v1/health

Detailed health check with system metrics.

{
  "version": "0.1.0",
  "api_version": "v1",
  "uptime_seconds": 3600,
  "sessions": 5,
  "docker": true,
  "disk": {
    "total_bytes": 500107862016,
    "available_bytes": 250000000000
  },
  "memory": {
    "total_bytes": 17179869184,
    "used_bytes": 8589934592
  }
}

GET /api/v1/metrics

System metrics.

{
  "uptime_seconds": 3600,
  "active_sessions": 5,
  "max_sessions": 50,
  "memory": {
    "total_bytes": 17179869184,
    "used_bytes": 8589934592
  }
}

Projects

POST /api/v1/projects

Create a project (starts git clone).

Request:

{
  "name": "my-project",
  "git_url": "https://github.com/user/repo.git"
}

Response: 201 Created

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "my-project",
  "git_url": "https://github.com/user/repo.git",
    "default_image": null,
  "state": "cloning",
  "created_at": "2026-04-13T10:00:00Z",
  "updated_at": "2026-04-13T10:00:00Z"
}

Errors:

  • 400 — invalid URL or SSRF validation failure
  • 409 — project with this git_url already exists

GET /api/v1/projects

List all projects.

Response: 200 OK

[
  {
    "id": "...",
    "name": "my-project",
    "git_url": "https://github.com/user/repo.git",
    "default_image": null,
    "state": "ready",
    "created_at": "...",
    "updated_at": "..."
  }
]

GET /api/v1/projects/{id}

Get project by ID.

Response: 200 OK — project object, or 404 Not Found

DELETE /api/v1/projects/{id}

Delete a project and its data.

Response: 204 No Content, or 404 Not Found

POST /api/v1/projects/{id}/retry

Retry a failed clone.

Response: 200 OK — updated project object Errors:

  • 404 — project not found
  • 409 — project is not in failed state

Sessions

POST /api/v1/projects/{project_id}/sessions

Create a session within a project.

Request:

{
  "profile": "claude-default"
}

{


**Errors:**
- `404` — project not found
- `409` — project not in `ready` state
- `429` — session limit reached for this project

#### `GET /api/v1/projects/{project_id}/sessions`

List sessions for a specific project.

#### `GET /api/v1/sessions`

List all sessions globally. Supports pagination:
- `?limit=20` — max results (default: 20)
- `?offset=0` — skip N results

#### `GET /api/v1/sessions/{id}`

Get session by ID.

**Response:** `200 OK`
```json
{
  "id": "...",
  "project_id": "...",
  "container_id": "abc123def456",
  "state": "running",
  "profile": "claude-default",
  "created_at": "...",
  "updated_at": "...",
  "stopped_at": null,
  "error_reason": null
}

POST /api/v1/sessions/{id}/stop

Stop a running session.

Response: 200 OK — updated session object Errors: 404, 409 (not in stoppable state)

POST /api/v1/sessions/{id}/resume

Resume a stopped session.

Response: 200 OK — updated session object Errors: 404, 409 (not in stopped state)

POST /api/v1/sessions/{id}/retry

Retry a failed session.

Response: 200 OK — updated session object Errors: 404, 409 (not in failed state)

DELETE /api/v1/sessions/{id}

Delete a session record. Container is stopped and removed if still running.

Response: 204 No Content

Docker Resources

GET /api/v1/images

List available Docker images.

Response: 200 OK

[
  {
    "reference": "ubuntu:24.04",
    "is_default": true
  }
]

GET /api/v1/profiles

List configured session profiles.

Response: 200 OK

[
  {
    "name": "claude-default",
    "init_command": null,
    "env_vars": { "NODE_ENV": "production" }
  }
]

Events

GET /api/v1/events

Server-Sent Events stream. See SSE Events.

Error Format

All errors return a JSON envelope:

{
  "error": "Human-readable error message"
}

HTTP status mapping from RelayError:

Error type Status
NotFound 404
Auth 403
SessionLimit 429
Config, Git 400
Database, Docker 500

Audit Logging

All mutating requests (POST, PUT, PATCH, DELETE) are logged with:

  • HTTP method
  • Request path
  • Source IP
  • Response status code

Source: runner/src/rest_api.rs, runner/src/rest_handlers/