How Jenkins API is Documented: From Source Annotations to Live Endpoints
Jenkins generates its remote access API documentation directly from Java source code using @Exported and @ExportedBean annotations, with the hudson.model.Api class serving as the central dispatcher that reflects these annotations into JSON, XML, and Python endpoints.
The Jenkins continuous integration server maintains a comprehensive remote access API that remains automatically synchronized with its codebase. Unlike traditional projects that maintain separate OpenAPI or Swagger specifications, Jenkins employs a self-documenting architecture where annotations in the Java source define the API surface. This approach ensures that the documentation available at any …/api/ endpoint is always current with the deployed version in the jenkinsci/jenkins repository.
The @Exported Annotation System
At the heart of Jenkins API documentation lies a metadata-driven system using two key annotations. The @Exported annotation marks specific fields and methods that should be exposed in the remote API, while @ExportedBean identifies classes that serve as top-level exportable objects. These annotations carry optional metadata controlling visibility, naming, and depth limits.
When developers annotate model objects—such as Jenkins, Job, or Run instances—these markers become the authoritative source of API documentation. This eliminates documentation drift because the code structure itself defines the contract.
How the API Layer Processes Requests
The hudson.model.Api class in core/src/main/java/hudson/model/Api.java orchestrates the request handling pipeline. When a request hits an endpoint like …/api/json, the system executes a four-stage process:
Detecting the Target Bean
First, the API layer identifies the bean passed to the Api constructor. This is typically a model object representing the requested resource, such as a specific job or build instance.
Building the Reflective Model
Next, the ModelBuilder introspects the bean's class hierarchy to collect all members marked with @Exported or @ExportedBean. This reflection-based discovery builds a runtime model of the available data structure without requiring manual schema definitions.
Serializing to Different Formats
Based on the requested format—whether json, xml, or python—the handler utilizes Flavor helpers to serialize the reflective model into the appropriate response structure. This design allows Jenkins to support multiple output formats from a single annotated source.
Applying Query Parameters
The API supports several query parameters that let consumers prune or reshape output:
tree: Select specific fields and nested objectsxpath: Filter XML responses using XPath expressions (handled indoXml)wrapper: Wrap responses in specified elementsdepth: Control the recursion depth for nested objects
For example, to retrieve only specific fields using the tree parameter:
GET https://jenkins.example.com/api/json?tree=jobs[fullName,lastBuild[number,status]]
Or to filter XML with XPath:
GET https://jenkins.example.com/api/xml?xpath=/hudson/job[name='MyJob']/lastBuild/number
To control recursion depth:
GET https://jenkins.example.com/job/MyJob/api/json?depth=2
Client-Side Implementation and Testing
JavaScript API Wrappers
The Jenkins UI consumes the same API endpoints through JavaScript wrappers located in src/main/js/api/. These files contain inline JSDoc comments that document client-side usage:
search.js: Wraps the search endpoint for browser-based queriespluginManager.js: Handles plugin management API callssecurityConfig.js: Manages security-related API interactions
For instance, the search wrapper allows UI components to query jobs:
// Retrieve the list of jobs as JSON
Jenkins.api.search("/api/json", {tree: "jobs[fullName]"}, function(data) {
console.log(data.jobs);
});
Validation and Error Messages
The Messages.properties files provide user-visible error messages that appear when invalid query parameters are supplied, such as illegal wrapper names or malformed XPath expressions.
Automated Testing
The ApiTest.java file in test/src/test/java/hudson/model/ApiTest.java serves as executable documentation, containing JUnit tests that verify JSON and XML output for each exported field. These tests ensure that the self-documented API remains stable across versions and provide concrete usage examples for developers.
Summary
Jenkins employs a unique self-documenting strategy for its remote API:
@Exportedand@ExportedBeanannotations in the source code define the public API surfacehudson.model.Apiacts as the central dispatcher, reflecting annotations into multiple output formats- Query parameters (
tree,xpath,depth,wrapper) allow flexible data retrieval without changing the underlying schema - JavaScript wrappers in
src/main/js/api/extend the API to browser clients with inline documentation ApiTest.javavalidates the documented behavior through automated tests
This architecture ensures that the API documentation visible at any …/api/ endpoint is always synchronized with the actual implementation in the jenkinsci/jenkins repository.
Frequently Asked Questions
How does Jenkins keep its API documentation synchronized with code changes?
Jenkins generates API documentation directly from the @Exported and @ExportedBean annotations present in the Java source code. Because the hudson.model.Api class reflects these annotations at runtime to produce JSON, XML, and Python responses, the documentation automatically updates whenever developers modify the annotations. This eliminates the need for separate OpenAPI or Swagger files that might become outdated.
What is the purpose of the tree parameter in Jenkins API requests?
The tree query parameter allows API consumers to specify exactly which fields and nested objects to return, functioning as a projection mechanism. For example, ?tree=jobs[fullName,lastBuild[number,status]] retrieves only the job names and their last build numbers and statuses, reducing payload size and improving performance. The parameter is processed by the Flavor serialization helpers in the API layer.
Where can I find examples of how to use the Jenkins API?
Concrete usage examples exist in two primary locations within the source code. First, the ApiTest.java file in test/src/test/java/hudson/model/ApiTest.java contains JUnit tests demonstrating valid JSON and XML outputs for various exported fields. Second, the JavaScript files in src/main/js/api/ (such as search.js and pluginManager.js) show how the Jenkins UI itself consumes the API endpoints, providing real-world client implementation patterns.
Why doesn't Jenkins use OpenAPI or Swagger for its API documentation?
Jenkins predates the widespread adoption of OpenAPI specifications and instead implements a reflection-based documentation system. The @Exported annotations serve a similar purpose to OpenAPI schemas but are embedded directly in the Java code. This approach ensures that the API contract is defined alongside the business logic, making it impossible for documentation to diverge from implementation. The live API reference displayed at …/api/ endpoints is generated on-demand from these annotations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →