# How Jenkins API is Documented: From Source Annotations to Live Endpoints

> Discover how Jenkins API documentation originates from Java source annotations like @Exported, managed by hudson.model.Api, generating live JSON, XML, and Python endpoints for easy integration.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: internals
- Published: 2026-08-01

---

**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`](https://github.com/jenkinsci/jenkins/blob/main/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 objects
- **`xpath`**: Filter XML responses using XPath expressions (handled in `doXml`)
- **`wrapper`**: Wrap responses in specified elements
- **`depth`**: Control the recursion depth for nested objects

For example, to retrieve only specific fields using the tree parameter:

```http
GET https://jenkins.example.com/api/json?tree=jobs[fullName,lastBuild[number,status]]

```

Or to filter XML with XPath:

```http
GET https://jenkins.example.com/api/xml?xpath=/hudson/job[name='MyJob']/lastBuild/number

```

To control recursion depth:

```http
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`](https://github.com/jenkinsci/jenkins/blob/main/search.js)**: Wraps the search endpoint for browser-based queries
- **[`pluginManager.js`](https://github.com/jenkinsci/jenkins/blob/main/pluginManager.js)**: Handles plugin management API calls
- **[`securityConfig.js`](https://github.com/jenkinsci/jenkins/blob/main/securityConfig.js)**: Manages security-related API interactions

For instance, the search wrapper allows UI components to query jobs:

```javascript
// 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`](https://github.com/jenkinsci/jenkins/blob/main/ApiTest.java) file in [`test/src/test/java/hudson/model/ApiTest.java`](https://github.com/jenkinsci/jenkins/blob/main/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:

- **`@Exported` and `@ExportedBean`** annotations in the source code define the public API surface
- **`hudson.model.Api`** acts 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.java`](https://github.com/jenkinsci/jenkins/blob/main/ApiTest.java)** validates 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`](https://github.com/jenkinsci/jenkins/blob/main/ApiTest.java)** file in [`test/src/test/java/hudson/model/ApiTest.java`](https://github.com/jenkinsci/jenkins/blob/main/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`](https://github.com/jenkinsci/jenkins/blob/main/search.js) and [`pluginManager.js`](https://github.com/jenkinsci/jenkins/blob/main/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.