API

GitHub

Connect GitHub accounts, repositories, and App sources.

The GitHub API connects an Openship instance to GitHub — via the Openship GitHub App, an OAuth account, or the local gh CLI — and then lets you browse the accounts, repositories, branches and files you can deploy from. It also manages the push webhooks that drive auto-deploy. In the dashboard this is the GitHub connection card in Settings and the repo picker in the deploy wizard.

Both cloud and self-hosted

This module is mounted on every instance. The local identity routes and every /api/github/sources route are self-hosted only and return 404 on Openship Cloud. Source management additionally requires the active workspace's owner role.

Connection state

GET /api/github/home is the dashboard's single entry point: it returns { state, accounts, repos } in one round trip, filtered to the accounts and repos your member role is allowed to see. GET /api/github/status is narrower — the Settings card's data source — returning { state, accounts, installUrl, cloudUnreachable, customSourcesConfigured }. The last field tells clients that App lifecycle controls belong to the workspace source manager rather than the legacy Openship App connection.

const result = await ship.github.getHome();
console.log(result);
curl "$OPENSHIP_URL/api/github/home" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"

Connect

Starts or advances the connection flow. The response is intentionally mode-agnostic — the frontend just reacts to the flow field:

  • { connected: true } — already connected, nothing to do.
  • { connected: false, flow: "redirect", url } — open url (OAuth handoff or GitHub App install).
  • { connected: false, flow: "installations", state, installations, installUrl } — let the user select an existing installation, or open installUrl to install on another account.
  • { connected: false, flow: "device_code", userCode, verificationUri, ... } — self-hosted device login.
  • { connected: false, flow: "token", message } — collect a personal token using the method's declared credential scope.
  • { connected: false, flow: "terminal", command, message } — run command (e.g. gh auth login) yourself.

The optional body field source ("oauth" | "cli") forces a specific path when the dashboard shows both the "Connect Openship App" and "Use gh CLI" buttons; omit it to let the server pick based on the instance's auth mode.

On Openship Cloud, repository authorization is separate from the GitHub identity used to sign in. The same GitHub user can authorize repository access for multiple Openship accounts. This never moves or disconnects another account's sign-in link. Existing installations are discovered through that user's GitHub authorization and verified again when selected.

For a redirect with completion: "attempt", poll github.pollConnect({ state }) using the returned state until it completes or reports an error. An existing connected installation does not mean a new attempt succeeded. A flow: "installations" response is completed with github.claimInstallation({ state, installationId: String(id) }) after the user selects it. Cloud also supports a personal token in Settings → Git; the Library's Other connection methods link opens that page.

const result = await ship.github.connect({
  source: "oauth",
});
console.log(result);
curl -X POST "$OPENSHIP_URL/api/github/connect" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"source":"oauth"}'

Disconnect

POST /api/github/disconnect

Body (or ?source=): source is "oauth", "cli", or "all" (default "all"). This drops Openship's stored credentials for that source; it does not uninstall the GitHub App — that happens only when you remove it from github.com (Openship reacts to the uninstall webhook).

On Cloud, disconnecting oauth clears repository authorization and cancels its pending connection attempts. It preserves the account's GitHub sign-in method and any separately saved personal token.

This endpoint does not delete a workspace-owned source. Use DELETE /api/github/sources/:id for that explicit owner-only operation.

Workspace-owned GitHub App sources

These endpoints are available only on self-hosted instances. All reads are sanitized: private keys, client secrets, webhook secrets, and their encrypted envelope are never returned.

List sources

Returns { data, configuration }. configuration contains publicReady, publicUrl, setupUrl, and webhookUrl. Each source in data contains public App metadata, health, default status, and its claimed installations.

One-click manifest

Start the GitHub.com flow with:

The response contains { url, manifest }. Submit manifest as a JSON string in a form field named manifest to url; the dashboard does this automatically. GitHub redirects to the configured setup page with code and state, which must be sent to:

POST /api/github/sources/manifest/convert
{ "code": "…", "state": "…" }

Conversion consumes the user/workspace-bound state exactly once, encrypts GitHub's generated credentials, and returns { data, installUrl }.

Manual registration and GitHub Enterprise Server

POST /api/github/sources/manual

Prop

Type

The API signs an App JWT and verifies /app before saving the source. It returns { data, installUrl }.

PATCH /api/github/sources/:id accepts the same identity and endpoint fields, all optional. Omitted secret fields retain their existing encrypted values. App ID or API URL cannot change while the source has claimed installations. POST .../verify refreshes public App metadata and marks bad credentials as needing attention.

Making a source default atomically rebinds existing projects for every GitHub owner installed on that source. Deleting a source promotes another active source when possible and rebinds affected projects; projects with no replacement lose their installation binding and auto-deploy is disabled. Deleting locally does not uninstall the GitHub App itself.

Create a repository

const result = await ship.github.createRepo({
  name: "my-app",
  private: true,
  owner: "acme",
});
console.log(result);
curl -X POST "$OPENSHIP_URL/api/github/repos" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-app","private":true,"owner":"acme"}'

Prop

Type

Returns 201 with { data } (the created repository).

Browse repos, branches and files

List repos for the connected account (?owner= narrows to one account), or for a named org via GET /api/github/orgs/:org/repos. Both return { data: [...] } filtered to repos your role may see.

File browsing reads directly from GitHub:

  • GET /api/github/repos/:owner/:repo/files — directory listing. Query: path (default repo root) and branch.
  • GET /api/github/repos/:owner/:repo/file — one file's contents. Query: file (default package.json) and branch. .json files are parsed and returned as JSON.
