POST /v1/github/installation
Bind a GitHub App installation ID to your Layers organization.
/v1/github/installation- Auth
- Bearer
- Scope
- github:admin
Record the GitHub App installation your user just authorized. Layers uses this binding to create short-lived tokens for cloning, analyzing, and opening PRs against any repo the install can see. One installation per organization.
The installation flow is: you send the user to a Layers install URL (GET /v1/github/installation/install-url), GitHub redirects back to you with an installation_id in the query string, you post that ID here. One uninstall on the GitHub side revokes all access — the API does not store long-lived GitHub credentials.
installationIdintegerrequiredThe numeric `installation_id` GitHub returned on the redirect.statestringrequiredThe CSRF `state` value GitHub round-tripped on the redirect — same string you originally sent (or that Layers generated) on `/install-url`.
The body is strict — extra keys (e.g. orgLogin, note) are rejected with 422 VALIDATION. The org login is read from GitHub via the installation itself and returned in the response.
Example request
curl https://api.layers.com/v1/github/installation \
-H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..." \
-H "Content-Type: application/json" \
-d '{
"installationId": 50291845,
"state": "lUNN5tIRm-K3a8sBXvBQDxVOCgz2x9YK"
}'await layers.github.registerInstallation({
installationId: 50291845,
state: "lUNN5tIRm-K3a8sBXvBQDxVOCgz2x9YK",
});layers.github.register_installation(
installation_id=50291845,
state="lUNN5tIRm-K3a8sBXvBQDxVOCgz2x9YK",
)Response
{
"installationId": 50291845,
"githubAccount": {
"login": "acme-coffee",
"type": "Organization"
},
"orgLogin": "acme-coffee",
"status": "active",
"registeredAt": "2026-04-18T19:14:09.123456+00:00"
}Re-posting the same installationId for an org that's already bound to it is a no-op — registeredAt reflects the original grant.
Errors
| Status | Code | When |
|---|---|---|
| 422 | VALIDATION | installationId / state missing, unknown body keys supplied, or GitHub reports the installation does not exist / the App cannot see it. |
| 401 | UNAUTHENTICATED | Missing or invalid key. |
| 403 | FORBIDDEN_SCOPE | Key lacks github:admin. |
| 409 | CONFLICT | Your organization already has a different installation bound. Detach first. |
| 429 | RATE_LIMITED | Write budget exhausted. |
See also
GET /v1/github/installation/install-url— create the install URLGET /v1/github/installation— read current bindingPOST /v1/projects/:id/ingest/github— run the SDK-install flow