API Reference

ConTree provides a REST API for managing sandboxed container execution with Git-like branching.

Base URL: https://api.contree.dev/v1

Authentication: Bearer JWT token (required for all endpoints)

Images

Manage OCI container images for sandbox execution.

List Images

GET /images

Parameters:

Name

Type

Default

Description

limit

integer

100

Number of results (1-1000)

offset

integer

0

Pagination offset

tagged

boolean

Filter by tagged images only

tag

string

Filter by tag prefix

since

string

Filter by creation time (ISO 8601 or relative: 15m, 2h, 3d)

until

string

Upper bound for creation time

Response: 200 OK — Array of Image objects

Import Image

POST /images/import

Import an OCI image filesystem from a container registry.

Request Body:

{
  "registry": "docker.io/library/python:3.12-slim",
  "credentials": {
    "username": "user",
    "password": "token"
  },
  "tag": "python-slim",
  "timeout": 300
}

Note

Only the filesystem is imported. OCI metadata (ENV, ENTRYPOINT, CMD) is not preserved.

Response: 202 Accepted with Location header pointing to the operation.

Update Image Tag

PATCH /images/{imageUUID}/tag

Request Body:

{"tag": "my-custom-tag"}

Tags are unique per account. Reassigning a tag moves it to the new image.

Response: 200 OK — Updated Image object

Remove Image Tag

DELETE /images/{imageUUID}/tag

Response: 200 OK — Image object with tag removed

Files

Upload and manage input files for sandbox execution.

Upload File

POST /files
Content-Type: application/octet-stream

<binary file content>

Response: 201 Created

{
  "uuid": "550e8400-e29b-41d4-a716-446655440000",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}

Check File Exists

HEAD /files?uuid={fileUUID}

Response: 200 OK if exists, 404 Not Found otherwise

Get File by Hash

GET /files?sha256={hash}

Response: 200 OK — FileResponse object

Instances

Spawn and manage sandbox container instances.

Spawn Instance

POST /instances

Create a new sandboxed execution instance.

Request Body:

{
  "image": "tag:python-slim",
  "command": "python /input/script.py",
  "shell": true,
  "env": {
    "PYTHONPATH": "/app"
  },
  "cwd": "/root",
  "timeout": 60,
  "files": {
    "/input/script.py": {
      "uuid": "550e8400-e29b-41d4-a716-446655440000",
      "mode": "0644"
    }
  },
  "truncate_output_at": 1048576,
  "stdin": "base64:SGVsbG8gV29ybGQ="
}

Key Parameters:

Name

Type

Default

Description

image

string

required

Image UUID or tag:name reference

command

string

required

Executable path or shell expression

shell

boolean

false

Run command through shell

env

object

Environment variables

cwd

string

/root

Working directory

timeout

integer

Max execution time in seconds

files

object

Map of paths to file UUIDs with permissions

truncate_output_at

integer

1 MiB

Output size limit (max 10 MiB)

stdin

string

Input data (ASCII or base64: prefixed)

hostname

string

Custom hostname

disposable

boolean

Auto-cleanup after execution

Response: 201 Created with Location header

{
  "uuid": "instance-uuid-here"
}

Operations

Track async operations (image imports, instance executions).

List Operations

GET /operations

Parameters:

Name

Type

Default

Description

limit

integer

100

Number of results (1-1000)

offset

integer

0

Pagination offset

status

string

Filter: PENDING, EXECUTING, SUCCESS, FAILED, CANCELLED

kind

string

Filter: image_import, instance

since

string

Time filter (ISO 8601 or relative)

until

string

Upper bound time filter

Response: 200 OK — Array of Operation objects

Get Operation Status

GET /operations/{operationId}

Response: 200 OK

{
  "id": "operation-uuid",
  "status": "SUCCESS",
  "kind": "instance",
  "created_at": "2024-01-15T10:30:00Z",
  "result": {
    "exit_code": 0,
    "stdout": {"content": "Hello World", "encoding": "ascii", "truncated": false},
    "stderr": {"content": "", "encoding": "ascii", "truncated": false},
    "cpu_time_ms": 150,
    "memory_bytes": 52428800,
    "timed_out": false
  }
}

Headers: Retry-After indicates recommended polling interval.

Cancel Operation

DELETE /operations/{operationId}

Response: 202 Accepted

Inspection

Inspect image contents and download files from executed instances.

Find Image by Tag

GET /inspect/?tag={tagName}

Response: 302 Found — Redirect to /inspect/{imageUUID}/

Get Image Metadata

GET /inspect/{imageUUID}/

Response: 200 OK

{
  "uuid": "image-uuid",
  "tag": "python-slim",
  "created_at": "2024-01-15T10:00:00Z"
}

List Directory

GET /inspect/{imageUUID}/list?path=/output

Parameters:

Name

Type

Default

Description

path

string

required

Directory path to list

text

boolean

false

Return plain text (ls-style) format

Response: 200 OK

{
  "path": "/output",
  "items": [
    {
      "name": "result.json",
      "size": 1024,
      "mode": "0644",
      "is_regular": true,
      "modified_at": "2024-01-15T10:35:00Z"
    }
  ]
}

Download File

GET /inspect/{imageUUID}/download?path=/output/result.json

Parameters:

Name

Type

Default

Description

path

string

required

File path (URL-encoded)

text

boolean

false

Force text/plain content type

Response: 200 OK — File content with appropriate Content-Type

Check Path Exists

HEAD /inspect/{imageUUID}/?path=/some/path

Response: 200 OK if exists, 404 Not Found otherwise

Error Responses

All endpoints return standard error responses:

{
  "error": "validation_error",
  "message": "Invalid image UUID format",
  "details": {}
}

Common Status Codes:

Code

Description

400

Bad Request — Invalid parameters

401

Unauthorized — Missing or invalid token

403

Forbidden — Insufficient permissions

404

Not Found — Resource doesn’t exist

409

Conflict — Operation state conflict

422

Unprocessable Entity — Invalid path

Interactive Sandbox

Try the API directly in your browser using the Swagger UI:

contree.dev/v1/

OpenAPI Specification

The complete OpenAPI specification is available at:

contree.dev/static/api.yaml