DEV Community

Alex Spinov
Alex Spinov

Posted on

Jenkins Has a Free API: Here's How to Use It for CI/CD Automation

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"
Enter fullscreen mode Exit fullscreen mode

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']}")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)