Documentation

Alpha

Build an app

Sign people in with OAuth, or install a bot on repositories and act as it.

The Upstream API is in alpha. Endpoints, fields and limits can change before it's stable. Send feedback to support@coline.app.

An app can work in two ways, and one app can do both:

  • Sign people in. Someone approves your app and it acts as them, with the access they agreed to.
  • Install as a bot. An owner installs your app on their account or organization and picks repositories. The app acts as its own bot, named {slug}-bot, on just those repositories.

Create an app in Your apps. Choose the most access it will ever need; people and owners can only grant up to that.

Sign people in

Send people to:

https://upstream.codes/login/oauth/authorize
  ?client_id=CLIENT_ID
  &redirect_uri=https://example.com/callback
  &scope=repo:read issues:write
  &state=RANDOM
  &code_challenge=BASE64URL_SHA256_OF_VERIFIER
  &code_challenge_method=S256

After they approve, they come back to your callback with code and state. Exchange the code:

curl -X POST https://upstream.codes/login/oauth/access_token \
  -H "Accept: application/json" \
  -d client_id=CLIENT_ID -d client_secret=CLIENT_SECRET \
  -d code=CODE -d redirect_uri=https://example.com/callback \
  -d code_verifier=VERIFIER

You get an access token that lasts eight hours and a refresh token that rotates each time you use it. Using an old refresh token again revokes the whole chain. Apps without a server, such as CLIs and mobile apps, register as public clients, skip the secret and must use PKCE. Callback URLs must match exactly.

Access tokens work like personal access tokens: the same scopes, the REST API and Git over HTTPS. People can revoke an app at any time in Connected apps.

Install as a bot

Share your app's install link, https://upstream.codes/apps/{slug}/installations/new. Owners pick a namespace and repositories, then approve.

To act as the bot:

  1. Generate a private key on your app's Keys and secrets tab. It downloads once.
  2. Sign a JWT with it using RS256, with iss set to your app ID and exp at most ten minutes out.
  3. Create an installation token:
curl -X POST -H "Authorization: Bearer $APP_JWT" \
  https://api.upstream.codes/api/v3/app/installations/$INSTALLATION_ID/access_tokens

Installation tokens last an hour and can only reach the installation's repositories with the permissions the owner approved. List installations with GET /app/installations. GitHub App libraries that let you set the API base URL work against https://api.upstream.codes/api/v3.

A bot can open and comment on Issues and Change Requests, review, report checks, publish releases, run Actions and push. It can't change repository settings, delete or transfer repositories, manage webhooks or assign people.

Changing permissions

Removing a permission takes effect right away. Adding one asks every installation's owner to approve it again; until they do, the installation keeps its current access.

Events for your app

Set a webhook URL and events on your app. It receives events from every repository it's installed on, signed with your webhook secret. Payloads include installation.id. In the GitHub format, deliveries carry X-GitHub-Event, X-Hub-Signature-256 and X-GitHub-Hook-Installation-Target-Type: integration, so GitHub App webhook libraries verify and route them unchanged.

Your app also gets these events whatever events you chose. They go only to your app, never to repository or organization webhooks:

EventActionsSent when
installationcreated, deleted, suspend, unsuspend, new_permissions_acceptedSomeone installs, removes, suspends or resumes your app, or approves permissions you added. Includes the installation, its account and the repositories it can reach.
installation_repositoriesadded, removedThe owner adds or removes repositories, or switches between all and selected repositories. Includes repository_selection, repositories_added and repositories_removed.

An app can suspend and resume its own installations with PUT and DELETE /app/installations/{id}/suspended.

Run CI from your app

An app with the checks permission (checks:write) works like a GitHub CI app:

  1. Subscribe to check_suite, and to check_run to hear about re-runs of single checks.
  2. Each push to a branch of a repository the app is installed on sends check_suite with the requested action for the pushed commit. Start a build when it arrives.
  3. Report results as check runs on that head_sha with an installation token. They join your app's check suite for the commit.
  4. When all of your runs on the commit have finished, check_suite arrives with the completed action and the suite's conclusion.

When someone re-runs your checks, you get check_suite with rerequested for the whole suite, or check_run with rerequested for one run. Report the runs again to answer. People re-run checks from the Checks tab of a Change Request or through the check suites API. Only your app receives requested and rerequested; repository and organization webhooks get completed.

Subscribe to workflow_job to follow jobs in Upstream Actions as they move through queued, waiting, in_progress and completed.

Apps that use the Upstream payload format get the same events under dotted names, such as installation.created, installation_repositories.added, check_suite.requested, check.rerequested and workflow_job.in_progress.