Skip to content
Latchkey

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

Terminal
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

ParameterWhat it does
contentThe CI YAML to validate (URL-encoded)
include_merged_yamlReturn the config after includes/extends
include_jobsInclude the list of jobs that would be created
refRef 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →