Melso Docs

GitHub

Verified request, response and authorization contracts.

GitHub installations belong to a workspace. Connecting requires a human owner/admin and verified GitHub account ownership. Repository access is checked again when credentials or PR actions are requested. Run-scoped GitHub credentials are worker integration details and are intentionally not examples for customer PAT clients.

Connect starts with GitHub user authorization. Melso finds the installations of its GitHub App that the member owns: their personal account, or an organization where they are an active admin. The member confirms which of those accounts to connect, since one may already serve another company; with none, GitHub's installation page opens next and the account installed there is connected. GitHub returns the browser to Melso after installing, and after an owner changes repository access when the App's "Redirect on update" setting is on.

A coding Run gets a token for each GitHub owner among its repositories: contents and pull requests write, issues write, and read access to checks, statuses, Actions, deployments and environments, each as far as the installation approved it. It never gets Workflows or Administration access. The chat's command VM gets read-only access to the company's repositories and those on Areas the member can open; when the member's Vault holds a GH_TOKEN or GITHUB_TOKEN, the VM uses that token instead.

Examples use the environment variables from Overview. UUID placeholders must be replaced with your own IDs.

GET /api/workspaces/{workspaceId}/github/installations

Auth: Workspace member with access to this resource.

Request: Path: workspace UUID.

Response: {installations:GitHubInstallationResponse[],can_manage:boolean,configured:boolean,repository_browse_configured:boolean,configuration_error:string}; management identifiers are redacted for non-admins and can_manage indicates management access.

Status: 200; 503 GitHub authorization unavailable. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/workspaces/$WORKSPACE_ID/github/installations" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

GET /api/workspaces/{workspaceId}/github/connect

Auth: Human workspace owner/admin; Run/MCP actors rejected.

Request: Optional query return_to:"github"|"repositories"|"chat", the page GitHub returns to. Optional mode:"install" opens GitHub's installation page to add another account instead of finding existing installations.

Response: {configured:boolean,url?:string,error?:string}. Open url in the member's browser; it expires with its one-use state after 10 minutes.

Status: 200; 400 invalid return target or mode; 403 human admin required. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/workspaces/$WORKSPACE_ID/github/connect" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

GET /api/workspaces/{workspaceId}/github/connect/candidates

Auth: The human workspace owner/admin who authorized on GitHub.

Request: Query state:string, the github_choose value GitHub returned to the page.

Response: {candidates:{installation_id:integer,account_login:string,account_type:string,account_avatar_url?:string}[],return_to:string}. The owner proof stays on the server.

Status: 200; 400 invalid state; 403 human admin required; 404 no pending choice. Authentication and resource-access errors follow Overview.

POST /api/workspaces/{workspaceId}/github/connect/complete

Auth: The human workspace owner/admin who authorized on GitHub.

Request: {state:string,installation_ids:integer[]}, installations from the pending choice.

Response: Empty.

Status: 204; 400 installation outside the choice; 403 access revoked; 404 no pending choice; 409 the choice expired or an installation changed. Authentication and resource-access errors follow Overview.

GET /api/workspaces/{workspaceId}/github/installations/{installationId}/repositories

Auth: Workspace owner/admin, or a workspace API key with admin scope.

Request: Path: workspace and installation record UUIDs. Query page?:integer (default 1), per_page?:integer (default/max 100).

Response: {repositories:GitHubRepositoryResponse[],total_count:integer,next_page:integer|null}.

Status: 200; 403 reconnect required; 404 installation mismatch; 502 GitHub request failed; 503 GitHub unavailable. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/workspaces/$WORKSPACE_ID/github/installations/$INSTALLATION_ID/repositories" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

DELETE /api/workspaces/{workspaceId}/github/installations/{installationId}

Auth: Workspace owner/admin.

Request: Path: workspace and installation record IDs.

Disconnects the account from this workspace. When no other workspace uses the installation, Melso also uninstalls its GitHub App from the account, so GitHub stops sending its webhooks and its tokens stop working. Mirrored pull requests and Task links stay.

Response: Empty.

Status: 204; 404 this workspace has no such installation; 502 GitHub did not uninstall the App, and the installation stays connected. Authentication and resource-access errors follow Overview.

curl -sS -X DELETE "$MELSO_URL/api/workspaces/$WORKSPACE_ID/github/installations/$INSTALLATION_ID" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

GET /api/tasks/{id}/pull-requests

Auth: Workspace member with access to this resource.

