GitLab CI Lint API: Validate Config with curl
The GitLab project CI Lint API validates a .gitlab-ci.yml on the server and returns valid true/false plus errors, callable with plain curl in any pipeline.
When you cannot install the glab CLI on a runner, curl against the CI Lint API gives the same server-side validation. The project-scoped endpoint resolves includes exactly as a real pipeline would.
What it does
The POST /projects/:id/ci/lint endpoint accepts your CI YAML content and returns JSON with valid, errors, warnings, and (optionally) the merged config. Passing include_merged_yaml=true returns the config after includes and extends.
Common usage
curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"https://gitlab.com/api/v4/projects/$PROJECT_ID/ci/lint" \
--data-urlencode "content=$(cat .gitlab-ci.yml)"
# with merged config resolved
curl -s --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"https://gitlab.com/api/v4/projects/$PROJECT_ID/ci/lint?include_merged_yaml=true" \
--data-urlencode "content=$(cat .gitlab-ci.yml)"Options
| Parameter | What it does |
|---|---|
| content | The CI YAML to validate (URL-encoded) |
| include_merged_yaml | Return the config after includes/extends |
| include_jobs | Include the list of jobs that would be created |
| ref | Ref to use when resolving includes |
| PRIVATE-TOKEN (header) | API token with read access to the project |
In CI
Add a lint job that curls this endpoint and fails when valid is false; parse the response with jq. It is the portable alternative to glab ci lint when the runner image is minimal.
Common errors in CI
The response includes "valid":false with "errors":["jobs:build:script config should be a string ...","root config contains unknown keys: stages "]. A 401 Unauthorized or {"message":"401 Unauthorized"} means a bad or missing PRIVATE-TOKEN. {"message":"404 Project Not Found"} means the wrong PROJECT_ID or no access.