Skip to main content

Overview

The GitHub Integration API lets you link a GitHub repository to a registry entry so that default-branch pushes and matching Git tags automatically publish updated skill versions. It requires a Pro plan and the registry:push permission. For the operator setup flow, see Set up GitHub integration. The integration works in three steps:
  1. Install the SelfTune GitHub App on your GitHub account or organization
  2. Bind the installation to your SelfTune org
  3. Connect a specific repository to a registry entry
SelfTune can read repository contents and publish into the registry by default. If you grant the optional Checks and Commit statuses permissions, it can also post publish results back to GitHub. It still does not open pull requests or push commits back to GitHub.

Settings

Read org GitHub settings

Returns org-level GitHub write-back policy.
GET /api/v1/github/settings
Authorization: Bearer {API_KEY}

Response

{
  "write_back_mode": "checks"
}

Update org GitHub settings

POST /api/v1/github/settings
Content-Type: application/json
Authorization: Bearer {API_KEY}

{
  "write_back_mode": "checks"
}
write_back_mode values:
  • off
  • checks
  • checks_and_prs

Authentication

All endpoints require:
Authorization: Bearer {API_KEY}

Installations

List installations

Returns all GitHub App installations bound to your org.
GET /api/v1/github/installations
Authorization: Bearer {API_KEY}

Response

{
  "installations": [
    {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "installation_id": 12345678,
      "account_login": "my-org",
      "account_type": "Organization",
      "suspended": false,
      "created_at": "2026-04-01T10:00:00Z",
      "updated_at": "2026-04-01T10:00:00Z"
    }
  ]
}

Bind installation

Records a GitHub App installation so SelfTune can access repositories under that account. Call this after the user completes the GitHub App installation flow and you have the installation_id from GitHub’s redirect callback.
POST /api/v1/github/installations
Content-Type: application/json
Authorization: Bearer {API_KEY}

{
  "installation_id": 12345678,
  "account_login": "my-org",
  "account_type": "Organization"
}

Request fields

FieldTypeRequiredNotes
installation_idIntegerYesGitHub App installation ID from the OAuth callback
account_loginStringYesGitHub username or org name (max 100 chars)
account_type"User" | "Organization"YesType of GitHub account
suspendedBooleanNoWhether the installation is suspended; defaults to false

Response

{
  "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "installation_id": 12345678,
  "account_login": "my-org",
  "account_type": "Organization",
  "suspended": false,
  "created_at": "2026-04-01T10:00:00Z",
  "updated_at": "2026-04-01T10:00:00Z"
}

Repositories

List repositories

Returns repositories accessible through a given installation.
GET /api/v1/github/repos?installation_id=12345678
Authorization: Bearer {API_KEY}

Query parameters

ParameterTypeRequiredNotes
installation_idIntegerYesThe installation to list repos for

Response

{
  "repos": [
    {
      "id": 987654321,
      "full_name": "my-org/my-skill-repo",
      "owner": "my-org",
      "name": "my-skill-repo",
      "visibility": "public",
      "default_branch": "main",
      "html_url": "https://github.com/my-org/my-skill-repo",
      "pushed_at": "2026-04-10T08:00:00Z",
      "connected_elsewhere": false
    }
  ]
}
connected_elsewhere is true when another SelfTune org already has a connection to this repo.

Connections

A connection links one repository to one registry entry. When a git tag matching tag_pattern is pushed, SelfTune publishes a new version of that entry automatically.

List connections

GET /api/v1/github/connections
Authorization: Bearer {API_KEY}

Response

{
  "connections": [
    {
      "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "org_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "entry_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "entry_name": "my-skill",
      "installation_id": 12345678,
      "repo_owner": "my-org",
      "repo_name": "my-skill-repo",
      "repo_full_name": "my-org/my-skill-repo",
      "default_branch": "main",
      "skill_path": ".",
      "auto_publish": true,
      "write_back_enabled": false,
      "tag_pattern": "v*",
      "created_by": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "created_at": "2026-04-01T10:00:00Z",
      "updated_at": "2026-04-01T10:00:00Z",
      "last_attempt": null
    }
  ]
}

Create connection

Links a repository to a registry entry. After creation, pushes to the configured default branch publish commit-based prerelease versions and tags that match tag_pattern publish release versions.
POST /api/v1/github/connections
Content-Type: application/json
Authorization: Bearer {API_KEY}

{
  "entry_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "installation_id": 12345678,
  "repo_full_name": "my-org/my-skill-repo",
  "default_branch": "main",
  "skill_path": ".",
  "auto_publish": true,
  "write_back_enabled": false,
  "tag_pattern": "v*"
}

Request fields

FieldTypeRequiredDefaultNotes
entry_idUUIDYesThe registry entry to publish to
installation_idIntegerYesThe bound GitHub installation that has access to the repo
repo_full_nameStringYesowner/repo format (e.g. my-org/my-skill)
default_branchStringNo"main"Branch used for non-tag pushes
skill_pathStringNo"."Path within the repo to the skill root; use "." for repo root
auto_publishBooleanNotrueWhether tag pushes automatically publish a new version
write_back_enabledBooleanNofalseWhether this connection should post commit statuses and check-runs when org mode allows it
tag_patternStringNo"v*"Glob pattern for tags that trigger publishing (e.g. "v*" matches v1.0.0)

Response

Returns the created connection object (same shape as list items above) with HTTP 201.

Update connection

Updates connection-level write-back policy.
PATCH /api/v1/github/connections/{id}
Content-Type: application/json
Authorization: Bearer {API_KEY}

{
  "write_back_enabled": true
}

Response

Returns the updated connection object.

Delete connection

Removes the connection. Existing published versions are not affected.
DELETE /api/v1/github/connections/{id}
Authorization: Bearer {API_KEY}

Response

{ "deleted": true }

Sync connection

Manually triggers a sync for an existing connection, re-reading the latest state of the repository. Useful for backfilling or re-publishing after a configuration change.
POST /api/v1/github/connections/{id}/sync
Authorization: Bearer {API_KEY}

Response

Returns HTTP 200 with:
{
  "connection_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "status": "published",
  "version": "0.0.0-github.abcdef1",
  "source_ref": "abcdef1234567890fedcba9876543210abcdef12",
  "published_at": "2026-04-14T12:00:00Z",
  "message": "Published 0.0.0-github.abcdef1 from acme/skills.",
  "write_back_status": "success",
  "check_run_id": "123456789",
  "status_context": "selftune/publish/abcd1234"
}
write_back_status values:
  • disabled
  • pending
  • success
  • failed
  • unsupported

Registry entry fields

When creating a registry entry via the push API, two new optional fields are available:
FieldTypeDefaultNotes
visibility"public" | "org" | "unlisted""org"Who can discover this entry in the registry
source_repoStringThe owner/repo this entry is sourced from
Visibility options:
  • "public" — listed in the public registry and discoverable by anyone
  • "org" — visible only within your SelfTune org
  • "unlisted" — accessible by direct link but not listed publicly

Version source tracking

Published versions now include provenance fields indicating how they were created:
FieldTypeNotes
source"cli" | "github" | "github-direct"How the version was published
source_refString | nullGit ref (tag or SHA) the version was built from
source_repoString | nullowner/repo the version came from
These fields appear in version responses from the registry API and are set automatically when publishing via GitHub.