const result = await ship.github.getFile({
  owner: "acme",
  repo: "my-app",
  file: "package.json",
  branch: "main",
});
console.log(result);
curl "$OPENSHIP_URL/api/github/repos/acme/my-app/file?file=package.json&branch=main" \
  -H "Authorization: Bearer $OPENSHIP_TOKEN"

Webhooks

POST /api/github/repos/:owner/:repo/webhooks registers the Openship push webhook on the repo (or reuses an existing one) so pushes trigger auto-deploy. It takes no request body — the target repo comes from the path. GET lists the repo's hooks. To remove one, DELETE with the hook id:

DELETE /api/github/repos/:owner/:repo/webhooks

Prop

Type

Clone token

GET /api/github/repos/:owner/:repo/clone-token mints a short-lived (under an hour) GitHub App installation token and returns { token, cloneUrl, command } — a ready-to-run git clone. This is the same credential the build pipeline clones with, and is available only when the Openship GitHub App is installed for the owner.

Errors

400 — Not connected to GitHub

Returned by the repo-listing routes when no usable GitHub source (App installation, OAuth account, or gh CLI) is configured. Connect first with POST /api/github/connect, then retry.

409 — no installation token

clone-token needs a GitHub App installation for the owner. In gh CLI or PAT modes there is no installation token, so this route 409s. Install the Openship GitHub App on that account to use clone tokens.

503 — cloud_unreachable

On a self-hosted instance connected to Openship Cloud, GitHub OAuth and App-install URLs are resolved through openship.io. If the SaaS is unreachable, connect returns 503 rather than a dead install link. Check network / the cloud connection in Settings, then retry.

An instance configured with its own self-hosted GitHub App does not use this cloud proxy; GITHUB_AUTH_MODE=auto selects the complete local App configuration first.

404 on a repo route

The :owner/:repo isn't visible to the active GitHub source (private, not granted to your member role, or does not exist). Confirm the repo appears in GET /api/github/home first.

Operations

Connect

OperationSDKREST API
Read GitHub connection status.github.getStatus(input?)GET /api/github/status
github:read
Read the GitHub overview for the current identity.github.getHome()GET /api/github/home
github:read
Start GitHub authorization or select an accessible App installation. Repository access is separate from Cloud sign-in.github.connect(input?)POST /api/github/connect
github:write
Claim an authorized GitHub App installation.github.claimInstallation(input)POST /api/github/installations/claim
github:write
Read local Git identity availability.github.getLocalStatus()GET /api/github/local-status
github:read · Self-hosted
Poll the returned state for one connection attempt, or omit state for a self-hosted device flow.github.pollConnect(input?)GET /api/github/connect/poll
github:read
Configure the installation’s GitHub token.github.setInstanceToken(input)POST /api/github/instance-token
github:admin · Self-hosted
Disconnect a GitHub identity or source association.github.disconnect(input?)POST /api/github/disconnect
github:admin

Repositories and source

OperationSDKREST API
List accessible repositories.github.listRepos(input?)GET /api/github/repos
github:list
List repositories in a GitHub organization.github.listOrgRepos(input)GET /api/github/orgs/:org/repos
github:list
Read repository metadata.github.getRepo(input)GET /api/github/repos/:owner/:repo
github:read
Create a repository through the configured GitHub identity.github.createRepo(input)POST /api/github/repos
github:write
Delete an authorized repository.github.deleteRepo(input)DELETE /api/github/repos/:owner/:repo
github:admin
List repository branches.github.listBranches(input)GET /api/github/repos/:owner/:repo/branches
github:list
Obtain an authorized repository clone credential.github.getCloneToken(input)GET /api/github/repos/:owner/:repo/clone-token
github:read
Detect build configuration in a repository.github.detectStack(input)GET /api/github/repos/:owner/:repo/detect
github:read
List repository files at a path.github.listFiles(input)GET /api/github/repos/:owner/:repo/files
github:list
Read a repository tree.github.listTree(input)GET /api/github/repos/:owner/:repo/tree
github:list
Read repository file content.github.getFile(input)GET /api/github/repos/:owner/:repo/file
github:read

Webhooks

OperationSDKREST API
List repository webhooks.github.listWebhooks(input)GET /api/github/repos/:owner/:repo/webhooks
github:list
Register a repository webhook for deployment events.github.registerWebhook(input)POST /api/github/repos/:owner/:repo/webhooks
github:write
Delete a repository webhook.github.deleteWebhook(input)DELETE /api/github/repos/:owner/:repo/webhooks
github:admin

GitHub App sources

OperationSDKREST API
List configured GitHub App sources.github.listSources()GET /api/github/sources
github:admin · Self-hosted
Start GitHub App manifest registration.github.beginManifest(input)POST /api/github/sources/manifest
github:admin · Self-hosted
Convert a completed GitHub App manifest.github.convertManifest(input)POST /api/github/sources/manifest/convert
github:admin · Self-hosted
Register an existing GitHub App source.github.createManualSource(input)POST /api/github/sources/manual
github:admin · Self-hosted
Change a GitHub App source’s configuration.github.updateSource(id, input)PATCH /api/github/sources/:id
github:admin · Self-hosted
Verify source credentials with GitHub.github.verifySource(id)POST /api/github/sources/:id/verify
github:admin · Self-hosted
Select the default GitHub App source.github.setDefaultSource(id)POST /api/github/sources/:id/default
github:admin · Self-hosted
Create an installation URL for a GitHub App source.github.createInstallUrl(id)POST /api/github/sources/:id/install
github:admin · Self-hosted
Remove a GitHub App source.github.deleteSource(id)DELETE /api/github/sources/:id
github:admin · Self-hosted

HTTP endpoints

OperationSDKREST API
GitHub OAuth callback — browser navigates here, no session yet.HTTP onlyGET /api/github/connect/redirect
Handler authentication

On this page