Complete a GitHub organization claim: prove admin, create the org
POST/api/orgs/claims/{installation_id}
completeOrganizationClaim
The second half of the org claim, made by `/new/organization/claim` after the App installation callback lands there — or straight after a begin that answered `next: complete`. `installation_id` must be an **active** App installation on a GitHub **organisation** (`409 not_an_org_installation` otherwise — one answer whether the id is unknown to GitHub, suspended, an enterprise or a personal installation, so this is not an existence oracle). An installation this deployment has not recorded — the App was installed from github.com, or after an earlier consent expired — is read live under the App's credential and recorded **only once the proof below has passed**; a refused proof writes nothing. **The proof is live and it is the lock.** `GET /user/memberships/orgs/{org}` is asked of GitHub under the caller's own GitHub App user token, here and now, and only `role: admin, state: active` admits them. Who installed the App is never consulted, and a member who can *see* the installation is refused here exactly as a stranger is. Refusals name what stands in the way: `github_app_login_required` (403, the GitHub link is a classic OAuth-App login — reconnect GitHub), `github_app_permission_missing` (403, the App needs the organization permission *Members: read* and an org owner must approve it on GitHub), `not_an_org_admin` (403), `github_identity_required` (403, no GitHub link at all); none of them names the organisation. On proof the org workspace is created with the installation's login as its slug and the caller as Owner — the same creation `POST /api/orgs` performs, with the GitHub reservation satisfied by the proof instead of the directory probe — the installation is recorded as owned by that workspace, and the claim is written to the audit log (`201`). **Re-entrant.** A slug that is already a workspace is adopted rather than refused when the caller Owns it by the policy layer's decision — the shape a claim left in when it failed after creating the workspace — and the installation is marked and the claim audited then (`200`); an installation already marked with that same workspace answers `200` again with nothing written. A workspace the caller does not own is `409 already_exists` with nothing written; an installation already marked with a DIFFERENT workspace (a GitHub org renamed and claimed again) is `409 not_an_org_installation`, and no second workspace is created. **Browser sessions only**, for the same reason as the begin route. 404 when this deployment has no GitHub App configured.
Requires authentication using a session cookie — see tokens and scopes.
curl
curl -X POST 'https://neosource.dev/api/orgs/claims/INSTALLATION_ID' \
-b 'ns_session=$NEOSOURCE_SESSION'fetch
fetch("https://neosource.dev/api/orgs/claims/INSTALLATION_ID", {
method: "POST",
credentials: "include",
});Path parameters
installation_idrequiredGitHub's installation id, as the callback's redirect carried it.
Responses
200The claim was already complete, or its workspace already existed under the caller; nothing new was created
application/json
201Org created; the caller is its Owner
application/json
Standard errors
Bodies documented once for the whole API — see standard errors.
- 400Bad Request — one of: invalid_input
- 401Authentication required
- 403Forbidden — one of: forbidden, github_app_login_required, github_app_permission_missing, github_identity_required, not_an_org_admin, org_installations_unsupported
- 404Not Found — one of: not_found
- 409Conflict — one of: already_exists, conflict, not_an_org_installation
- 429Rate limited — retry after the `Retry-After` header
- 500Internal server error
- 502Bad Gateway — one of: upstream
- 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
- 504Gateway timeout — the request exceeded the server's handling budget