Jenkins REST API is one of the most overlooked features of the most popular CI/CD server. You can trigger builds, check status, manage plugins, create jobs, and build custom dashboards — all via simple HTTP calls.
Why Use the Jenkins API?
- Trigger builds from Slack, GitHub webhooks, or custom tools
- Monitor build health across all pipelines
- Automate job creation and configuration
- Build custom CI/CD dashboards
Getting Started
export JENKINS_URL="http://localhost:8080"
export JENKINS_USER="admin"
export JENKINS_TOKEN="your-api-token"
# Get Jenkins info
curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" "$JENKINS_URL/api/json" | jq '{mode: .mode, numExecutors: .numExecutors, jobs: [.jobs[] | {name: .name, color: .color}]}'
# Trigger a build
curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" -X POST "$JENKINS_URL/job/my-project/build"
# Trigger with parameters
curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" -X POST "$JENKINS_URL/job/deploy/buildWithParameters?ENVIRONMENT=staging&VERSION=2.1.0"
Python Client
import requests
import time
class JenkinsClient:
def __init__(self, url, user, token):
self.url = url
self.auth = (user, token)
def get_jobs(self):
resp = requests.get(f"{self.url}/api/json", auth=self.auth)
return resp.json()['jobs']
def get_build_info(self, job, build_number):
resp = requests.get(f"{self.url}/job/{job}/{build_number}/api/json", auth=self.auth)
return resp.json()
def get_last_build(self, job):
return self.get_build_info(job, 'lastBuild')
def trigger_build(self, job, parameters=None):
if parameters:
resp = requests.post(f"{self.url}/job/{job}/buildWithParameters", params=parameters, auth=self.auth)
else:
resp = requests.post(f"{self.url}/job/{job}/build", auth=self.auth)
return resp.status_code in (200, 201)
def get_console_output(self, job, build_number):
resp = requests.get(f"{self.url}/job/{job}/{build_number}/consoleText", auth=self.auth)
return resp.text
def wait_for_build(self, job, build_number=None, timeout=300):
if not build_number:
time.sleep(3)
build_number = self.get_last_build(job)['number']
start = time.time()
while time.time() - start < timeout:
info = self.get_build_info(job, build_number)
if not info.get('building', True):
return info
time.sleep(5)
raise TimeoutError(f"Build {build_number} timed out")
# Usage
jenkins = JenkinsClient('http://localhost:8080', 'admin', 'your-token')
# Check all jobs
for job in jenkins.get_jobs():
status = 'PASS' if job['color'] == 'blue' else 'FAIL' if 'red' in job['color'] else job['color']
print(f"{status:6s} | {job['name']}")
# Deploy and wait
jenkins.trigger_build('deploy', {'ENVIRONMENT': 'staging', 'VERSION': '2.1.0'})
result = jenkins.wait_for_build('deploy')
print(f"Build #{result['number']}: {result['result']}")
Build Health Dashboard
def build_health_report(jenkins):
jobs = jenkins.get_jobs()
print(f"{'Job':40s} {'Status':8s} {'Last Build':12s} {'Duration':10s}")
print('-' * 75)
for job in jobs:
try:
last = jenkins.get_last_build(job['name'])
status = last.get('result', 'BUILDING')
duration = last.get('duration', 0) / 1000
timestamp = time.strftime('%Y-%m-%d', time.localtime(last['timestamp']/1000))
print(f"{job['name']:40s} {status:8s} {timestamp:12s} {duration:8.1f}s")
except Exception:
print(f"{job['name']:40s} {'N/A':8s}")
build_health_report(jenkins)
Create Jobs Programmatically
def create_pipeline_job(jenkins, name, git_url, branch='main', jenkinsfile='Jenkinsfile'):
config_xml = f"""<?xml version='1.1' encoding='UTF-8'?>
<flow-definition>
<description>Auto-generated pipeline</description>
<definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition">
<scm class="hudson.plugins.git.GitSCM">
<userRemoteConfigs>
<hudson.plugins.git.UserRemoteConfig>
<url>{git_url}</url>
</hudson.plugins.git.UserRemoteConfig>
</userRemoteConfigs>
<branches>
<hudson.plugins.git.BranchSpec>
<name>*/{branch}</name>
</hudson.plugins.git.BranchSpec>
</branches>
</scm>
<scriptPath>{jenkinsfile}</scriptPath>
</definition>
</flow-definition>"""
resp = requests.post(
f"{jenkins.url}/createItem?name={name}",
data=config_xml,
headers={'Content-Type': 'application/xml'},
auth=jenkins.auth
)
return resp.status_code == 200
create_pipeline_job(jenkins, 'my-new-service', 'https://github.com/org/repo.git')
Slack Notification Integration
def notify_build_result(jenkins, job, build_number, slack_webhook):
info = jenkins.get_build_info(job, build_number)
color = '#36a64f' if info['result'] == 'SUCCESS' else '#ff0000'
duration = info['duration'] / 1000
payload = {
'attachments': [{
'color': color,
'title': f"{job} #{build_number}: {info['result']}",
'fields': [
{'title': 'Duration', 'value': f"{duration:.1f}s", 'short': True},
{'title': 'Branch', 'value': 'main', 'short': True}
],
'footer': 'Jenkins CI'
}]
}
requests.post(slack_webhook, json=payload)
Real-World Use Case
A development team with 200+ Jenkins jobs built a custom dashboard using the Jenkins API. It showed build health across all projects, highlighted flaky tests, and automatically triggered dependent builds when upstream projects succeeded. The dashboard reduced "is the build broken?" questions by 80%.
What You Can Build
- Custom CI/CD dashboard with real-time build status
- Auto-trigger system for dependent pipelines
- Flaky test detector analyzing build history
- Deploy bot triggered from Slack or Discord
- Build analytics tracking speed and reliability trends
Need custom CI/CD automation? I build DevOps tools and pipelines.
Email me: spinov001@gmail.com
Check out my developer tools: https://apify.com/spinov001
Top comments (0)