Loading...
Loading...
GitLab REST API via curl. Use this skill to manage projects, issues, merge requests, and pipelines in GitLab.
npx skill4agent add vm0-ai/vm0-skills gitlabcurlOfficial docs:https://docs.gitlab.com/ee/api/
apiexport GITLAB_HOST="gitlab.com" # Or your self-hosted GitLab domain
export GITLAB_TOKEN="glpat-xxxxxxxxxxxx" # Personal access token with api scopeImportant: When usingin a command that pipes to another command, wrap the command containing$VARin$VAR. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.bash -c '...'bashbash -c 'curl -s "https://api.example.com" -H "Authorization: Bearer $API_KEY"' | jq .
GITLAB_HOSTGITLAB_TOKENhttps://${GITLAB_HOST}/api/v4Note: Project IDs can be numeric (e.g.,) or URL-encoded paths (e.g.,123).mygroup%2Fmyproject
bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/user" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '{id, username, name, email, state}'bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects?membership=true&per_page=20" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '.[] | {id, path_with_namespace, visibility, default_branch}'membership=trueowned=truesearch=keywordvisibility=public|internal|private<project-id>mygroup%2Fmyprojectbash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '{id, name, path_with_namespace, default_branch, visibility, web_url}<project-id>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues?state=opened&per_page=20" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '.[] | {iid, title, state, author: .author.username, labels, web_url}'state=opened|closed|alllabels=bug,urgentassignee_id=123search=keyword<project-id><issue-iid>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues/<issue-iid>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '{iid, title, description, state, author: .author.username, assignees: [.assignees[].username], labels, created_at, web_url}'<project-id>/tmp/gitlab_request.json{
"title": "Bug: Login page not loading",
"description": "The login page shows a blank screen on mobile devices.",
"labels": "bug,frontend"
}bash -c 'curl -s -X POST "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, web_url}'<project-id><assignee-id><milestone-id>/tmp/gitlab_request.json{
"title": "Implement user profile page",
"description": "Create a user profile page with avatar and bio.",
"assignee_ids": [<assignee-id>],
"milestone_id": <milestone-id>,
"labels": "feature,frontend"
}bash -c 'curl -s -X POST "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, web_url}'<project-id><issue-iid>/tmp/gitlab_request.json{
"title": "Updated: Bug fix for login page",
"labels": "bug,frontend,in-progress"
}bash -c 'curl -s -X PUT "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues/<issue-iid>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, labels, updated_at}'<project-id><issue-iid>/tmp/gitlab_request.json{
"state_event": "close"
}bash -c 'curl -s -X PUT "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues/<issue-iid>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, state}'"state_event": "reopen"<project-id><issue-iid>/tmp/gitlab_request.json{
"body": "Investigating this issue. Will update soon."
}bash -c 'curl -s -X POST "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues/<issue-iid>/notes" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{id, body, author: .author.username, created_at}'<project-id>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/merge_requests?state=opened&per_page=20" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '.[] | {iid, title, state, source_branch, target_branch, author: .author.username, web_url}'state=opened|closed|merged|allscope=created_by_me|assigned_to_me|alllabels=review-needed<project-id><mr-iid>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/merge_requests/<mr-iid>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '{iid, title, state, source_branch, target_branch, author: .author.username, merge_status, has_conflicts, web_url}'<project-id>/tmp/gitlab_request.json{
"source_branch": "feature/user-profile",
"target_branch": "main",
"title": "Add user profile page",
"description": "This MR adds a new user profile page with avatar support."
}bash -c 'curl -s -X POST "https://${GITLAB_HOST}/api/v4/projects/<project-id>/merge_requests" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, web_url}'<project-id><mr-iid>/tmp/gitlab_request.json{
"merge_when_pipeline_succeeds": true
}bash -c 'curl -s -X PUT "https://${GITLAB_HOST}/api/v4/projects/<project-id>/merge_requests/<mr-iid>/merge" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{iid, title, state, merged_by: .merged_by.username}'merge_when_pipeline_succeeds=truesquash=trueshould_remove_source_branch=true<project-id>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/pipelines?per_page=10" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '.[] | {id, status, ref, sha: .sha[0:8], created_at, web_url}'<project-id><pipeline-id>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/pipelines/<pipeline-id>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '{id, status, ref, duration, finished_at, web_url}'<project-id><pipeline-id>bash -c 'curl -s "https://${GITLAB_HOST}/api/v4/projects/<project-id>/pipelines/<pipeline-id>/jobs" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"' | jq '.[] | {id, name, stage, status, duration}'/tmp/gitlab_search.txtjohnbash -c 'curl -s -G "https://${GITLAB_HOST}/api/v4/users" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --data-urlencode "search@/tmp/gitlab_search.txt"' | jq '.[] | {id, username, name, state}'/tmp/gitlab_request.json{
"name": "my-new-project",
"visibility": "private",
"initialize_with_readme": true
}bash -c 'curl -s -X POST "https://${GITLAB_HOST}/api/v4/projects" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" --header "Content-Type: application/json" -d @/tmp/gitlab_request.json' | jq '{id, path_with_namespace, web_url}'<project-id><issue-iid>bash -c 'curl -s -X DELETE "https://${GITLAB_HOST}/api/v4/projects/<project-id>/issues/<issue-iid>" --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" -w "\nHTTP Status: %{http_code}"'mygroup/myprojectmygroup%2Fmyprojectmygroup/subgroup/myprojectmygroup%2Fsubgroup%2Fmyproject# Using numeric ID
PROJECT_ID="123"
# Using encoded path
PROJECT_ID="mygroup%2Fmyproject"iidid%2Fper_pagepagemerge_statuscan_be_mergedGITLAB_HOST