Skip to content

API Reference

All API endpoints require authentication via a Bearer token, unless noted otherwise.

Terminal window
Authorization: Bearer kod_your_token

Health check endpoint. No authentication required.

Response: 200

{ "status": "ok" }

List all repositories. Requires repo:read.

Response: 200

[
{
"name": "my-project",
"createdAt": 1706234567890,
"path": "/root/.kod/repos/my-project.git",
"ownerTokenId": "abc123",
"protectedBranches": []
}
]

Create a new repository. Requires repo:write.

Request:

{ "name": "my-project" }

Response: 201

Import a local or remote Git repository with git clone --mirror. Requires repo:write.

Request:

{
"source": "https://github.com/example/project.git",
"name": "project"
}

name is optional. If omitted, Kod derives it from the source URL/path.

Response: 201

Get repository details. Requires repo:read.

Response: 200

Update a repository (e.g., rename). Requires repo:write.

Request:

{ "name": "new-name" }

Response: 200

Delete a repository. Requires repo:delete.

Response: 204

Protected branches can only be pushed by the repository owner or an admin token. Collaborator tokens with repo:write are rejected by the Git pre-receive hook.

List protected branches. Requires repo:read.

Response: 200

{ "branches": ["main"] }

PUT /repos/:name/protections/branches/:branch

Section titled “PUT /repos/:name/protections/branches/:branch”

Protect a branch. Requires repo:write and repository owner or admin access.

Response: 200

DELETE /repos/:name/protections/branches/:branch

Section titled “DELETE /repos/:name/protections/branches/:branch”

Remove branch protection. Requires repo:write and repository owner or admin access.

Response: 200

List collaborators for a repository. Requires collaborator:read.

Response: 200

{
"repoName": "my-project",
"collaborators": ["alice", "bob"]
}

Add a collaborator. Requires collaborator:write.

Request:

{ "username": "alice" }

Response: 201

DELETE /repos/:name/collaborators/:username

Section titled “DELETE /repos/:name/collaborators/:username”

Remove a collaborator. Requires collaborator:write.

Response: 204

Trigger a workflow. Requires workflow:trigger.

Request:

{
"branch": "main",
"files": [".kod/workflows/build.toml"]
}

files is optional — if omitted, all workflow files in .kod/workflows/ are executed. Explicit workflow files must stay inside .kod/workflows/.

Response: 202

{ "id": "abc123xyz456", "status": "queued" }

List workflow runs for a repository. Requires workflow:read.

Response: 200

[
{
"id": "abc123xyz456",
"repoName": "my-project",
"branch": "main",
"status": "completed",
"startedAt": 1706234567890,
"completedAt": 1706234600000,
"result": {
"success": true,
"duration": 32110,
"steps": [
{
"name": "test",
"success": true,
"output": "All tests passed",
"duration": 12000
}
]
}
}
]

Get a specific workflow run. Requires workflow:read.

Response: 200

List secrets for a repository (names and metadata only). Requires secrets:read.

Response: 200

[
{
"name": "DEPLOY_TOKEN",
"repoName": "my-project",
"createdAt": 1706234567890,
"updatedAt": 1706234567890
}
]

Create or update a secret. Requires secrets:write. Requires an encryption key to be configured on the server.

Secret names must be valid environment variable names (letters, digits, underscores, starting with a letter or underscore).

Request:

{ "value": "my-secret-value" }

Response: 200

{
"name": "DEPLOY_TOKEN",
"repoName": "my-project",
"message": "Secret saved"
}

Delete a secret. Requires secrets:write.

Response: 204

List webhooks. Requires webhook:read and repository owner or admin access.

Response: 200

[
{
"id": "abc123xyz456",
"repoName": "my-project",
"url": "https://example.com/hook",
"events": ["push", "workflow"],
"createdAt": 1706234567890
}
]

Secrets are never returned.

Create a webhook. Requires webhook:write and repository owner or admin access.

Request:

{
"url": "https://example.com/hook",
"events": ["push", "workflow"],
"secret": "optional-signing-secret"
}

Response: 201

Delete a webhook. Requires webhook:write and repository owner or admin access.

Response: 204

List webhook delivery history. Requires webhook:read and repository owner or admin access.

Response: 200

[
{
"id": "delivery123",
"webhookId": "abc123xyz456",
"repoName": "my-project",
"event": "push",
"url": "https://example.com/hook",
"status": "success",
"attempts": 1,
"maxAttempts": 4,
"createdAt": 1706234567890,
"lastAttemptAt": 1706234568000,
"responseStatus": 204
}
]

POST /repos/:name/webhooks/:id/deliveries/:deliveryId/retry

Section titled “POST /repos/:name/webhooks/:id/deliveries/:deliveryId/retry”

Retry a webhook delivery immediately. Requires webhook:write and repository owner or admin access.

Response: 202

List SSH public keys for the authenticated token’s username. Admin tokens can pass ?username=alice.

Response: 200

[
{
"id": "key123",
"username": "alice",
"name": "laptop",
"publicKey": "ssh-ed25519 AAAA...",
"keyType": "ssh-ed25519",
"fingerprint": "SHA256:abc...",
"createdAt": 1706234567890
}
]

Add an SSH public key for the authenticated token’s username. Admin tokens can pass username.

Request:

{
"publicKey": "ssh-ed25519 AAAA... alice@laptop",
"name": "laptop",
"username": "alice"
}

Response: 201

Remove an SSH public key. Users can remove their own keys; admins can remove any key.

Response: 204

List all API tokens. Requires admin.

Response: 200

[
{
"id": "abc123",
"name": "ci-deploy",
"createdAt": 1706234567890,
"lastUsedAt": 1706234600000,
"permissions": ["repo:read", "workflow:trigger"]
}
]

Create a new API token. Requires admin.

Request:

{
"name": "ci-deploy",
"permissions": ["repo:read", "workflow:trigger", "webhook:read"],
"expiresInDays": 30,
"username": "alice"
}

All fields except name are optional. Default permissions: ["repo:read", "repo:write"].

Response: 201

{
"id": "abc123",
"name": "ci-deploy",
"token": "kod_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
"permissions": ["repo:read", "workflow:trigger"],
"expiresAt": 1709826567890,
"message": "Save this token - it will not be shown again"
}

Delete a token. Requires admin. You cannot delete your own token.

Response: 204

Kod serves Git over HTTP at /repos/:name.git. Authenticate using HTTP Basic Auth with your API token as the password:

Terminal window
git clone http://localhost:3000/repos/my-project.git
# Username: git (or anything)
# Password: your API token

Kod can serve Git over SSH on KOD_SSH_PORT (default 2222). SSH authentication uses public keys added with POST /keys or kod keys add.

Terminal window
git clone ssh://kod@host:2222/my-project.git
ssh kod@host -p 2222 repos
ssh kod@host -p 2222 info my-project

If KOD_SSH_ANONYMOUS_READ=true, unauthenticated read-only access is available with the anonymous SSH username:

Terminal window
git clone ssh://anonymous@host:2222/my-project.git