Skip to content

REST API Reference

Base URL: https://api.coldrune.com (or your self-hosted instance)

All responses use JSON. Errors follow the format:

{"error": {"code": "ERROR_CODE", "message": "Human readable description"}}

Most endpoints require one of:

  • Authorization: Bearer <session-token> — for human users
  • X-API-Key: cr_sa_... — for service accounts

Request a magic link login code.

{"email": "you@example.com"}

Returns 200 with {"message": "..."}. The 6-digit code is sent via email (or printed to server logs in dev mode).

Verify the login code and receive a session token.

{"email": "you@example.com", "code": "123456"}

Returns 200 with {"token": "..."}.

Invalidate the current session. Requires auth.

Return the authenticated user’s profile. Requires auth.

{"id": "...", "email": "you@example.com", "name": "...", "is_superadmin": false}

Create an organization. Requires auth. Caller becomes owner.

{"name": "my-org"}

List organizations the user is a member of. Superadmins see all.

Get organization details.

Rename an organization. Requires owner role.

{"name": "new-name"}

Soft-delete an organization. Requires owner role.

Invite a user to the organization. Requires admin+ role.

{"email": "alice@example.com", "role": "developer"}

Roles: owner, admin, developer, member.

List organization members.

PATCH /api/orgs/{org_name}/members/{user_id}

Section titled “PATCH /api/orgs/{org_name}/members/{user_id}”

Update a member’s role. Requires owner role.

{"role": "admin"}

DELETE /api/orgs/{org_name}/members/{user_id}

Section titled “DELETE /api/orgs/{org_name}/members/{user_id}”

Remove a member. Requires admin+ role.

Create a project. Automatically creates dev, staging, prod environments. Requires admin+ role.

{"name": "api-backend"}

List projects in the organization.

GET /api/orgs/{org_name}/projects/{project_name}

Section titled “GET /api/orgs/{org_name}/projects/{project_name}”

Get project details.

PATCH /api/orgs/{org_name}/projects/{project_name}

Section titled “PATCH /api/orgs/{org_name}/projects/{project_name}”

Rename a project. Requires admin+ role.

{"name": "new-name"}

DELETE /api/orgs/{org_name}/projects/{project_name}

Section titled “DELETE /api/orgs/{org_name}/projects/{project_name}”

Soft-delete a project. Requires admin+ role.

POST /api/orgs/{org_name}/projects/{project_name}/envs

Section titled “POST /api/orgs/{org_name}/projects/{project_name}/envs”

Create an environment. Requires admin+ role.

{"name": "qa"}

GET /api/orgs/{org_name}/projects/{project_name}/envs

Section titled “GET /api/orgs/{org_name}/projects/{project_name}/envs”

List environments in a project.

DELETE /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}

Section titled “DELETE /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}”

Delete an environment. Requires admin+ role.

PUT /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}

Section titled “PUT /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}”

Set (create or update) a secret. Requires write permission.

{"value": "s3cret"}

Returns the secret metadata with version number:

{"key": "DB_PASSWORD", "version": 2, "created_at": "...", "updated_at": "..."}

GET /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}

Section titled “GET /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}”

Get a secret’s decrypted value. Requires read permission.

{"key": "DB_PASSWORD", "value": "s3cret", "version": 2}

GET /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets

Section titled “GET /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets”

List secret keys. Values are not returned. Requires read permission.

{
  "data": [
    {"key": "DB_PASSWORD", "version": 2, "updated_at": "2026-04-01T12:00:00Z"}
  ]
}

DELETE /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}

Section titled “DELETE /api/orgs/{org_name}/projects/{project_name}/envs/{env_name}/secrets/{key}”

Soft-delete a secret. Requires write permission.

Grant an ACL rule. Upserts if the same subject + pattern combination exists. Requires admin+ role.

{
  "subject_type": "user",
  "email": "alice@example.com",
  "project_pattern": "api-*",
  "env_pattern": "*",
  "permission": "write"
}

For service accounts, use "subject_type": "service_account" and "subject_id": "<sa-id>" instead of email.

List ACL rules for the organization. Requires admin+ role.

Revoke an ACL rule. Requires admin+ role.

POST /api/orgs/{org_name}/service-accounts

Section titled “POST /api/orgs/{org_name}/service-accounts”

Create a service account. The API key is returned once and cannot be retrieved again. Requires admin+ role.

{"name": "ci-deploy", "project": "api-backend"}

project is optional. Omit to create an org-scoped service account.

Response:

{"id": "...", "name": "ci-deploy", "api_key": "cr_sa_..."}

List service accounts in the organization. Requires admin+ role.

DELETE /api/orgs/{org_name}/service-accounts/{sa_id}

Section titled “DELETE /api/orgs/{org_name}/service-accounts/{sa_id}”

Revoke a service account. Cascades soft-delete to its ACL rules. Requires admin+ role.

Query audit logs. Requires admin+ role or superadmin.

Query parameters:

ParameterDescription
actionFilter by action (e.g. secret.set, org.create)
actor_idFilter by actor ID
resource_typeFilter by resource type (e.g. secret, org)
limitMax results (1-100, default 20)
afterPagination cursor from previous response

Response:

{
  "data": [
    {
      "id": "...",
      "actor_type": "user",
      "actor_name": "alice@example.com",
      "action": "secret.set",
      "resource_type": "secret",
      "resource_id": "...",
      "org_id": "...",
      "ip_address": "203.0.113.1",
      "metadata": {"key": "DB_PASSWORD", "version": 2},
      "created_at": "2026-04-01T12:00:00Z"
    }
  ],
  "pagination": {
    "total": 142,
    "limit": 20,
    "has_next": true,
    "next_cursor": "..."
  }
}

Create a manual backup. Returns the backup metadata.

List all backups.

Restore from a backup. Downloads and decrypts the backup to {db_path}.restore.{id}. The operator must manually stop the server, swap the database file, and restart.

No authentication required.

{"status": "ok"}