# The GitHub App, then the project

> Hive talks to GitHub through a GitHub App installation — that is how it reads your code, posts commit statuses, and receives the webhooks that start runs. The App is public: you install it on your own account or organisation, and it issues a per-installation token scoped to the repositories you selected.

Source: https://hiveci.io/docs/github-app-and-projects
Language: en

## Install the App first
Hive talks to GitHub through a GitHub App installation — that is how it reads your code, posts commit statuses, and receives the webhooks that start runs. The App is public: you install it on your own account or organisation, and it issues a per-installation token scoped to the repositories you selected.
The install link is `https://github.com/apps/<slug>/installations/new`, where the slug comes from your instance's `/api/v1/config` as `github_app_slug`. The onboarding wizard renders it as a button; if it shows "ask your operator" instead, the instance has not been configured with its App slug and an operator has to set that before any tenant can self-serve.
Install it on the **account that owns the repository** — a personal account for a personal repo, the organisation for an org repo. Grant it only the repositories you want Hive to run.
## Then register the project
```
register_project    # or POST /api/v1/projects
list_projects       # what is already registered
```
A project is a name plus a `repo_url`. Registration is a *database* action: it does not install the App, and it does not check that an installation exists. That is why the order matters — the two steps look independent and are not.
## Installations belong to one tenant
The first tenant to bind an installation keeps it. If an installation is already bound elsewhere, Hive does not silently move it: the binding is an operator action, deliberately, so that a reinstall cannot transfer a repository between tenants by accident.
## Verifying it actually worked
The honest check is a delivery, not a settings page. Push a commit and look for a run:
```
list_runs
get_onboarding_state
```
If nothing appears, the usual causes are: the App is installed on a different account than the one owning the repo; the repository was not included in the installation's repository selection; or the project's `repo_url` does not match the repository the webhook is coming from.
