Skip to Content
ProjectsOverview

Projects

A project is a named container for your code and runtime. You push a code tarball, Computalot publishes the revision immediately, and then jobs trigger runtime preparation on demand.

For platform-provided compute primitives that don’t require your own code, use Sealed Recipes instead.

Lifecycle

POST /api/v1/projects → create POST /api/v1/projects/:name/push → upload code tarball POST /api/v1/jobs → submit work POST /api/v1/projects/:name/init → optional: prepare currently available workers GET /api/v1/projects/:name/status → inspect published vs warm state

GET /api/v1/projects/:name/status is the top-level truth for the active revision. After push publishes the current content hash, you can submit jobs with "project": "my-project" immediately. ready_for_jobs: true just means the active revision is already warm.

Quick Example

# 1. Create curl -sS "$BASE_URL/api/v1/projects" \ -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "my-project", "remote_dir": "/root/my-project"}' # 2. Upload (raw binary, NOT multipart) tar czf code.tar.gz Dockerfile computalot.project.json script.py curl -sS "$BASE_URL/api/v1/projects/my-project/push" \ -X POST -H "Authorization: Bearer $TOKEN" --data-binary @code.tar.gz # 3. Submit work immediately if you want curl -sS "$BASE_URL/api/v1/jobs" \ -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "structured_runner", "runner_command": ["python3", "script.py"], "payload": {"test": true}, "project": "my-project", "timeout_s": 120}' # 4. Optional: prepare currently available workers ahead of time curl -sS "$BASE_URL/api/v1/projects/my-project/init" \ -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{}'

How It Works

Projects run as sandboxed OCI containers. Push a tarball with your code, a Dockerfile, and a computalot.project.json manifest. Computalot builds a container image and runs tasks in a sandboxed environment.

See Project Manifest for the manifest schema and Setup for the init flow.

If your project runs long ML or evaluation jobs, declare immutable model/dataset inputs in data_sources, declare writable package/model caches in cache_mounts, and enable resumable checkpoints on the jobs themselves. Do not assume runner-side downloads are reused automatically across tasks.

Updating Code

Push a new tarball. The new revision is published immediately; future jobs on that revision may cold-start once while runtime preparation catches up. Use invalidate only if you want to discard old prepared runtimes, and use init only if you want to prepare currently available workers ahead of time:

tar czf code.tar.gz . curl -sS "$BASE_URL/api/v1/projects/my-project/push" \ -X POST -H "Authorization: Bearer $TOKEN" --data-binary @code.tar.gz curl -sS "$BASE_URL/api/v1/projects/my-project/invalidate" \ -X POST -H "Authorization: Bearer $TOKEN" curl -sS "$BASE_URL/api/v1/projects/my-project/init" \ -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d '{}'

Use PUT /api/v1/projects/:name for metadata-only changes. A successful POST /push updates the latest content hash immediately, marks the new revision published but not yet warm, and can include tarball_diff (added_files, removed_files, changed_files) when the previous tarball is available locally. If POST /push returns 409, wait for the current refresh to finish and retry.

Readiness

  • can_accept_new_jobs: true means the latest project revision is published and jobs can be submitted now
  • ready_for_jobs: true means the active revision is already warm enough to admit work without waiting for runtime preparation
  • It does not prove your application-level imports or credentials are valid — use manifest validation checks for that
  • After a successful push, expect can_accept_new_jobs: true and often ready_for_jobs: false while the first job or an optional /init prepares runtime
  • Use GET /api/v1/projects/:name/status/details when status_message is not enough — it adds sanitized diagnostics, log tails, and recovery guidance
  • Run one small smoke job after setup changes before submitting a large batch

Recovery

If setup fails or the runtime state becomes stale:

  1. GET /api/v1/projects/:name/status to confirm the active revision is not ready
  2. GET /api/v1/projects/:name/status/details for sanitized diagnostics plus the recommended next step
  3. Fix your project, push a new tarball if needed, then POST /api/v1/projects/:name/invalidate
  4. Submit a small job normally, or call POST /api/v1/projects/:name/init if you specifically want to prepare currently available workers ahead of time

Endpoints

MethodPathDescription
POST/api/v1/projectsCreate a project
GET/api/v1/projectsList your projects
GET/api/v1/projects/:nameProject config + readiness
PUT/api/v1/projects/:nameUpdate project metadata (not code)
DELETE/api/v1/projects/:nameDelete project (blocked if active jobs)
POST/api/v1/projects/:name/pushUpload code tarball
POST/api/v1/projects/:name/initPrepare currently available workers
PUT/api/v1/projects/:name/cancel-queuedCancel queued/planning jobs
POST/api/v1/projects/:name/invalidateMark for re-init
GET/api/v1/projects/:name/statusCheck readiness
GET/api/v1/projects/:name/status/detailsDiagnostics for setup issues
PUT/api/v1/projects/:name/kv/:keyWrite project-scoped shared state
GET/api/v1/projects/:name/kv/:keyRead project-scoped shared state
DELETE/api/v1/projects/:name/kv/:keyDelete project-scoped shared state
GET/api/v1/projects/:name/streamSSE stream for all jobs in project
Last updated on