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 ^^^^^^^^^^^ .. code-block:: text 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 ^^^^^^^^^^^^ .. code-block:: text POST /images/import Import an OCI image filesystem from a container registry. **Request Body:** .. code-block:: json { "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 ^^^^^^^^^^^^^^^^ .. code-block:: text PATCH /images/{imageUUID}/tag **Request Body:** .. code-block:: json {"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 ^^^^^^^^^^^^^^^^ .. code-block:: text DELETE /images/{imageUUID}/tag **Response:** ``200 OK`` — Image object with tag removed Files ----- Upload and manage input files for sandbox execution. Upload File ^^^^^^^^^^^ .. code-block:: text POST /files Content-Type: application/octet-stream **Response:** ``201 Created`` .. code-block:: json { "uuid": "550e8400-e29b-41d4-a716-446655440000", "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" } Check File Exists ^^^^^^^^^^^^^^^^^ .. code-block:: text HEAD /files?uuid={fileUUID} **Response:** ``200 OK`` if exists, ``404 Not Found`` otherwise Get File by Hash ^^^^^^^^^^^^^^^^ .. code-block:: text GET /files?sha256={hash} **Response:** ``200 OK`` — FileResponse object Instances --------- Spawn and manage sandbox container instances. Spawn Instance ^^^^^^^^^^^^^^ .. code-block:: text POST /instances Create a new sandboxed execution instance. **Request Body:** .. code-block:: json { "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 .. code-block:: json { "uuid": "instance-uuid-here" } Operations ---------- Track async operations (image imports, instance executions). List Operations ^^^^^^^^^^^^^^^ .. code-block:: text 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 ^^^^^^^^^^^^^^^^^^^^ .. code-block:: text GET /operations/{operationId} **Response:** ``200 OK`` .. code-block:: json { "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 ^^^^^^^^^^^^^^^^ .. code-block:: text DELETE /operations/{operationId} **Response:** ``202 Accepted`` Inspection ---------- Inspect image contents and download files from executed instances. Find Image by Tag ^^^^^^^^^^^^^^^^^ .. code-block:: text GET /inspect/?tag={tagName} **Response:** ``302 Found`` — Redirect to ``/inspect/{imageUUID}/`` Get Image Metadata ^^^^^^^^^^^^^^^^^^ .. code-block:: text GET /inspect/{imageUUID}/ **Response:** ``200 OK`` .. code-block:: json { "uuid": "image-uuid", "tag": "python-slim", "created_at": "2024-01-15T10:00:00Z" } List Directory ^^^^^^^^^^^^^^ .. code-block:: text 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`` .. code-block:: json { "path": "/output", "items": [ { "name": "result.json", "size": 1024, "mode": "0644", "is_regular": true, "modified_at": "2024-01-15T10:35:00Z" } ] } Download File ^^^^^^^^^^^^^ .. code-block:: text 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 ^^^^^^^^^^^^^^^^^ .. code-block:: text HEAD /inspect/{imageUUID}/?path=/some/path **Response:** ``200 OK`` if exists, ``404 Not Found`` otherwise Error Responses --------------- All endpoints return standard error responses: .. code-block:: json { "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 `_