# Jenkins REST API Architecture: How Endpoints Are Exposed via Stapler

> Understand Jenkins REST API architecture and discover how Stapler exposes endpoints. Learn how Jenkins serializes model objects into XML, JSON, or Python literals for API access.

- Repository: [Jenkins/jenkins](https://github.com/jenkinsci/jenkins)
- Tags: architecture
- Published: 2026-06-19

---

**Jenkins exposes its REST API through the Stapler web framework using the `hudson.model.Api` class, which dispatches URLs ending in `/api/*` to format-specific methods that serialize annotated model objects into XML, JSON, or Python literals.**

The Jenkins REST API architecture provides programmatic access to virtually every first-class entity in the automation server. Built on top of the Stapler web framework, this architecture allows any model object extending `AbstractModelObject` to expose data via standardized HTTP endpoints. Understanding how the `Api` class processes requests reveals the mechanism behind the consistent `/api/` URL patterns found throughout the jenkinsci/jenkins codebase.

## Stapler Framework and the Api Class

Jenkins implements its remote API on top of the **Stapler** web framework. Every model object that needs to be reachable via HTTP can expose an `Api` helper object, specifically the class `hudson.model.Api`. When a request hits a URL ending with `/api/…`, Stapler creates an instance of `Api` for the target object and dispatches to one of its `do*` methods based on the suffix.

The mapping follows this pattern:

- `…/api/xml` → `Api.doXml` returns the bean as XML
- `…/api/json` → `Api.doJson` returns the bean as JSON (or JSONP when the `jsonp` query param is present)
- `…/api/python` → `Api.doPython` returns the bean as a Python literal

Additional parameters allow selective field selection, depth control, XPath filtering, and wrapper element naming for any URL pattern under `/api/*`.

## Request Processing Pipeline in Api.java

The core implementation lives in **[`core/src/main/java/hudson/model/Api.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/Api.java)**. The pipeline follows a strict sequence from security checks through serialization.

### Security Headers and Permission Checks

Every API response begins with header preparation. The `setHeaders()` method adds security-oriented response headers including `X‑Jenkins`, `X‑Content‑Type‑Options`, and `X‑Frame‑Options` to the response (lines 307-315 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java)).

Before exposing primitive XPath results or JSONP, the `permit()` method consults all registered **`SecureRequester`** extensions. These plugins enforce CSRF protection and other security policies, located at lines 298-304 in the same file.

### Model Building with Exported Annotations

The **`ModelBuilder`** class inspects the target class’s `@Exported` and `@ExportedBean` annotations to build a **`Model`** describing the fields that can be serialized. This occurs at lines 62-64 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java). Model classes throughout the codebase—such as [`jenkins/model/Jenkins.java`](https://github.com/jenkinsci/jenkins/blob/main/jenkins/model/Jenkins.java) (lines 354-356), [`hudson/model/Run.java`](https://github.com/jenkinsci/jenkins/blob/main/hudson/model/Run.java), and [`hudson/model/Computer.java`](https://github.com/jenkinsci/jenkins/blob/main/hudson/model/Computer.java)—use these annotations to define their API surface.

### Tree Pruning for Selective Data Retrieval

To prevent massive object graphs from being serialized, the architecture employs **`TreePruner`** implementations. Either a depth-based `ByDepth` or a path-based `NamedPathPruner` limits which parts of the object graph are emitted. This allows callers to request only the needed subtree via the `tree` or `depth` query parameters (lines 222-224 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java)).

### Serialization and Format Selection

Depending on the requested format, the bean is handed to `StaplerResponse.serveExposedBean` with the appropriate **`Flavor`** enum value (XML, JSON, JSONP, or PYTHON). This occurs at lines 58-60 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java), with the flavor definitions typically found near lines 15-17.

## XPath Processing and XML Filtering

For XML output specifically, the API supports server-side XPath processing. When the `xpath` query parameter is present, the implementation parses the generated XML into a DOM, runs the XPath expression, and removes any `exclude` nodes before writing the final output (lines 26-44 and 45-73 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java)). The optional `wrapper` parameter allows wrapping the XPath result in a custom element name, useful for maintaining valid XML structure when extracting single values.

## Practical API Usage Examples

Because any object implementing `AbstractModelObject` exposes this interface, you can query Jenkins entities directly:

```bash

# Get the whole Jenkins instance as XML

curl -s https://jenkins.example.com/api/xml

# Get only the list of jobs (name & color) as JSON

curl -s https://jenkins.example.com/api/json?tree=jobs[name,color]

# Fetch a specific build as a Python literal

curl -s https://jenkins.example.com/job/example/42/api/python

# Use XPath to retrieve just the <fullName> of a job (XML)

curl -s "https://jenkins.example.com/job/example/api/xml?xpath=//fullName"

# Wrap the XPath result in a custom element called <info>

curl -s "https://jenkins.example.com/job/example/api/xml?xpath=//fullName&wrapper=info"

# JSONP (requires a SecureRequester implementation to permit it)

curl -s "https://jenkins.example.com/api/json?jsonp=callback"

```

## Summary

- **Jenkins REST API architecture** relies on Stapler's dispatch mechanism to route `/api/*` requests to the `hudson.model.Api` class.
- The core implementation in [`/core/src/main/java/hudson/model/Api.java`](https://github.com/jenkinsci/jenkins/blob/main//core/src/main/java/hudson/model/Api.java) handles XML, JSON, JSONP, and Python output formats through dedicated `do*` methods.
- Security is enforced via `SecureRequester` extensions and hardened response headers set by `setHeaders()`.
- `@Exported` and `@ExportedBean` annotations drive the `ModelBuilder` to determine which fields are serializable across model classes like `Jenkins`, `Job`, and `Run`.
- **Tree pruning** via `TreePruner` implementations (such as `NamedPathPruner`) allows selective field retrieval using the `tree` or `depth` parameters.
- Optional **XPath processing** enables server-side filtering of XML responses with support for custom wrapper elements.

## Frequently Asked Questions

### What framework does Jenkins use for its REST API?

Jenkins uses the **Stapler** web framework. According to the jenkinsci/jenkins source code, the `Api` class acts as a dispatcher that Stapler invokes when URLs end with `/api/...`, routing requests to methods like `doXml` or `doJson` based on the specific path suffix.

### How does Jenkins determine which fields to expose in API responses?

The `ModelBuilder` class scans for `@Exported` and `@ExportedBean` annotations on model classes. As implemented in [`core/src/main/java/hudson/model/Api.java`](https://github.com/jenkinsci/jenkins/blob/main/core/src/main/java/hudson/model/Api.java) (lines 62-64), this builder constructs a `Model` that describes the fields eligible for serialization, driving the output for classes like `Jenkins`, `Job`, and `Run`.

### Can I filter the API response to include only specific fields?

Yes. Use the `tree` query parameter with a path expression such as `jobs[name,color]` or the `depth` parameter to limit object graph traversal. The `TreePruner`—specifically `NamedPathPruner` or `ByDepth`—processes these parameters in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java) (lines 222-224) to reduce payload size and improve performance.

### What security mechanisms protect the Jenkins REST API?

The `Api` class invokes `setHeaders()` to add security headers like `X-Content-Type-Options` and `X-Frame-Options` to every response (lines 307-315 in [`Api.java`](https://github.com/jenkinsci/jenkins/blob/main/Api.java)). Additionally, the `permit()` method checks all registered `SecureRequester` extensions before allowing JSONP or primitive XPath results, preventing CSRF attacks and unauthorized data access.