Request: Path: Task ID.

Response: {pull_requests:GitHubPullRequestResponse[]}.

Status: 200. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/tasks/$ID/pull-requests" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

GET /api/pull-requests/resolve

Auth: Workspace member with access to this resource.

Request: Query owner:string, repo:string, number:integer required.

Response: {id:UUID} for an authorized linked PR.

Status: 200; 400 missing/invalid query; 404 no accessible PR. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/pull-requests/resolve?owner=example&repo=product&number=1" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

GET /api/pull-requests/{id}

Auth: Workspace member with access to this resource.

Request: Path: PR record UUID.

Response: GitHubPullRequestDetailResponse.

Status: 200; 404 inaccessible PR. Authentication and resource-access errors follow Overview.

curl -sS -X GET "$MELSO_URL/api/pull-requests/$ID" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"

POST /api/pull-requests/{id}/merge

Auth: Workspace owner/admin (a person), or a workspace API key with admin scope. Run and MCP credentials are rejected, and tasks API keys get 403 workspace_key_scope; can_merge on the PR detail reports whether the caller may merge.

Request: merge_method?:"merge"|"squash"|"rebase", commit_title?:string, commit_message?:string.

Response: {merged:boolean,sha:string,pull_request:GitHubPullRequestResponse}.

Status: 200; 400 invalid method; 403 denied; 409 merge/check conflict; 502 GitHub failure. Authentication and resource-access errors follow Overview.

This action merges the PR. Use it only after review and authorization; closing keywords may also complete linked Tasks.

curl -sS -X POST "$MELSO_URL/api/pull-requests/$ID/merge" \
  -H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" -d '{"merge_method":"squash"}'

GitHubPullRequestDetailResponse

Source: server/internal/handler/github_pr_detail.go (GitHubPullRequestDetailResponse). Referenced nested objects retain their handler-defined fields; clients should tolerate additional fields.

FieldJSON type
bodystring
commits_countinteger
checksGitHubPullRequestCheckResponse[]
preferred_merge_methodstring
allow_merge_commitboolean
allow_squash_mergeboolean
allow_rebase_mergeboolean
can_mergeboolean
review_decisionstring (may be omitted)
review_taskGitHubPRReviewTaskResponse or null (may be omitted)

GitHubInstallationResponse

Source: server/internal/handler/github.go (GitHubInstallationResponse). Referenced nested objects retain their handler-defined fields; clients should tolerate additional fields.

FieldJSON type
idstring
workspace_idstring
installation_idinteger or null (may be omitted)
requires_reconnectboolean
account_loginstring
account_typestring
account_avatar_urlstring or null
created_atstring

GitHubPullRequestResponse

Source: server/internal/handler/github.go (GitHubPullRequestResponse). Referenced nested objects retain their handler-defined fields; clients should tolerate additional fields.

FieldJSON type
idstring
providerstring
workspace_idstring
repo_ownerstring
repo_namestring
numberinteger
titlestring
statestring
html_urlstring
branchstring or null
head_shastring or null: the head commit Melso last mirrored for the pull request; null when unknown
author_loginstring or null
author_avatar_urlstring or null
merged_atstring or null
closed_atstring or null
pr_created_atstring
pr_updated_atstring
mergeable_statestring or null
mergeablestring or null
merge_state_statusstring or null
snapshot_availableboolean or null (may be omitted)
checks_rollupstring or null
checks_conclusionstring or null
checks_totalinteger
checks_passedinteger
checks_failedinteger
checks_runninginteger
checks_pendinginteger
failed_check_namesstring[]
snapshot_staleboolean
snapshot_fetched_atstring or null
snapshot_head_shastring or null: the head commit the stored CI and merge snapshot describes. It equals head_sha exactly when snapshot_available is true; another commit means the snapshot is for an older head, and its fields stay empty until one for the current head arrives. Null before the first snapshot and when snapshots are not configured. Always null for other providers, whose check counts describe head_sha
additionsinteger
deletionsinteger
changed_filesinteger

GitHubRepositoryResponse

Source: server/internal/handler/github.go (GitHubRepositoryResponse). Referenced nested objects retain their handler-defined fields; clients should tolerate additional fields.

FieldJSON type
idinteger
full_namestring
html_urlstring
clone_urlstring
descriptionstring or null
privateboolean
archivedboolean
default_branchstring

GitHubPullRequestDetailResponse also includes every GitHubPullRequestResponse field.