The loop
◀── deploys
A service is an app you ship. It has environments
you define (staging, prod, whatever you call them) and a
history of builds, keyed by commit SHA. CI reports builds; GitLaunch
dispatches deploys of a chosen build to a chosen environment and tracks their status.
That is the entire model.
1. Report a build
When a build on your default branch succeeds, tell GitLaunch about it:
curl --fail-with-body -sS -X POST \
"https://gitlaunch.dev/api/v1/services/$SERVICE_ID/builds" \
-H "Authorization: Bearer $GITLAUNCH_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -nc --arg buildId "$COMMIT_SHA" \
--arg message "$COMMIT_MESSAGE" \
--arg commitAt "$COMMIT_TIMESTAMP" \
'{buildId:$buildId,message:$message,commitAt:$commitAt}')"
buildId— the commit SHA. Required.message— the commit message, so a build is recognisable on the dashboard. Built withjqbecause commit messages have newlines.commitAt— ISO-8601 time the commit was authored. This is what makes lead time mean commit-to-live rather than "since CI told us".
That is it. The build appears on the dashboard within a second, over Server-Sent Events.
2. Deploy a build
Clicking Deploy on a build (or POST …/builds/$BUILD_ID/deploy/$ENV
with an API key) makes GitLaunch trigger your deploy pipeline with two inputs,
environment and buildId. How it triggers depends on the provider you bind:
- GitHub —
workflow_dispatchon a workflow file in your repo, through the GitLaunch GitHub App. - Jenkins —
buildWithParameterson a job. - Raw — an HTTP POST of
{ "buildId", "environment" }to a URL you own. This is how GitLab, CircleCI and everything else plug in.
Your deploy job reports back as it goes:
curl --fail-with-body -sS -X PATCH \
"https://gitlaunch.dev/api/v1/services/$SERVICE_ID/builds/$BUILD_ID/deploy/$ENVIRONMENT" \
-H "Authorization: Bearer $GITLAUNCH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"deploying"}' # then: deployed | error | cancelled
Statuses are exactly deploying, deployed, error and
cancelled. Every terminal outcome must report one, or the build sits on
"deploying" in the dashboard. Rolling back is deploying an older build; the dashboard
keeps the history, so the button is always there.
Your CI system
GitLaunch generates the exact snippet for your service — templated with your real environments, your default branch and this instance's URL — for:
- GitHub Actions — a build-report step, and a complete
deploy.ymlwith the status calls in place. - GitLab CI — a
report_buildjob for.gitlab-ci.yml, gated to$CI_DEFAULT_BRANCH. - Jenkins — a pipeline stage using a
gitlaunch-api-keycredential. - CircleCI, Buildkite, Drone, a shell script — the raw
curl.
Snippets are also served as JSON, so a tool can read them instead of a human:
GET https://gitlaunch.dev/api/v1/services/$SERVICE_ID/setup-snippets.
You keep your CI. GitLaunch never runs your build, never sees your code, and never
holds your cloud credentials — it holds a build history and a button.
Let an agent do it
Onboarding hands you a prompt for Claude Code, Cursor, Codex or any agent that can
read your repo. The prompt points at a skill this instance serves at
/skills/gitlaunch-onboarding/SKILL.md
— you can read it right now. The agent detects your stack and which host your repo
lives on, fetches the snippets above, writes or amends your pipelines, opens a pull
request, then watches the first pipeline run and fixes it until it is green and the
build shows up in GitLaunch. It never pushes to your default branch and never writes
your API key into a tracked file.
API keys
Keys are scoped: builds:write, deployments:write,
services:read, flags:evaluate and so on. A CI key needs
builds:write and deployments:write and nothing else. Keys are
shown once, stored hashed, and revocable from settings.
Self-hosting and source
GitLaunch is open core. The source is at https://github.com/donedgardo/launchpad:
src/ is under the FSL (free to run, one account and one seat),
ee/ is the commercial multi-seat, SSO and billing layer. There is a
Docker image and a one-click Railway template; the README covers both. A self-hosted
instance serves these same docs, snippets and skill addressed to its own URL, and
reports nothing back to us.
Why a waitlist
The hosted service is in beta and we are onboarding accounts by hand, partly so we can watch where new users get stuck and fix it. The waitlist stores your email and the UTM source you arrived with — that is all, and the privacy policy says so in plain language. If you would rather not wait, self-host: the product does not need us to exist.